1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
2d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor
3eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregornamespace PR8965 {
4eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor  template<typename T>
5eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor  struct X {
6eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor    typedef int type;
7eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor
8eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor    T field; // expected-note{{in instantiation of member class}}
9eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor  };
10eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor
11eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor  template<typename T>
12eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor  struct Y {
13eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor    struct Inner;
14eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor
15eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor    typedef typename X<Inner>::type // expected-note{{in instantiation of template class}}
16eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor      type; // expected-note{{not-yet-instantiated member is declared here}}
17eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor
18eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor    struct Inner {
19eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor      typedef type field; // expected-error{{no member 'type' in 'PR8965::Y<int>'; it has not yet been instantiated}}
20eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor    };
21eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor  };
22eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor
23eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor  Y<int> y; // expected-note{{in instantiation of template class}}
24eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor}
25eff1dbec93999bfc5406eb861efd8add9de23633Douglas Gregor
26d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregortemplate<typename T>
27d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregorclass X {
28d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregorpublic:
29d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor  struct C { T &foo(); };
30d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor
31d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor  struct D {
32d048bb79f5c3b3751878aec038bce28a5ce0f439Douglas Gregor    struct E { T &bar(); }; // expected-error{{cannot form a reference to 'void'}}
33d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor    struct F; // expected-note{{member is declared here}}
34d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor  };
35d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor};
36d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor
37d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas GregorX<int>::C *c1;
38d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas GregorX<float>::C *c2;
39d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor
400efc2c1716be4f1c5f1343cad3b047e74861f030Douglas GregorX<int>::X *xi; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}}
410efc2c1716be4f1c5f1343cad3b047e74861f030Douglas GregorX<float>::X *xf; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}}
42d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor
43d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregorvoid test_naming() {
44d4eea8362605807327735727a9098abe1eb23b19Douglas Gregor  c1 = c2; // expected-error{{assigning to 'X<int>::C *' from incompatible type 'X<float>::C *'}}
45d4eea8362605807327735727a9098abe1eb23b19Douglas Gregor  xi = xf;  // expected-error{{assigning to 'X<int>::X<int> *' from incompatible type 'X<float>::X<float> *'}}
46d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor    // FIXME: error above doesn't print the type X<int>::X cleanly!
47d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor}
48d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor
49d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregorvoid test_instantiation(X<double>::C *x,
50d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor                        X<float>::D::E *e,
51d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor                        X<float>::D::F *f) {
52d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor  double &dr = x->foo();
53d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor  float &fr = e->bar();
547c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  f->foo(); // expected-error{{implicit instantiation of undefined member 'X<float>::D::F'}}
55d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor
56d475b8d9e6f5ff0e6ab8d15667ce8a64c7cb9a4dDouglas Gregor}
57d048bb79f5c3b3751878aec038bce28a5ce0f439Douglas Gregor
58d048bb79f5c3b3751878aec038bce28a5ce0f439Douglas Gregor
59d048bb79f5c3b3751878aec038bce28a5ce0f439Douglas GregorX<void>::C *c3; // okay
60d048bb79f5c3b3751878aec038bce28a5ce0f439Douglas GregorX<void>::D::E *e1; // okay
617c2342dd4c9947806842e5aca3d2bb2e542853c9John McCallX<void>::D::E e2; // expected-note{{in instantiation of member class 'X<void>::D::E' requested here}}
626c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall
636c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall// Redeclarations.
646c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCallnamespace test1 {
656c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall  template <typename T> struct Registry {
667002f4c03c2d0544f4e8bea8d3a5636519081e35John McCall    struct node;
676c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall    static node *Head;
687002f4c03c2d0544f4e8bea8d3a5636519081e35John McCall    struct node {
696c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall      node(int v) { Head = this; }
706c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall    };
716c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall  };
726c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall  void test() {
736c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall    Registry<int>::node node(0);
746c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall  }
756c1c1b8c6ca743a5b6b4c81f9ac56392c12c7457John McCall}
762243288c4826905b5a0837f6f21d9d821688652eJohn McCall
772243288c4826905b5a0837f6f21d9d821688652eJohn McCall// Redeclarations during explicit instantiations.
782243288c4826905b5a0837f6f21d9d821688652eJohn McCallnamespace test2 {
792243288c4826905b5a0837f6f21d9d821688652eJohn McCall  template <typename T> class A {
802243288c4826905b5a0837f6f21d9d821688652eJohn McCall    class Foo;
812243288c4826905b5a0837f6f21d9d821688652eJohn McCall    class Foo {
822243288c4826905b5a0837f6f21d9d821688652eJohn McCall      int foo();
832243288c4826905b5a0837f6f21d9d821688652eJohn McCall    };
842243288c4826905b5a0837f6f21d9d821688652eJohn McCall  };
852243288c4826905b5a0837f6f21d9d821688652eJohn McCall  template class A<int>;
862243288c4826905b5a0837f6f21d9d821688652eJohn McCall
872243288c4826905b5a0837f6f21d9d821688652eJohn McCall  template <typename T> class B {
882243288c4826905b5a0837f6f21d9d821688652eJohn McCall    class Foo;
892243288c4826905b5a0837f6f21d9d821688652eJohn McCall    class Foo {
907002f4c03c2d0544f4e8bea8d3a5636519081e35John McCall    public:
912243288c4826905b5a0837f6f21d9d821688652eJohn McCall      typedef int X;
922243288c4826905b5a0837f6f21d9d821688652eJohn McCall    };
932243288c4826905b5a0837f6f21d9d821688652eJohn McCall    typename Foo::X x;
942243288c4826905b5a0837f6f21d9d821688652eJohn McCall    class Foo;
952243288c4826905b5a0837f6f21d9d821688652eJohn McCall  };
962243288c4826905b5a0837f6f21d9d821688652eJohn McCall  template class B<int>;
972243288c4826905b5a0837f6f21d9d821688652eJohn McCall
982243288c4826905b5a0837f6f21d9d821688652eJohn McCall  template <typename T> class C {
992243288c4826905b5a0837f6f21d9d821688652eJohn McCall    class Foo;
1002243288c4826905b5a0837f6f21d9d821688652eJohn McCall    class Foo;
1012243288c4826905b5a0837f6f21d9d821688652eJohn McCall  };
1022243288c4826905b5a0837f6f21d9d821688652eJohn McCall  template <typename T> class C<T>::Foo {
1032243288c4826905b5a0837f6f21d9d821688652eJohn McCall    int x;
1042243288c4826905b5a0837f6f21d9d821688652eJohn McCall  };
1052243288c4826905b5a0837f6f21d9d821688652eJohn McCall  template class C<int>;
1062243288c4826905b5a0837f6f21d9d821688652eJohn McCall}
107c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith
108c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smithnamespace AliasTagDef {
109c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith  template<typename T>
110c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith  struct F {
111b3df1386680b3830d2f4d300d4d7eaba134135fcDouglas Gregor    using S = struct U { // expected-warning {{C++11}}
112c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith      T g() {
113c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith        return T();
114c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith      }
115c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith    };
116c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith  };
117c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith
118c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith  int m = F<int>::S().g();
119c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith  int n = F<int>::U().g();
120c89edf5aaa08683f4afcf61a7a1d183c08b76498Richard Smith}
121efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor
122efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregornamespace rdar10397846 {
123efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  template<int I> struct A
124efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  {
125efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor    struct B
126efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor    {
12750800fc551ac6b8a95cca662223e7f061bbd169aDavid Blaikie      struct C { C() { int *ptr = I; } }; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} \
12850800fc551ac6b8a95cca662223e7f061bbd169aDavid Blaikie                                             expected-warning{{expression which evaluates to zero treated as a null pointer constant of type 'int *'}}
129efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor    };
130efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  };
131efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor
132efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  template<int N> void foo()
133efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  {
13450800fc551ac6b8a95cca662223e7f061bbd169aDavid Blaikie    class A<N>::B::C X; // expected-note 2 {{in instantiation of member function}}
135efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor    int A<N+1>::B::C::*member = 0;
136efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  }
137efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor
138efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  void bar()
139efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  {
14050800fc551ac6b8a95cca662223e7f061bbd169aDavid Blaikie    foo<0>(); // expected-note{{in instantiation of function template}}
141efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor    foo<1>(); // expected-note{{in instantiation of function template}}
142efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor  }
143efaa93aaa2653f4eb40e6a22e504a448da94aaf8Douglas Gregor}
144