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