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