1 // RUN: rm -rf %t
2 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -fno-modules-error-recovery -I %S/Inputs/template-default-args -std=c++11 %s -DBEGIN= -DEND=
3 // RUN: %clang_cc1 -fmodules -fimplicit-module-maps -verify -fmodules-cache-path=%t -fno-modules-error-recovery -I %S/Inputs/template-default-args -std=c++11 %s -DBEGIN="namespace N {" -DEND="}"
4 
5 BEGIN
6 template<typename T> struct A;
7 template<typename T> struct B;
8 template<typename T> struct C;
9 template<typename T = int> struct D;
10 template<typename T = int> struct E {};
11 template<typename T> struct H {};
12 template<typename T = int, typename U = int> struct I {};
13 END
14 
15 #include "b.h"
16 #include "d.h"
17 
18 BEGIN
19 template<typename T = int> struct A {};
20 template<typename T> struct B {};
21 template<typename T = int> struct B;
22 template<typename T = int> struct C;
23 template<typename T> struct D {};
24 template<typename T> struct F {};
25 template<typename T> struct G {};
26 template<typename T> struct J {};
27 template<typename T = int> struct J;
28 struct K : J<> {};
29 END
30 
31 #include "c.h"
32 
33 BEGIN
34 A<> a;
35 B<> b;
36 extern C<> c;
37 D<> d;
38 E<> e;
39 F<> f;
40 G<> g; // expected-error {{missing '#include "a.h"'; default argument of 'G' must be defined before it is used}}
41 // expected-note@a.h:7 {{default argument declared here is not reachable}}
42 H<> h; // expected-error {{missing '#include "a.h"'; default argument of 'H' must be defined before it is used}}
43 // expected-note@a.h:8 {{default argument declared here is not reachable}}
44 I<> i;
45 L<> *l;
46 END
47 
48 namespace DeferredLookup {
49   template<typename T, typename U = T> using X = U;
f()50   template<typename T> void f() { (void) X<T>(); }
51   template<typename T> int n = X<T>(); // expected-warning {{extension}}
52   template<typename T> struct S { X<T> xt; enum E : int; };
53   template<typename T> enum S<T>::E : int { a = X<T>() };
54 
test()55   void test() {
56     f<int>();
57     n<int> = 1;
58     S<int> s;
59     S<int>::E e = S<int>::E::a;
60 
61     Indirect::B<int>::C<int> indirect;
62   }
63 }
64