| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- // RUN: %clang_cc1 -fms-compatibility -std=c++11 %s -verify
- // MSVC should compile this file without errors.
- namespace test_basic {
- template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
- struct Foo { T x; };
- typedef int Baz;
- template struct Foo<>;
- }
- namespace test_namespace {
- namespace nested {
- template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
- struct Foo {
- static_assert(sizeof(T) == 4, "should get int, not double");
- };
- typedef int Baz;
- }
- typedef double Baz;
- template struct nested::Foo<>;
- }
- namespace test_inner_class_template {
- struct Outer {
- template <typename T = Baz> // expected-warning {{using the undeclared type 'Baz' as a default template argument is a Microsoft extension}}
- struct Foo {
- static_assert(sizeof(T) == 4, "should get int, not double");
- };
- typedef int Baz;
- };
- typedef double Baz;
- template struct Outer::Foo<>;
- }
- namespace test_nontype_param {
- template <typename T> struct Bar { T x; };
- typedef int Qux;
- template <Bar<Qux> *P>
- struct Foo {
- };
- Bar<int> g;
- template struct Foo<&g>;
- }
- // MSVC accepts this, but Clang doesn't.
- namespace test_template_instantiation_arg {
- template <typename T> struct Bar { T x; };
- template <typename T = Bar<Weber>> // expected-error {{use of undeclared identifier 'Weber'}}
- struct Foo {
- static_assert(sizeof(T) == 4, "Bar should have gotten int");
- // FIXME: These diagnostics are bad.
- }; // expected-error {{expected ',' or '>' in template-parameter-list}}
- // expected-warning@-1 {{does not declare anything}}
- typedef int Weber;
- }
- #ifdef __clang__
- // These are negative test cases that MSVC doesn't compile either. Try to use
- // unique undeclared identifiers so typo correction doesn't find types declared
- // above.
- namespace test_undeclared_nontype_parm_type {
- template <Zargon N> // expected-error {{unknown type name 'Zargon'}}
- struct Foo { int x[N]; };
- typedef int Zargon;
- template struct Foo<4>;
- }
- namespace test_undeclared_nontype_parm_type_no_name {
- template <typename T, Asdf> // expected-error {{unknown type name 'Asdf'}}
- struct Foo { T x; };
- template struct Foo<int, 0>;
- }
- namespace test_undeclared_type_arg {
- template <typename T>
- struct Foo { T x; };
- template struct Foo<Yodel>; // expected-error {{use of undeclared identifier 'Yodel'}}
- }
- namespace test_undeclared_nontype_parm_arg {
- // Bury an undeclared type as a template argument to the type of a non-type
- // template parameter.
- template <typename T> struct Bar { T x; };
- template <Bar<Xylophone> *P> // expected-error {{use of undeclared identifier 'Xylophone'}}
- // expected-note@-1 {{template parameter is declared here}}
- struct Foo { };
- typedef int Xylophone;
- Bar<Xylophone> g;
- template struct Foo<&g>; // expected-error {{cannot be converted}}
- }
- #endif
|