summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaTemplate/ms-delayed-default-template-args.cpp
diff options
context:
space:
mode:
authorReid Kleckner <reid@kleckner.net>2014-06-06 22:36:36 +0000
committerReid Kleckner <reid@kleckner.net>2014-06-06 22:36:36 +0000
commitdf6e4a06e42b8282220a73e6299b30ff2ec329ed (patch)
tree1384aa1336da74d0c26d9a12c19d3f4da9acf480 /clang/test/SemaTemplate/ms-delayed-default-template-args.cpp
parent57e06dfb4123b2dc2b3483931f8319cc35bb44b3 (diff)
downloadbcm5719-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.cpp96
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
OpenPOWER on IntegriCloud