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