1*67e74705SXin Li // RUN: %clang_cc1 -std=c++11 -verify %s 2*67e74705SXin Li 3*67e74705SXin Li // Check that we deal with cases where the instantiation of a class template 4*67e74705SXin Li // recursively requires the instantiation of the same template. 5*67e74705SXin Li namespace test1 { 6*67e74705SXin Li template<typename T> struct A { 7*67e74705SXin Li struct B { // expected-note {{not complete until the closing '}'}} 8*67e74705SXin Li B b; // expected-error {{has incomplete type 'test1::A<int>::B'}} 9*67e74705SXin Li }; 10*67e74705SXin Li B b; // expected-note {{in instantiation of}} 11*67e74705SXin Li }; 12*67e74705SXin Li A<int> a; // expected-note {{in instantiation of}} 13*67e74705SXin Li } 14*67e74705SXin Li 15*67e74705SXin Li namespace test2 { 16*67e74705SXin Li template<typename T> struct A { 17*67e74705SXin Li struct B { 18*67e74705SXin Li struct C {}; 19*67e74705SXin Li char c[1 + C()]; // expected-error {{invalid operands to binary expression}} operator +test2::A20*67e74705SXin Li friend constexpr int operator+(int, C) { return 4; } 21*67e74705SXin Li }; 22*67e74705SXin Li B b; // expected-note {{in instantiation of}} 23*67e74705SXin Li }; 24*67e74705SXin Li A<int> a; // expected-note {{in instantiation of}} 25*67e74705SXin Li } 26*67e74705SXin Li 27*67e74705SXin Li namespace test3 { 28*67e74705SXin Li // PR12317 29*67e74705SXin Li template<typename T> struct A { 30*67e74705SXin Li struct B { 31*67e74705SXin Li enum { Val = 1 }; 32*67e74705SXin Li char c[1 + Val]; // ok 33*67e74705SXin Li }; 34*67e74705SXin Li B b; 35*67e74705SXin Li }; 36*67e74705SXin Li A<int> a; 37*67e74705SXin Li } 38*67e74705SXin Li 39*67e74705SXin Li namespace test4 { 40*67e74705SXin Li template<typename T> struct M { typedef int type; }; 41*67e74705SXin Li template<typename T> struct A { 42*67e74705SXin Li struct B { // expected-note {{not complete until the closing '}'}} 43*67e74705SXin Li int k[typename A<typename M<T>::type>::B().k[0] + 1]; // expected-error {{incomplete type}} 44*67e74705SXin Li }; 45*67e74705SXin Li B b; // expected-note {{in instantiation of}} 46*67e74705SXin Li }; 47*67e74705SXin Li A<int> a; // expected-note {{in instantiation of}} 48*67e74705SXin Li } 49*67e74705SXin Li 50*67e74705SXin Li // FIXME: PR12298: Recursive constexpr function template instantiation leads to 51*67e74705SXin Li // stack overflow. 52*67e74705SXin Li #if 0 53*67e74705SXin Li namespace test5 { 54*67e74705SXin Li template<typename T> struct A { 55*67e74705SXin Li constexpr T f(T k) { return g(k); } 56*67e74705SXin Li constexpr T g(T k) { 57*67e74705SXin Li return k ? f(k-1)+1 : 0; 58*67e74705SXin Li } 59*67e74705SXin Li }; 60*67e74705SXin Li // This should be accepted. 61*67e74705SXin Li constexpr int x = A<int>().f(5); 62*67e74705SXin Li } 63*67e74705SXin Li 64*67e74705SXin Li namespace test6 { 65*67e74705SXin Li template<typename T> constexpr T f(T); 66*67e74705SXin Li template<typename T> constexpr T g(T t) { 67*67e74705SXin Li typedef int arr[f(T())]; 68*67e74705SXin Li return t; 69*67e74705SXin Li } 70*67e74705SXin Li template<typename T> constexpr T f(T t) { 71*67e74705SXin Li typedef int arr[g(T())]; 72*67e74705SXin Li return t; 73*67e74705SXin Li } 74*67e74705SXin Li // This should be ill-formed. 75*67e74705SXin Li int n = f(0); 76*67e74705SXin Li } 77*67e74705SXin Li 78*67e74705SXin Li namespace test7 { 79*67e74705SXin Li template<typename T> constexpr T g(T t) { 80*67e74705SXin Li return t; 81*67e74705SXin Li } 82*67e74705SXin Li template<typename T> constexpr T f(T t) { 83*67e74705SXin Li typedef int arr[g(T())]; 84*67e74705SXin Li return t; 85*67e74705SXin Li } 86*67e74705SXin Li // This should be accepted. 87*67e74705SXin Li int n = f(0); 88*67e74705SXin Li } 89*67e74705SXin Li #endif 90