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