1df6e4a06SReid Kleckner // RUN: %clang_cc1 -fms-compatibility -std=c++11 %s -verify 2df6e4a06SReid Kleckner 3df6e4a06SReid Kleckner // MSVC should compile this file without errors. 4df6e4a06SReid Kleckner 5df6e4a06SReid Kleckner namespace test_basic { 6df6e4a06SReid Kleckner template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}} 7df6e4a06SReid Kleckner struct Foo { T x; }; 8df6e4a06SReid Kleckner typedef int Baz; 9df6e4a06SReid Kleckner template struct Foo<>; 10df6e4a06SReid Kleckner } 11df6e4a06SReid Kleckner 12df6e4a06SReid Kleckner namespace test_namespace { 13df6e4a06SReid Kleckner namespace nested { 14df6e4a06SReid Kleckner template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}} 15df6e4a06SReid Kleckner struct Foo { 16df6e4a06SReid Kleckner static_assert(sizeof(T) == 4, "should get int, not double"); 17df6e4a06SReid Kleckner }; 18df6e4a06SReid Kleckner typedef int Baz; 19df6e4a06SReid Kleckner } 20df6e4a06SReid Kleckner typedef double Baz; 21df6e4a06SReid Kleckner template struct nested::Foo<>; 22df6e4a06SReid Kleckner } 23df6e4a06SReid Kleckner 24df6e4a06SReid Kleckner namespace test_inner_class_template { 25df6e4a06SReid Kleckner struct Outer { 26df6e4a06SReid Kleckner template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}} 27df6e4a06SReid Kleckner struct Foo { 28df6e4a06SReid Kleckner static_assert(sizeof(T) == 4, "should get int, not double"); 29df6e4a06SReid Kleckner }; 30df6e4a06SReid Kleckner typedef int Baz; 31df6e4a06SReid Kleckner }; 32df6e4a06SReid Kleckner typedef double Baz; 33df6e4a06SReid Kleckner template struct Outer::Foo<>; 34df6e4a06SReid Kleckner } 35df6e4a06SReid Kleckner 36df6e4a06SReid Kleckner namespace test_nontype_param { 37df6e4a06SReid Kleckner template <typename T> struct Bar { T x; }; 38df6e4a06SReid Kleckner typedef int Qux; 39df6e4a06SReid Kleckner template <Bar<Qux> *P> 40df6e4a06SReid Kleckner struct Foo { 41df6e4a06SReid Kleckner }; 42df6e4a06SReid Kleckner Bar<int> g; 43df6e4a06SReid Kleckner template struct Foo<&g>; 44df6e4a06SReid Kleckner } 45df6e4a06SReid Kleckner 46df6e4a06SReid Kleckner // MSVC accepts this, but Clang doesn't. 47df6e4a06SReid Kleckner namespace test_template_instantiation_arg { 48df6e4a06SReid Kleckner template <typename T> struct Bar { T x; }; 49df6e4a06SReid Kleckner template <typename T = Bar<Weber>> // expected-error {{use of undeclared identifier 'Weber'}} 50df6e4a06SReid Kleckner struct Foo { 51df6e4a06SReid Kleckner static_assert(sizeof(T) == 4, "Bar should have gotten int"); 52*0c42539dSRichard Smith }; 53df6e4a06SReid Kleckner typedef int Weber; 54df6e4a06SReid Kleckner } 55df6e4a06SReid Kleckner 569a96e420SReid Kleckner // MSVC accepts this, but Clang doesn't. 579a96e420SReid Kleckner namespace test_scope_spec { 589a96e420SReid Kleckner template <typename T = ns::Bar> // expected-error {{use of undeclared identifier 'ns'}} 599a96e420SReid Kleckner struct Foo { 609a96e420SReid Kleckner static_assert(sizeof(T) == 4, "Bar should have gotten int"); 619a96e420SReid Kleckner }; 629a96e420SReid Kleckner namespace ns { typedef int Bar; } 639a96e420SReid Kleckner } 649a96e420SReid Kleckner 65df6e4a06SReid Kleckner #ifdef __clang__ 66df6e4a06SReid Kleckner // These are negative test cases that MSVC doesn't compile either. Try to use 67df6e4a06SReid Kleckner // unique undeclared identifiers so typo correction doesn't find types declared 68df6e4a06SReid Kleckner // above. 69df6e4a06SReid Kleckner 70df6e4a06SReid Kleckner namespace test_undeclared_nontype_parm_type { 71df6e4a06SReid Kleckner template <Zargon N> // expected-error {{unknown type name 'Zargon'}} 72df6e4a06SReid Kleckner struct Foo { int x[N]; }; 73df6e4a06SReid Kleckner typedef int Zargon; 74df6e4a06SReid Kleckner template struct Foo<4>; 75df6e4a06SReid Kleckner } 76df6e4a06SReid Kleckner 77df6e4a06SReid Kleckner namespace test_undeclared_nontype_parm_type_no_name { 78df6e4a06SReid Kleckner template <typename T, Asdf> // expected-error {{unknown type name 'Asdf'}} 79df6e4a06SReid Kleckner struct Foo { T x; }; 80df6e4a06SReid Kleckner template struct Foo<int, 0>; 81df6e4a06SReid Kleckner } 82df6e4a06SReid Kleckner 83df6e4a06SReid Kleckner namespace test_undeclared_type_arg { 84df6e4a06SReid Kleckner template <typename T> 85df6e4a06SReid Kleckner struct Foo { T x; }; 86df6e4a06SReid Kleckner template struct Foo<Yodel>; // expected-error {{use of undeclared identifier 'Yodel'}} 87df6e4a06SReid Kleckner } 88df6e4a06SReid Kleckner 89df6e4a06SReid Kleckner namespace test_undeclared_nontype_parm_arg { 90df6e4a06SReid Kleckner // Bury an undeclared type as a template argument to the type of a non-type 91df6e4a06SReid Kleckner // template parameter. 92df6e4a06SReid Kleckner template <typename T> struct Bar { T x; }; 93df6e4a06SReid Kleckner 94b481f028SSaar Raz template <Bar<Xylophone> *P> // expected-error {{use of undeclared identifier 'Xylophone'}} 95b481f028SSaar Raz // expected-note@-1{{template parameter is declared here}} 96df6e4a06SReid Kleckner struct Foo { }; 97df6e4a06SReid Kleckner 98df6e4a06SReid Kleckner typedef int Xylophone; 99df6e4a06SReid Kleckner Bar<Xylophone> g; 100ff1e0fceSSaar Raz template struct Foo<&g>; // expected-error {{value of type}} 101df6e4a06SReid Kleckner } 102df6e4a06SReid Kleckner 103df6e4a06SReid Kleckner #endif 104