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