p3.cpp revision f62c690c55fb920f3ba0a4f6e6e259e2ae7ce297
1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org// RUN: %clang_cc1 -fsyntax-only -verify %s
2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct A0 {
3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  struct K { };
4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgtemplate <typename T> struct B0: A0 {
7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  static void f() {
8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    K k;
9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  }
10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org};
11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace E1 {
13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  typedef double A;
14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  template<class T> class B {
16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    typedef int A;
17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  };
18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  template<class T>
20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  struct X : B<T> {
21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    A* blarg(double *dp) {
22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org      return dp;
23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    }
24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  };
25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}
26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgnamespace E2 {
28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  struct A {
29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    struct B;
30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int *a;
31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org    int Y;
32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org  };
33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org
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