|  | // RUN: %clang_cc1 -verify -std=c++11 %s | 
|  | // RUN: %clang_cc1 -verify -std=c++11 -fdelayed-template-parsing %s | 
|  | // RUN: %clang_cc1 -verify -std=c++20 -fsyntax-only %s | 
|  |  | 
|  | template<typename T> | 
|  | void f0() { | 
|  | struct X; | 
|  | typedef struct Y { | 
|  | T (X::* f1())(int) { return 0; } | 
|  | } Y2; | 
|  |  | 
|  | Y2 y = Y(); | 
|  | } | 
|  |  | 
|  | template void f0<int>(); | 
|  |  | 
|  | // PR5764 | 
|  | namespace PR5764 { | 
|  | struct X { | 
|  | template <typename T> | 
|  | void Bar() { | 
|  | typedef T ValueType; | 
|  | struct Y { | 
|  | Y() { V = ValueType(); } | 
|  |  | 
|  | ValueType V; | 
|  | }; | 
|  |  | 
|  | Y y; | 
|  | } | 
|  | }; | 
|  |  | 
|  | void test(X x) { | 
|  | x.Bar<int>(); | 
|  | } | 
|  | } | 
|  |  | 
|  | // Instantiation of local classes with virtual functions. | 
|  | namespace local_class_with_virtual_functions { | 
|  | template <typename T> struct X { }; | 
|  | template <typename T> struct Y { }; | 
|  |  | 
|  | template <typename T> | 
|  | void f() { | 
|  | struct Z : public X<Y<T>*> { | 
|  | virtual void g(Y<T>* y) { } | 
|  | void g2(int x) {(void)x;} | 
|  | }; | 
|  | Z z; | 
|  | (void)z; | 
|  | } | 
|  |  | 
|  | struct S { }; | 
|  | void test() { f<S>(); } | 
|  | } | 
|  |  | 
|  | namespace PR8801 { | 
|  | template<typename T> | 
|  | void foo() { | 
|  | class X; | 
|  | typedef int (X::*pmf_type)(); | 
|  | class X : public T { }; | 
|  |  | 
|  | pmf_type pmf = &T::foo; | 
|  | } | 
|  |  | 
|  | struct Y { int foo(); }; | 
|  |  | 
|  | template void foo<Y>(); | 
|  | } | 
|  |  | 
|  | namespace TemplatePacksAndLambdas { | 
|  | template <typename ...T> int g(T...); | 
|  | struct S { | 
|  | template <typename ...T> static void f(int f = g([]{ static T t; return ++t; }()...)) {} | 
|  | }; | 
|  | void h() { S::f<int, int, int>(); } | 
|  | } | 
|  |  | 
|  | namespace PR9685 { | 
|  | template <class Thing> void forEach(Thing t) { t.func(); } | 
|  |  | 
|  | template <typename T> void doIt() { | 
|  | struct Functor { | 
|  | void func() { (void)i; } | 
|  | int i; | 
|  | }; | 
|  |  | 
|  | forEach(Functor()); | 
|  | } | 
|  |  | 
|  | void call() { | 
|  | doIt<int>(); | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace PR12702 { | 
|  | struct S { | 
|  | template <typename F> bool apply(F f) { return f(); } | 
|  | }; | 
|  |  | 
|  | template <typename> struct T { | 
|  | void foo() { | 
|  | struct F { | 
|  | int x; | 
|  |  | 
|  | bool operator()() { return x == 0; } | 
|  | }; | 
|  |  | 
|  | S().apply(F()); | 
|  | } | 
|  | }; | 
|  |  | 
|  | void call() { T<int>().foo(); } | 
|  | } | 
|  |  | 
|  | namespace PR17139 { | 
|  | template <class T> void foo(const T &t) { t.foo(); } | 
|  |  | 
|  | template <class F> void bar(F *f) { | 
|  | struct B { | 
|  | F *fn; | 
|  | void foo() const { fn(); } | 
|  | } b = { f }; | 
|  | foo(b); | 
|  | } | 
|  |  | 
|  | void go() {} | 
|  |  | 
|  | void test() { bar(go); } | 
|  | } | 
|  |  | 
|  | namespace PR17740 { | 
|  | class C { | 
|  | public: | 
|  | template <typename T> static void foo(T function); | 
|  | template <typename T> static void bar(T function); | 
|  | template <typename T> static void func(T function); | 
|  | }; | 
|  |  | 
|  | template <typename T> void C::foo(T function) { function(); } | 
|  |  | 
|  | template <typename T> void C::bar(T function) { | 
|  | foo([&function]() { function(); }); | 
|  | } | 
|  |  | 
|  | template <typename T> void C::func(T function) { | 
|  | struct Struct { | 
|  | T mFunction; | 
|  |  | 
|  | Struct(T function) : mFunction(function) {}; | 
|  |  | 
|  | void operator()() { | 
|  | mFunction(); | 
|  | }; | 
|  | }; | 
|  |  | 
|  | bar(Struct(function)); | 
|  | } | 
|  |  | 
|  | void call() { | 
|  | C::func([]() {}); | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace PR14373 { | 
|  | struct function { | 
|  | template <typename _Functor> function(_Functor __f) { __f(); } | 
|  | }; | 
|  | template <typename Func> function exec_func(Func f) { | 
|  | struct functor { | 
|  | functor(Func f) : func(f) {} | 
|  | void operator()() const { func(); } | 
|  | Func func; | 
|  | }; | 
|  | return functor(f); | 
|  | } | 
|  | struct Type { | 
|  | void operator()() const {} | 
|  | }; | 
|  | int call() { | 
|  | exec_func(Type()); | 
|  | return 0; | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace PR18907 { | 
|  | template <typename> | 
|  | class C : public C<int> {}; // expected-error{{within its own definition}} | 
|  |  | 
|  | template <typename X> | 
|  | void F() { | 
|  | struct A : C<X> {}; | 
|  | } | 
|  |  | 
|  | struct B { | 
|  | void f() { F<int>(); } | 
|  | }; | 
|  | } | 
|  |  | 
|  | namespace PR23194 { | 
|  | struct X { | 
|  | int operator()() const { return 0; } | 
|  | }; | 
|  | struct Y { | 
|  | Y(int) {} | 
|  | }; | 
|  | template <bool = true> int make_seed_pair() noexcept { | 
|  | struct state_t { | 
|  | X x; | 
|  | Y y{x()}; | 
|  | }; | 
|  | return 0; | 
|  | } | 
|  | int func() { | 
|  | return make_seed_pair(); | 
|  | } | 
|  | } | 
|  |  | 
|  | namespace PR18653 { | 
|  | // Forward declarations | 
|  |  | 
|  | template<typename T> void f1() { | 
|  | void g1(struct x1); | 
|  | struct x1 {}; | 
|  | } | 
|  | template void f1<int>(); | 
|  |  | 
|  | template<typename T> void f1a() { | 
|  | void g1(union x1); | 
|  | union x1 {}; | 
|  | } | 
|  | template void f1a<int>(); | 
|  |  | 
|  | template<typename T> void f2() { | 
|  | void g2(enum x2);  // expected-error{{ISO C++ forbids forward references to 'enum' types}} | 
|  | enum x2 { nothing }; | 
|  | } | 
|  | template void f2<int>(); | 
|  |  | 
|  | template<typename T> void f3() { | 
|  | enum class x3; | 
|  | void g3(enum x3); | 
|  | enum class x3 { nothing }; | 
|  | } | 
|  | template void f3<int>(); | 
|  |  | 
|  |  | 
|  | template<typename T> void f4() { | 
|  | void g4(struct x4 {} x);  // expected-error{{'x4' cannot be defined in a parameter type}} | 
|  | } | 
|  | template void f4<int>(); | 
|  |  | 
|  | template<typename T> void f4a() { | 
|  | void g4(union x4 {} x);  // expected-error{{'x4' cannot be defined in a parameter type}} | 
|  | } | 
|  | template void f4a<int>(); | 
|  |  | 
|  |  | 
|  | template <class T> void f(); | 
|  | template <class T> struct S1 { | 
|  | void m() { | 
|  | f<class newclass>(); | 
|  | f<union newunion>(); | 
|  | } | 
|  | }; | 
|  | template struct S1<int>; | 
|  |  | 
|  | template <class T> struct S2 { | 
|  | void m() { | 
|  | f<enum new_enum>();  // expected-error{{ISO C++ forbids forward references to 'enum' types}} | 
|  | } | 
|  | }; | 
|  | template struct S2<int>; | 
|  |  | 
|  | template <class T> struct S3 { | 
|  | void m() { | 
|  | enum class new_enum; | 
|  | f<enum new_enum>(); | 
|  | } | 
|  | }; | 
|  | template struct S3<int>; | 
|  |  | 
|  | template <class T> struct S4 { | 
|  | struct local {}; | 
|  | void m() { | 
|  | f<local>(); | 
|  | } | 
|  | }; | 
|  | template struct S4<int>; | 
|  |  | 
|  | template <class T> struct S4a { | 
|  | union local {}; | 
|  | void m() { | 
|  | f<local>(); | 
|  | } | 
|  | }; | 
|  | template struct S4a<int>; | 
|  |  | 
|  | template <class T> struct S5 { | 
|  | enum local { nothing }; | 
|  | void m() { | 
|  | f<local>(); | 
|  | } | 
|  | }; | 
|  | template struct S5<int>; | 
|  |  | 
|  | template <class T> struct S7 { | 
|  | enum class local { nothing }; | 
|  | void m() { | 
|  | f<local>(); | 
|  | } | 
|  | }; | 
|  | template struct S7<int>; | 
|  |  | 
|  |  | 
|  | template <class T> void fff(T *x); | 
|  | template <class T> struct S01 { | 
|  | struct local { }; | 
|  | void m() { | 
|  | local x; | 
|  | fff(&x); | 
|  | } | 
|  | }; | 
|  | template struct S01<int>; | 
|  |  | 
|  | template <class T> struct S01a { | 
|  | union local { }; | 
|  | void m() { | 
|  | local x; | 
|  | fff(&x); | 
|  | } | 
|  | }; | 
|  | template struct S01a<int>; | 
|  |  | 
|  | template <class T> struct S02 { | 
|  | enum local { nothing }; | 
|  | void m() { | 
|  | local x; | 
|  | fff(&x); | 
|  | } | 
|  | }; | 
|  | template struct S02<int>; | 
|  |  | 
|  | template <class T> struct S03 { | 
|  | enum class local { nothing }; | 
|  | void m() { | 
|  | local x; | 
|  | fff(&x); | 
|  | } | 
|  | }; | 
|  | template struct S03<int>; | 
|  |  | 
|  |  | 
|  | template <class T> struct S04 { | 
|  | void m() { | 
|  | struct { } x; | 
|  | fff(&x); | 
|  | } | 
|  | }; | 
|  | template struct S04<int>; | 
|  |  | 
|  | template <class T> struct S04a { | 
|  | void m() { | 
|  | union { } x; | 
|  | fff(&x); | 
|  | } | 
|  | }; | 
|  | template struct S04a<int>; | 
|  |  | 
|  | template <class T> struct S05 { | 
|  | void m() { | 
|  | enum { nothing } x; | 
|  | fff(&x); | 
|  | } | 
|  | }; | 
|  | template struct S05<int>; | 
|  |  | 
|  | template <class T> struct S06 { | 
|  | void m() { | 
|  | class { virtual void mmm() {} } x; | 
|  | fff(&x); | 
|  | } | 
|  | }; | 
|  | template struct S06<int>; | 
|  | } | 
|  |  | 
|  | namespace PR20625 { | 
|  | template <typename T> | 
|  | void f() { | 
|  | struct N { | 
|  | static constexpr int get() { return 42; } | 
|  | }; | 
|  | constexpr int n = N::get(); | 
|  | static_assert(n == 42, "n == 42"); | 
|  | } | 
|  |  | 
|  | void g() { f<void>(); } | 
|  | } | 
|  |  | 
|  |  | 
|  | namespace PR21332 { | 
|  | template<typename T> void f1() { | 
|  | struct S {  // expected-note{{in instantiation of member class 'S' requested here}} | 
|  | void g1(int n = T::error);  // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} \ | 
|  | // expected-note {{in instantiation of default function argument expression for 'g1<int>' required here}} | 
|  | }; | 
|  | } | 
|  | template void f1<int>();  // expected-note{{in instantiation of function template specialization 'PR21332::f1<int>' requested here}} | 
|  |  | 
|  | template<typename T> void f2() { | 
|  | struct S {  // expected-note{{in instantiation of member class 'S' requested here}} | 
|  | void g2() noexcept(T::error);  // expected-error{{type 'int' cannot be used prior to '::' because it has no members}} | 
|  | }; | 
|  | } | 
|  | template void f2<int>();  // expected-note{{in instantiation of function template specialization 'PR21332::f2<int>' requested here}} | 
|  |  | 
|  | template<typename T> void f3() { | 
|  | enum S { | 
|  | val = T::error;  // expected-error{{expected '}' or ','}} expected-error{{type 'int' cannot be used prior to '::' because it has no members}} | 
|  | }; | 
|  | } | 
|  | template void f3<int>();  //expected-note{{in instantiation of function template specialization 'PR21332::f3<int>' requested here}} | 
|  |  | 
|  | template<typename T> void f4() { | 
|  | enum class S { | 
|  | val = T::error;  // expected-error{{expected '}' or ','}} expected-error{{type 'int' cannot be used prior to '::' because it has no members}} | 
|  | }; | 
|  | } | 
|  | template void f4<int>();  // expected-note{{in instantiation of function template specialization 'PR21332::f4<int>' requested here}} | 
|  |  | 
|  | template<typename T> void f5() { | 
|  | class S {  // expected-note {{in instantiation of default member initializer 'PR21332::f5()::S::val' requested here}} | 
|  | int val = T::error;  // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} | 
|  | }; | 
|  | } | 
|  | template void f5<int>();  // expected-note {{in instantiation of function template specialization 'PR21332::f5<int>' requested here}} | 
|  |  | 
|  | template<typename T> void f6() { | 
|  | class S {  // expected-note {{in instantiation of member function 'PR21332::f6()::S::get' requested here}} | 
|  | void get() { | 
|  | class S2 {  // expected-note {{in instantiation of member class 'S2' requested here}} | 
|  | void g1(int n = T::error);  // expected-error {{type 'int' cannot be used prior to '::' because it has no members}} \ | 
|  | // expected-note  {{in instantiation of default function argument expression for 'g1<int>' required here}} | 
|  | }; | 
|  | } | 
|  | }; | 
|  | } | 
|  | template void f6<int>();  // expected-note{{in instantiation of function template specialization 'PR21332::f6<int>' requested here}} | 
|  |  | 
|  | template<typename T> void f7() { | 
|  | struct S { void g() noexcept(undefined_val); };  // expected-error{{use of undeclared identifier 'undefined_val'}} | 
|  | } | 
|  | template void f7<int>(); | 
|  | } | 
|  |  | 
|  | // Ensure that we correctly perform implicit conversions when instantiating the | 
|  | // default arguments of local functions. | 
|  | namespace rdar23721638 { | 
|  | struct A { | 
|  | A(const char *) = delete;  // expected-note 2 {{explicitly marked deleted here}} | 
|  | }; | 
|  |  | 
|  | template <typename T> void foo() { | 
|  | struct Inner { // expected-note {{in instantiation}} | 
|  | void operator()(T a = "") {} // expected-error {{conversion function from 'const char[1]' to 'rdar23721638::A' invokes a deleted function}} \ | 
|  | // expected-note  {{in instantiation of default function argument expression for 'operator()<rdar23721638::A>' required here}} \ | 
|  | // expected-note  {{passing argument to parameter 'a' here}} | 
|  | }; | 
|  | Inner()(); | 
|  | } | 
|  | template void foo<A>(); // expected-note {{in instantiation}} | 
|  |  | 
|  | template <typename T> void bar() { | 
|  | auto lambda = [](T a = "") {}; // expected-error {{conversion function from 'const char[1]' to 'rdar23721638::A' invokes a deleted function}} \ | 
|  | // expected-note  {{in instantiation of default function argument expression for 'operator()<rdar23721638::A>' required here}} \ | 
|  | // expected-note  {{passing argument to parameter 'a' here}} | 
|  | lambda(); | 
|  | } | 
|  | template void bar<A>(); // expected-note {{in instantiation}} | 
|  | } | 
|  |  | 
|  | namespace anon_union_default_member_init { | 
|  | template<typename T> void f() { | 
|  | struct S { | 
|  | union { | 
|  | int i = 0; | 
|  | }; | 
|  | }; | 
|  | } | 
|  | void g() { f<int>(); } | 
|  | } | 
|  |  | 
|  | namespace PR45000 { | 
|  | template <typename T> | 
|  | void f(int x = [](T x = nullptr) -> int { return x; }()); | 
|  | // expected-error@-1 {{cannot initialize a parameter of type 'int' with an rvalue of type 'std::nullptr_t'}} | 
|  | // expected-note@-2  {{in instantiation of default function argument expression for 'operator()<int>' required here}} | 
|  | // expected-note@-3  {{passing argument to parameter 'x' here}} | 
|  |  | 
|  | void g() { f<int>(); } | 
|  | // expected-note@-1 {{in instantiation of default function argument expression for 'f<int>' required here}} | 
|  | } | 
|  |  | 
|  | namespace LambdaInDefaultMemberInitializer { | 
|  | template<typename T> void f() { | 
|  | struct S { | 
|  | void *p = [this] { return &p; }(); | 
|  | }; | 
|  | } | 
|  | template void f<int>(); | 
|  | } | 
|  |  | 
|  | #if __cplusplus >= 201703L | 
|  |  | 
|  | // Reduced from https://github.com/llvm/llvm-project/issues/98526 | 
|  | // This relies on the deferral instantiation of the local lambda, otherwise we would fail in DeduceReturnType(). | 
|  | namespace local_recursive_lambda { | 
|  |  | 
|  | template <typename F> struct recursive_lambda { | 
|  | template <typename... Args> auto operator()(Args &&...args) const { | 
|  | return fn(*this, args...); | 
|  | } | 
|  | F fn; | 
|  | }; | 
|  |  | 
|  | template <typename F> recursive_lambda(F) -> recursive_lambda<F>; | 
|  |  | 
|  | void foo() { | 
|  | recursive_lambda{[&](auto &self_fn, int) -> int { | 
|  | return self_fn(0); | 
|  | }}(0); | 
|  | } | 
|  |  | 
|  | } // namespace local_recursive_lambda | 
|  |  | 
|  | #endif | 
|  |  | 
|  | namespace PR134038_Regression { | 
|  |  | 
|  | template <class T> class G { | 
|  | public: | 
|  | template <class> class Iter { | 
|  | public: | 
|  | Iter(); | 
|  | ~Iter(); | 
|  |  | 
|  | operator G<T>(); | 
|  | }; | 
|  | }; | 
|  |  | 
|  | template <class ObserverType> | 
|  | template <class ContainerType> | 
|  | G<ObserverType>::Iter<ContainerType>::Iter() {} | 
|  |  | 
|  | template <class ObserverType> | 
|  | template <class ContainerType> | 
|  | G<ObserverType>::Iter<ContainerType>::~Iter() {} | 
|  |  | 
|  | template <class ObserverType> | 
|  | template <class ContainerType> | 
|  | G<ObserverType>::Iter<ContainerType>::operator G<ObserverType>() { | 
|  | return G<ObserverType>{}; | 
|  | } | 
|  |  | 
|  | void NotifySettingChanged()  { | 
|  | G<int>::Iter<int> Iter; | 
|  | G<int> g = Iter; | 
|  | } | 
|  |  | 
|  | } |