p3.cpp revision 746619a5ace6dcbd0970e904b1ebda838064ec03
15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// RUN: %clang_cc1 -fsyntax-only -verify %s
25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liustruct A0 {
35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  struct K { };
45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liutemplate <typename T> struct B0: A0 {
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  static void f() {
85c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    K k;
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu};
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liunamespace E1 {
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  typedef double A;
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  template<class T> class B {
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    typedef int A;
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  };
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  template<class T>
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  struct X : B<T> {
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    A* blarg(double *dp) {
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return dp;
235c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  };
255c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
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