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