diff options
author | Reid Kleckner <reid@kleckner.net> | 2014-06-06 22:36:36 +0000 |
---|---|---|
committer | Reid Kleckner <reid@kleckner.net> | 2014-06-06 22:36:36 +0000 |
commit | df6e4a06e42b8282220a73e6299b30ff2ec329ed (patch) | |
tree | 1384aa1336da74d0c26d9a12c19d3f4da9acf480 /clang/test/SemaTemplate/ms-delayed-default-template-args.cpp | |
parent | 57e06dfb4123b2dc2b3483931f8319cc35bb44b3 (diff) | |
download | bcm5719-llvm-df6e4a06e42b8282220a73e6299b30ff2ec329ed.tar.gz bcm5719-llvm-df6e4a06e42b8282220a73e6299b30ff2ec329ed.zip |
Delay lookup of simple default template arguments under -fms-compatibility
MSVC delays parsing of default arguments until instantiation. If the
default argument is never used, it is never parsed. We don't model
this.
Instead, if lookup of a type name fails in a template argument context,
we form a DependentNameType, which will be looked up at instantiation
time.
This fixes errors about 'CControlWinTraits' in atlwin.h.
Reviewers: rsmith
Differential Revision: http://reviews.llvm.org/D3995
llvm-svn: 210382
Diffstat (limited to 'clang/test/SemaTemplate/ms-delayed-default-template-args.cpp')
-rw-r--r-- | clang/test/SemaTemplate/ms-delayed-default-template-args.cpp | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp b/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp new file mode 100644 index 00000000000..ca9ddb0d9d1 --- /dev/null +++ b/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp @@ -0,0 +1,96 @@ +// 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 |