18c614e4f2b07741130e6c99a971a7093358fb9e4Richard Smith// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
2d46a1125d43bcfd47fbd1206ebd1226863549390John McCall
3d46a1125d43bcfd47fbd1206ebd1226863549390John McCall// C++11 [class.mem]p2:
4d46a1125d43bcfd47fbd1206ebd1226863549390John McCall//   A class is considered a completely-defined object type (or
5d46a1125d43bcfd47fbd1206ebd1226863549390John McCall//   complete type) at the closing } of the class-specifier. Within
6d46a1125d43bcfd47fbd1206ebd1226863549390John McCall//   the class member-specification, the class is regarded as complete
7d46a1125d43bcfd47fbd1206ebd1226863549390John McCall//   within function bodies, default arguments,
8d46a1125d43bcfd47fbd1206ebd1226863549390John McCall//   exception-specifications, and brace-or-equal-initializers for
9d46a1125d43bcfd47fbd1206ebd1226863549390John McCall//   non-static data members (including such things in nested classes).
10d46a1125d43bcfd47fbd1206ebd1226863549390John McCall//   Otherwise it is regarded as incomplete within its own class
11d46a1125d43bcfd47fbd1206ebd1226863549390John McCall//   member-specification.
12d46a1125d43bcfd47fbd1206ebd1226863549390John McCall
13d46a1125d43bcfd47fbd1206ebd1226863549390John McCallnamespace test0 {
14d46a1125d43bcfd47fbd1206ebd1226863549390John McCall  struct A { // expected-note {{definition of 'test0::A' is not complete until the closing '}'}}
15d46a1125d43bcfd47fbd1206ebd1226863549390John McCall    A x; // expected-error {{field has incomplete type 'test0::A'}}
16d46a1125d43bcfd47fbd1206ebd1226863549390John McCall  };
17d46a1125d43bcfd47fbd1206ebd1226863549390John McCall}
18d46a1125d43bcfd47fbd1206ebd1226863549390John McCall
19d46a1125d43bcfd47fbd1206ebd1226863549390John McCallnamespace test1 {
20d46a1125d43bcfd47fbd1206ebd1226863549390John McCall  template <class T> struct A {
21d46a1125d43bcfd47fbd1206ebd1226863549390John McCall    A<int> x; // expected-error {{implicit instantiation of template 'test1::A<int>' within its own definition}}
22d46a1125d43bcfd47fbd1206ebd1226863549390John McCall  };
23d46a1125d43bcfd47fbd1206ebd1226863549390John McCall}
24d46a1125d43bcfd47fbd1206ebd1226863549390John McCall
25d46a1125d43bcfd47fbd1206ebd1226863549390John McCallnamespace test2 {
26d46a1125d43bcfd47fbd1206ebd1226863549390John McCall  template <class T> struct A;
27d46a1125d43bcfd47fbd1206ebd1226863549390John McCall  template <> struct A<int> {};
28d46a1125d43bcfd47fbd1206ebd1226863549390John McCall  template <class T> struct A {
29d46a1125d43bcfd47fbd1206ebd1226863549390John McCall    A<int> x;
30d46a1125d43bcfd47fbd1206ebd1226863549390John McCall  };
31d46a1125d43bcfd47fbd1206ebd1226863549390John McCall}
3274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
3374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregornamespace test3 {
3474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  struct A {
3574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    struct B {
3674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      void f() throw(A);
3774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      void g() throw(B);
3874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    };
3974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
4074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    void f() throw(A);
4174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    void g() throw(B);
4274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  };
4374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
4474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  template<typename T>
4574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  struct A2 {
4674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    struct B {
4774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      void f1() throw(A2);
4874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      void f2() throw(A2<T>);
4974e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor      void g() throw(B);
5074e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    };
5174e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
5274e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    void f1() throw(A2);
5374e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    void f2() throw(A2<T>);
5474e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor    void g() throw(B);
5574e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  };
5674e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor
5774e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor  template struct A2<int>;
5874e2fc332e07c76d4e69ccbd0e9e47a0bafd3908Douglas Gregor}
59