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