1// RUN: %clang_cc1 -fsyntax-only -verify %s 2struct A0 { 3 struct K { }; 4}; 5 6template <typename T> struct B0: A0 { 7 static void f() { 8 K k; 9 } 10}; 11 12namespace E1 { 13 typedef double A; 14 15 template<class T> class B { 16 typedef int A; 17 }; 18 19 template<class T> 20 struct X : B<T> { 21 A* blarg(double *dp) { 22 return dp; 23 } 24 }; 25} 26 27namespace E2 { 28 struct A { 29 struct B; 30 int *a; 31 int Y; 32 }; 33 34 int a; 35 template<class T> struct Y : T { 36 struct B { /* ... */ }; 37 B b; 38 void f(int i) { a = i; } 39 Y* p; 40 }; 41 42 Y<A> ya; 43} 44 45namespace PR14402 { 46 template<typename T> 47 struct A { 48 typedef int n; 49 int f(); 50 51 struct B {}; 52 struct C : B { 53 // OK, can't be sure whether we derive from A yet. 54 using A::n; 55 int g() { return f(); } 56 }; 57 58 struct D { 59 using A::n; // expected-error {{using declaration refers into 'A<T>::', which is not a base class of 'D'}} 60 int g() { return f(); } // expected-error {{call to non-static member function 'f' of 'A' from nested type 'D'}} 61 }; 62 63 struct E { char &f(); }; 64 struct F : E { 65 // FIXME: Reject this prior to instantiation; f() is known to return int. 66 char &g() { return f(); } 67 // expected-error@-1 {{'PR14402::A<int>::f' is not a member of class 'PR14402::A<int>::F'}} 68 // expected-error@-2 {{non-const lvalue reference to type 'char' cannot bind to a temporary of type 'int'}} 69 }; 70 }; 71 72 template<> struct A<int>::B : A<int> {}; 73 A<int>::C::n n = A<int>::C().g(); 74 75 // 'not a member' 76 char &r = A<int>::F().g(); // expected-note {{in instantiation of}} 77 template<> struct A<char>::E : A<char> {}; 78 // 'cannot bind to a temporary' 79 char &s = A<char>::F().g(); // expected-note {{in instantiation of}} 80 81 struct X; 82 struct X { void f(); }; 83 struct X; 84 template<typename T> struct Y : X { 85 void g() { 86 X::f(); 87 } 88 }; 89} 90