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 // MSVC accepts this, but Clang doesn't. 59 namespace test_scope_spec { 60 template <typename T = ns::Bar> // expected-error {{use of undeclared identifier 'ns'}} 61 struct Foo { 62 static_assert(sizeof(T) == 4, "Bar should have gotten int"); 63 }; 64 namespace ns { typedef int Bar; } 65 } 66 67 #ifdef __clang__ 68 // These are negative test cases that MSVC doesn't compile either. Try to use 69 // unique undeclared identifiers so typo correction doesn't find types declared 70 // above. 71 72 namespace test_undeclared_nontype_parm_type { 73 template <Zargon N> // expected-error {{unknown type name 'Zargon'}} 74 struct Foo { int x[N]; }; 75 typedef int Zargon; 76 template struct Foo<4>; 77 } 78 79 namespace test_undeclared_nontype_parm_type_no_name { 80 template <typename T, Asdf> // expected-error {{unknown type name 'Asdf'}} 81 struct Foo { T x; }; 82 template struct Foo<int, 0>; 83 } 84 85 namespace test_undeclared_type_arg { 86 template <typename T> 87 struct Foo { T x; }; 88 template struct Foo<Yodel>; // expected-error {{use of undeclared identifier 'Yodel'}} 89 } 90 91 namespace test_undeclared_nontype_parm_arg { 92 // Bury an undeclared type as a template argument to the type of a non-type 93 // template parameter. 94 template <typename T> struct Bar { T x; }; 95 96 template <Bar<Xylophone> *P> // expected-error {{use of undeclared identifier 'Xylophone'}} 97 // expected-note@-1 {{template parameter is declared here}} 98 struct Foo { }; 99 100 typedef int Xylophone; 101 Bar<Xylophone> g; 102 template struct Foo<&g>; // expected-error {{cannot be converted}} 103 } 104 105 #endif 106