1 // RUN: %clang_cc1 -fsyntax-only -verify %s
2 struct A0 {
3   struct K { };
4 };
5 
6 template <typename T> struct B0: A0 {
7   static void f() {
8     K k;
9   }
10 };
11 
12 namespace 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 
27 namespace 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 
45 namespace 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