summaryrefslogtreecommitdiffstats
path: root/test/CXX
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-02-20 13:06:31 +0000
committerdim <dim@FreeBSD.org>2011-02-20 13:06:31 +0000
commit39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df (patch)
treea9243275843fbeaa590afc07ee888e006b8d54ea /test/CXX
parent69b4eca4a4255ba43baa5c1d9bbdec3ec17f479e (diff)
downloadFreeBSD-src-39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df.zip
FreeBSD-src-39fcc9a984e2820e4ea0fa2ac4abd17d9f3a31df.tar.gz
Vendor import of clang trunk r126079:
http://llvm.org/svn/llvm-project/cfe/trunk@126079
Diffstat (limited to 'test/CXX')
-rw-r--r--test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp2
-rw-r--r--test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp24
-rw-r--r--test/CXX/basic/basic.start/basic.start.main/p2h.cpp5
-rw-r--r--test/CXX/class.access/class.friend/p1.cpp41
-rw-r--r--test/CXX/class.access/class.friend/p11.cpp19
-rw-r--r--test/CXX/class.access/p4.cpp62
-rw-r--r--test/CXX/class.access/p6.cpp29
-rw-r--r--test/CXX/class.derived/class.abstract/p4.cpp4
-rw-r--r--test/CXX/class.derived/class.abstract/p5.cpp10
-rw-r--r--test/CXX/class.derived/class.member.lookup/p9.cpp28
-rw-r--r--test/CXX/class.derived/class.virtual/p3-0x.cpp53
-rw-r--r--test/CXX/class.derived/p8-0x.cpp22
-rw-r--r--test/CXX/class/class.friend/p1.cpp3
-rw-r--r--test/CXX/class/class.mem/p1.cpp27
-rw-r--r--test/CXX/class/class.mem/p13.cpp40
-rw-r--r--test/CXX/class/class.mem/p14.cpp19
-rw-r--r--test/CXX/class/class.mem/p1b.cpp46
-rw-r--r--test/CXX/class/class.mem/p8-0x-pedantic.cpp14
-rw-r--r--test/CXX/class/class.mem/p8-0x.cpp55
-rw-r--r--test/CXX/class/class.nest/p1-cxx0x.cpp14
-rw-r--r--test/CXX/class/class.nest/p1.cpp6
-rw-r--r--test/CXX/class/class.union/p1.cpp8
-rw-r--r--test/CXX/class/p1-0x.cpp10
-rw-r--r--test/CXX/class/p2-0x.cpp28
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp27
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.def/p2.cpp24
-rw-r--r--test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp1
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp31
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp35
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp73
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp86
-rw-r--r--test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp23
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp164
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp2
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp24
-rw-r--r--test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp20
-rw-r--r--test/CXX/dcl.decl/dcl.init/p6.cpp4
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp1
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp14
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp48
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct/p14.cpp31
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct/p2-cxx0x.cpp5
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp28
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp14
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp10
-rw-r--r--test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp26
-rw-r--r--test/CXX/dcl.decl/p4-0x.cpp8
-rw-r--r--test/CXX/except/except.handle/p16.cpp2
-rw-r--r--test/CXX/except/except.spec/p14-ir.cpp14
-rw-r--r--test/CXX/expr/expr.cast/p4-0x.cpp11
-rw-r--r--test/CXX/expr/expr.cast/p4.cpp23
-rw-r--r--test/CXX/expr/expr.mptr.oper/p5.cpp61
-rw-r--r--test/CXX/expr/expr.mptr.oper/p6-0x.cpp34
-rw-r--r--test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp17
-rw-r--r--test/CXX/expr/expr.post/expr.dynamic.cast/p3-0x.cpp14
-rw-r--r--test/CXX/expr/expr.post/expr.reinterpret.cast/p1-0x.cpp16
-rw-r--r--test/CXX/expr/expr.post/expr.static.cast/p3-0x.cpp24
-rw-r--r--test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp29
-rw-r--r--test/CXX/expr/expr.unary/expr.delete/p5.cpp22
-rw-r--r--test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp23
-rw-r--r--test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp38
-rw-r--r--test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp26
-rw-r--r--test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp172
-rw-r--r--test/CXX/expr/expr.unary/expr.unary.noexcept/ser.h8
-rw-r--r--test/CXX/expr/expr.unary/expr.unary.op/p4.cpp6
-rw-r--r--test/CXX/expr/expr.unary/expr.unary.op/p6.cpp36
-rw-r--r--test/CXX/over/over.built/p1.cpp16
-rw-r--r--test/CXX/over/over.built/p25.cpp15
-rw-r--r--test/CXX/over/over.load/p2-0x.cpp24
-rw-r--r--test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp59
-rw-r--r--test/CXX/over/over.match/over.match.funcs/p4-0x.cpp70
-rw-r--r--test/CXX/over/over.over/p2-resolve-single-template-id.cpp95
-rw-r--r--test/CXX/over/over.over/p2.cpp5
-rw-r--r--test/CXX/over/over.over/p4.cpp7
-rw-r--r--test/CXX/special/class.copy/p33-0x.cpp25
-rw-r--r--test/CXX/special/class.copy/p9.cpp24
-rw-r--r--test/CXX/special/class.ctor/p4-0x.cpp7
-rw-r--r--test/CXX/special/class.dtor/p2-0x.cpp10
-rw-r--r--test/CXX/special/class.inhctor/elsewhere.cpp31
-rw-r--r--test/CXX/special/class.inhctor/p3.cpp30
-rw-r--r--test/CXX/special/class.inhctor/p7.cpp18
-rw-r--r--test/CXX/stmt.stmt/stmt.label/p1.cpp25
-rw-r--r--test/CXX/stmt.stmt/stmt.select/p3.cpp2
-rw-r--r--test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp16
-rw-r--r--test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp40
-rw-r--r--test/CXX/temp/temp.arg/temp.arg.type/p2.cpp42
-rw-r--r--test/CXX/temp/temp.decls/temp.class.spec/p6.cpp21
-rw-r--r--test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp8
-rw-r--r--test/CXX/temp/temp.decls/temp.class.spec/p9-0x.cpp13
-rw-r--r--test/CXX/temp/temp.decls/temp.class.spec/p9.cpp26
-rw-r--r--test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp17
-rw-r--r--test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp16
-rw-r--r--test/CXX/temp/temp.decls/temp.friend/p1.cpp39
-rw-r--r--test/CXX/temp/temp.decls/temp.friend/p5.cpp106
-rw-r--r--test/CXX/temp/temp.decls/temp.friend/p8.cpp6
-rw-r--r--test/CXX/temp/temp.decls/temp.mem/p3.cpp6
-rw-r--r--test/CXX/temp/temp.decls/temp.mem/p5.cpp6
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/deduction.cpp50
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/example-bind.cpp352
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/example-function.cpp86
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp260
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp39
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/injected-class-name.cpp75
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp274
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp218
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p1.cpp9
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p2.cpp22
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p4.cpp135
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/p5.cpp393
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp34
-rw-r--r--test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp61
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp27
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp2
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp68
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp88
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp46
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp22
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp31
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp27
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp10
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp4
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp23
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp31
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp14
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp22
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp47
-rw-r--r--test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp55
-rw-r--r--test/CXX/temp/temp.param/p1.cpp12
-rw-r--r--test/CXX/temp/temp.param/p11-0x.cpp61
-rw-r--r--test/CXX/temp/temp.param/p15-cxx0x.cpp2
-rw-r--r--test/CXX/temp/temp.param/p9-0x.cpp52
-rw-r--r--test/CXX/temp/temp.param/p9.cpp4
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp239
-rw-r--r--test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp14
-rw-r--r--test/CXX/temp/temp.spec/temp.explicit/p12.cpp2
135 files changed, 5449 insertions, 131 deletions
diff --git a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
index df3429e..1e5a823 100644
--- a/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
+++ b/test/CXX/basic/basic.lookup/basic.lookup.argdep/p4.cpp
@@ -44,7 +44,7 @@ namespace Test {
// PR6716
namespace test1 {
template <class T> class A {
- template <class U> friend void foo(A &, U); // expected-note {{not viable: 1st argument ('A<int> const') would lose const qualifier}}
+ template <class U> friend void foo(A &, U); // expected-note {{not viable: 1st argument ('const A<int>') would lose const qualifier}}
};
void test() {
diff --git a/test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp b/test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp
new file mode 100644
index 0000000..911df98
--- /dev/null
+++ b/test/CXX/basic/basic.scope/basic.scope.hiding/p2.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// rdar4641403
+namespace N {
+ struct X { // expected-note{{candidate found by name lookup}}
+ float b;
+ };
+}
+
+using namespace N;
+
+typedef struct {
+ int a;
+} X; // expected-note{{candidate found by name lookup}}
+
+
+struct Y { };
+void Y(int) { }
+
+void f() {
+ X *x; // expected-error{{reference to 'X' is ambiguous}}
+ Y(1); // okay
+}
+
diff --git a/test/CXX/basic/basic.start/basic.start.main/p2h.cpp b/test/CXX/basic/basic.start/basic.start.main/p2h.cpp
new file mode 100644
index 0000000..abf8faa
--- /dev/null
+++ b/test/CXX/basic/basic.start/basic.start.main/p2h.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+int main() { } // expected-error{{'main' cannot be a template}}
+
diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp
index 277b70b..1668155 100644
--- a/test/CXX/class.access/class.friend/p1.cpp
+++ b/test/CXX/class.access/class.friend/p1.cpp
@@ -258,13 +258,12 @@ namespace test7 {
namespace test8 {
class A {
typedef int I; // expected-note 4 {{declared private here}}
- static const I x = 0;
+ static const I x = 0; // expected-note {{implicitly declared private here}}
friend I f(I i);
template<typename T> friend I g(I i);
};
- // FIXME: This should be on line 264.
- const A::I A::x; // expected-note {{declared private here}}
+ const A::I A::x;
A::I f(A::I i = A::x) {}
template<typename T> A::I g(A::I i) {
T t;
@@ -306,3 +305,39 @@ namespace test10 {
NS::bar->foo(); // expected-error {{private member}}
}
}
+
+// PR8705
+namespace test11 {
+ class A {
+ void test0(int);
+ void test1(int);
+ void test2(int);
+ void test3(int);
+ };
+
+ class B {
+ typedef int private_type; // expected-note 2 {{implicitly declared private here}}
+ friend void A::test0(int);
+ friend void A::test1(int);
+ };
+
+ void A::test0(B::private_type x) {}
+ void A::test1(int x = B::private_type()) {}
+ void A::test2(B::private_type x) {} // expected-error {{'private_type' is a private member of 'test11::B'}}
+ void A::test3(int x = B::private_type()) {} // expected-error {{'private_type' is a private member of 'test11::B'}}
+}
+
+
+// PR9221
+namespace test12 {
+ struct A {
+ void foo();
+ };
+ class B : private A {
+ friend void A::foo();
+ void *mem;
+ };
+ void A::foo() {
+ void *var = static_cast<B*>(this)->mem;
+ }
+}
diff --git a/test/CXX/class.access/class.friend/p11.cpp b/test/CXX/class.access/class.friend/p11.cpp
new file mode 100644
index 0000000..a05b2d2
--- /dev/null
+++ b/test/CXX/class.access/class.friend/p11.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// rdar://problem/8540720
+namespace test0 {
+ void foo() {
+ void bar();
+ class A {
+ friend void bar();
+ };
+ }
+}
+
+namespace test1 {
+ void foo() {
+ class A {
+ friend void bar(); // expected-error {{no matching function found in local scope}}
+ };
+ }
+}
diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp
index 115a22a..84b7b19 100644
--- a/test/CXX/class.access/p4.cpp
+++ b/test/CXX/class.access/p4.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify %s
// C++0x [class.access]p4:
@@ -201,7 +201,7 @@ namespace test4 {
// Implicit copy assignment operator uses.
namespace test5 {
class A {
- void operator=(const A &); // expected-note 2 {{declared private here}}
+ void operator=(const A &); // expected-note 2 {{implicitly declared private here}}
};
class Test1 { A a; }; // expected-error {{private member}}
@@ -450,3 +450,61 @@ namespace test18 {
A<int> member;
};
}
+
+// PR8325
+namespace test19 {
+ class A { ~A(); };
+ // The destructor is not implicitly referenced here. Contrast to test16,
+ // testing PR7281, earlier in this file.
+ void b(A* x) { throw x; }
+}
+
+// PR7930
+namespace test20 {
+ class Foo {
+ Foo(); // expected-note {{implicitly declared private here}}
+ };
+ Foo::Foo() {}
+
+ void test() {
+ Foo a; // expected-error {{calling a private constructor}}
+ }
+}
+
+namespace test21 {
+ template <class T> class A {
+ void foo();
+ void bar();
+ class Inner; // expected-note {{implicitly declared private here}}
+ public:
+ void baz();
+ };
+ template <class T> class A<T>::Inner {};
+ class B {
+ template <class T> class A<T>::Inner;
+ };
+
+ void test() {
+ A<int>::Inner i; // expected-error {{'Inner' is a private member}}
+ }
+}
+
+namespace rdar8876150 {
+ struct A { operator bool(); };
+ struct B : private A { using A::operator bool; };
+
+ bool f() {
+ B b;
+ return !b;
+ }
+}
+
+namespace test23 {
+ template <typename T> class A {
+ A();
+ static A instance;
+ };
+
+ template <typename T> A<T> A<T>::instance;
+ template class A<int>;
+}
diff --git a/test/CXX/class.access/p6.cpp b/test/CXX/class.access/p6.cpp
index 8795708..fe3304a 100644
--- a/test/CXX/class.access/p6.cpp
+++ b/test/CXX/class.access/p6.cpp
@@ -139,3 +139,32 @@ namespace test5 {
template <A::Enum en> class bar {}; // expected-error {{'Enum' is a private member of 'test5::A'}}
};
}
+
+namespace test6 {
+ class A {
+ public: class public_inner {};
+ protected: class protected_inner {};
+ private: class private_inner {}; // expected-note {{declared private here}}
+ };
+
+ class B : A {
+ public_inner a;
+ protected_inner b;
+ private_inner c; // expected-error {{ 'private_inner' is a private member of 'test6::A'}}
+ };
+}
+
+// PR9229
+namespace test7 {
+ void foo(int arg[1]);
+ class A {
+ void check();
+ };
+ class B {
+ friend class A;
+ A ins;
+ };
+ void A::check() {
+ void foo(int arg[__builtin_offsetof(B, ins)]);
+ }
+}
diff --git a/test/CXX/class.derived/class.abstract/p4.cpp b/test/CXX/class.derived/class.abstract/p4.cpp
index ca99bf7..b04de21 100644
--- a/test/CXX/class.derived/class.abstract/p4.cpp
+++ b/test/CXX/class.derived/class.abstract/p4.cpp
@@ -24,7 +24,7 @@ namespace PR6631 {
// subobject but not pure in another subobject.
namespace PartlyPure {
struct A {
- virtual void f() = 0; // expected-note{{pure virtual function}}
+ virtual void f() = 0; // expected-note{{unimplemented pure virtual method}}
};
struct B : A {
@@ -36,7 +36,7 @@ namespace PartlyPure {
struct D : B, C { };
void f() {
- (void) new D; // expected-error{{abstract type}}
+ (void) new D; // expected-error{{abstract class}}
}
}
diff --git a/test/CXX/class.derived/class.abstract/p5.cpp b/test/CXX/class.derived/class.abstract/p5.cpp
index 207519d..cdff931 100644
--- a/test/CXX/class.derived/class.abstract/p5.cpp
+++ b/test/CXX/class.derived/class.abstract/p5.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
struct A {
- virtual void f() = 0; // expected-note{{pure virtual function}}
+ virtual void f() = 0; // expected-note{{unimplemented pure virtual method}}
};
struct B : A {
@@ -9,15 +9,15 @@ struct B : A {
};
struct C : B {
- virtual void f() = 0; // expected-note 2{{pure virtual function}}
+ virtual void f() = 0; // expected-note 2{{unimplemented pure virtual method}}
};
struct D : C {
};
void test() {
- (void)new A; // expected-error{{object of abstract type}}
+ (void)new A; // expected-error{{abstract class}}
(void)new B;
- (void)new C; // expected-error{{object of abstract type}}
- (void)new D; // expected-error{{object of abstract type}}
+ (void)new C; // expected-error{{abstract class}}
+ (void)new D; // expected-error{{abstract class}}
}
diff --git a/test/CXX/class.derived/class.member.lookup/p9.cpp b/test/CXX/class.derived/class.member.lookup/p9.cpp
new file mode 100644
index 0000000..ba7bd21
--- /dev/null
+++ b/test/CXX/class.derived/class.member.lookup/p9.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace rdar8436162 {
+ class ClsA {
+ public:
+ static void f();
+ void g();
+ };
+
+ class ClsB : virtual private ClsA {
+ public:
+ using ClsA::f;
+ using ClsA::g; // expected-note{{member found by ambiguous name lookup}}
+ };
+
+ class ClsF : virtual private ClsA {
+ public:
+ using ClsA::f;
+ using ClsA::g; // expected-note{{member found by ambiguous name lookup}}
+ };
+
+ class ClsE : public ClsB, public ClsF {
+ void test() {
+ f();
+ g(); // expected-error{{member 'g' found in multiple base classes of different types}}
+ }
+ };
+}
diff --git a/test/CXX/class.derived/class.virtual/p3-0x.cpp b/test/CXX/class.derived/class.virtual/p3-0x.cpp
new file mode 100644
index 0000000..4bd9efd
--- /dev/null
+++ b/test/CXX/class.derived/class.virtual/p3-0x.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+
+namespace Test1 {
+
+struct B {
+ virtual void f(int);
+};
+
+struct D : B {
+ virtual void f(long) override; // expected-error {{'f' marked 'override' but does not override any member functions}}
+ void f(int) override;
+};
+}
+
+namespace Test2 {
+
+struct A {
+ virtual void f(int, char, int);
+};
+
+template<typename T>
+struct B : A {
+ virtual void f(T) override;
+};
+
+}
+
+namespace Test3 {
+
+struct A {
+ virtual void f(int, char, int);
+};
+
+template<typename... Args>
+struct B : A {
+ virtual void f(Args...) override; // expected-error {{'f' marked 'override' but does not override any member functions}}
+};
+
+template struct B<int, char, int>;
+template struct B<int>; // expected-note {{in instantiation of template class 'Test3::B<int>' requested here}}
+
+}
+
+namespace Test4 {
+struct B {
+ virtual void f() const final; // expected-note {{overridden virtual function is here}}
+};
+
+struct D : B {
+ void f() const; // expected-error {{declaration of 'f' overrides a 'final' function}}
+};
+
+}
diff --git a/test/CXX/class.derived/p8-0x.cpp b/test/CXX/class.derived/p8-0x.cpp
new file mode 100644
index 0000000..6a667f7
--- /dev/null
+++ b/test/CXX/class.derived/p8-0x.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify -std=c++0x
+
+namespace Test1 {
+
+struct A {
+ virtual void f(); // expected-note {{overridden virtual function is here}}
+};
+
+struct B explicit : A {
+ virtual void f(); // expected-error {{overrides function without being marked 'override'}}
+};
+
+struct C {
+ virtual ~C();
+};
+
+struct D explicit : C {
+ virtual ~D();
+};
+
+}
+
diff --git a/test/CXX/class/class.friend/p1.cpp b/test/CXX/class/class.friend/p1.cpp
index 3ad4a5f..bb1af10 100644
--- a/test/CXX/class/class.friend/p1.cpp
+++ b/test/CXX/class/class.friend/p1.cpp
@@ -57,7 +57,8 @@ class A {
friend A operator|(const A& l, const A& r); // okay
friend A operator|(const A& r); // expected-error {{ overloaded 'operator|' must be a binary operator (has 1 parameter) }}
- friend operator bool() const; // expected-error {{ must use a qualified name when declaring a conversion operator as a friend }}
+ friend operator bool() const; // expected-error {{ must use a qualified name when declaring a conversion operator as a friend }} \
+ // expected-error{{type qualifier is not allowed on this function}}
typedef void ftypedef();
friend ftypedef typedeffed_function; // okay (because it's not declared as a member)
diff --git a/test/CXX/class/class.mem/p1.cpp b/test/CXX/class/class.mem/p1.cpp
index 55507d4..a41f1db 100644
--- a/test/CXX/class/class.mem/p1.cpp
+++ b/test/CXX/class/class.mem/p1.cpp
@@ -62,3 +62,30 @@ struct S5
};
+
+namespace PR8245 {
+ class X {
+ public:
+ template<class C>
+ class Inner {
+ public:
+ void foo(bool bar = true);
+ int bam;
+ };
+
+ Inner<int> _foo;
+ };
+
+ void f() {
+ X::Inner<int> c2i;
+ X::Inner<float> c2f;
+ c2i.foo();
+ c2f.foo();
+ }
+
+ class Y {
+ class Inner {
+ void foo(int = sizeof(Y));
+ };
+ };
+}
diff --git a/test/CXX/class/class.mem/p13.cpp b/test/CXX/class/class.mem/p13.cpp
new file mode 100644
index 0000000..7cded23
--- /dev/null
+++ b/test/CXX/class/class.mem/p13.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// If T is the name of a class, then each of the following shall have
+// a name different from T:
+
+// - every static data member of class T;
+struct X0 {
+ static int X0; // expected-error{{member 'X0' has the same name as its class}}
+};
+
+// - every member function of class T
+// (Cannot be tested)
+
+// - every member of class T that is itself a type;
+struct X1 { // expected-note{{previous use is here}}
+ enum X1 { }; // expected-error{{use of 'X1' with tag type that does not match previous declaration}}
+};
+
+struct X2 {
+ typedef int X2; // expected-error{{member 'X2' has the same name as its class)}}
+};
+
+// - every enumerator of every member of class T that is an enumerated type; and
+struct X3 {
+ enum E {
+ X3 // expected-error{{member 'X3' has the same name as its class}}
+ };
+};
+
+// - every member of every anonymous union that is a member of class T.
+struct X4 {
+ union {
+ int X;
+ union {
+ float Y;
+ unsigned X4; // expected-error{{member 'X4' has the same name as its class}}
+ };
+ };
+};
+
diff --git a/test/CXX/class/class.mem/p14.cpp b/test/CXX/class/class.mem/p14.cpp
new file mode 100644
index 0000000..72b232e
--- /dev/null
+++ b/test/CXX/class/class.mem/p14.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// In addition, if class T has a user-declared constructor (12.1),
+// every non-static data member of class T shall have a name different
+// from T.
+
+struct X0 {
+ int X0; // okay
+};
+
+struct X1 {
+ int X1;
+ X1(); // expected-error{{declarator requires an identifier}}
+};
+
+struct X2 {
+ X2();
+ float X2; // expected-error{{member 'X2' has the same name as its class}}
+};
diff --git a/test/CXX/class/class.mem/p1b.cpp b/test/CXX/class/class.mem/p1b.cpp
new file mode 100644
index 0000000..d3493f6
--- /dev/null
+++ b/test/CXX/class/class.mem/p1b.cpp
@@ -0,0 +1,46 @@
+// The first run checks that the correct errors are generated,
+// implicitly checking the order of default argument parsing:
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// The second run checks the order of inline method definitions:
+// RUN: not %clang_cc1 -fsyntax-only %s 2> %t
+// RUN: FileCheck %s < %t
+
+class A {
+public:
+ void a1() {
+ B b = B();
+ }
+
+ class B;
+ void a2(B b = B()); // expected-error{{use of default argument to function 'B' that is declared later in class 'B'}}
+
+ void a3(int a = 42);
+
+ // CHEKC: error: use of undeclared identifier 'first'
+ void a4(int a = first); // expected-error{{use of undeclared identifier 'first'}}
+
+ class B {
+ public:
+ B(int b = 42) { // expected-note{{default argument declared here}}
+ A a;
+ a.a3();
+ a.a6();
+ }
+
+ void b1(A a = A()); // expected-error{{use of default argument to function 'A' that is declared later in class 'A'}}
+
+ // CHECK: error: use of undeclared identifier 'second'
+ void b2(int a = second); // expected-error{{use of undeclared identifier 'second'}}
+ };
+
+ void a5() {
+ B b = B();
+ }
+
+ void a6(B b = B());
+
+ A(int a = 42); // expected-note{{default argument declared here}}
+
+ // CHECK: error: use of undeclared identifier 'third'
+ void a7(int a = third); // expected-error{{use of undeclared identifier 'third'}}
+};
diff --git a/test/CXX/class/class.mem/p8-0x-pedantic.cpp b/test/CXX/class/class.mem/p8-0x-pedantic.cpp
new file mode 100644
index 0000000..a4b775c
--- /dev/null
+++ b/test/CXX/class/class.mem/p8-0x-pedantic.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -pedantic -verify %s
+
+namespace inline_extension {
+ struct Base1 {
+ virtual void f() {}
+ };
+
+ struct B : Base1 {
+ virtual void f() override {} // expected-warning {{'override' keyword only allowed in declarations, allowed as an extension}}
+ virtual void g() final {} // expected-warning {{'final' keyword only allowed in declarations, allowed as an extension}}
+ virtual void h() new {} // expected-warning {{'new' keyword only allowed in declarations, allowed as an extension}}
+ };
+}
+
diff --git a/test/CXX/class/class.mem/p8-0x.cpp b/test/CXX/class/class.mem/p8-0x.cpp
new file mode 100644
index 0000000..bf1b4c1
--- /dev/null
+++ b/test/CXX/class/class.mem/p8-0x.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+
+struct Base1 {
+ virtual void g();
+};
+
+struct A : Base1 {
+ virtual void f() new new; // expected-error {{class member already marked 'new'}}
+ virtual void g() override override; // expected-error {{class member already marked 'override'}}
+ virtual void h() final final; // expected-error {{class member already marked 'final'}}
+};
+
+struct Base2 {
+ virtual void e1(), e2();
+ virtual void f();
+};
+
+struct B : Base2 {
+ virtual void e1() override, e2(int); // No error.
+ virtual void f() override;
+ void g() override; // expected-error {{only virtual member functions can be marked 'override'}}
+ int h override; // expected-error {{only virtual member functions can be marked 'override'}}
+};
+
+struct C {
+ virtual void f() final;
+ void g() final; // expected-error {{only virtual member functions can be marked 'final'}}
+ int h final; // expected-error {{only virtual member functions can be marked 'final'}}
+};
+
+namespace inline_extension {
+ struct Base1 {
+ virtual void g() {}
+ };
+
+ struct A : Base1 {
+ virtual void f() new new {} // expected-error {{class member already marked 'new'}}
+ virtual void g() override override {} // expected-error {{class member already marked 'override'}}
+ virtual void h() final final {} // expected-error {{class member already marked 'final'}}
+ };
+
+ struct Base2 {
+ virtual void f();
+ };
+
+ struct B : Base2 {
+ virtual void f() override {}
+ void g() override {} // expected-error {{only virtual member functions can be marked 'override'}}
+ };
+
+ struct C {
+ virtual void f() final {}
+ void g() final {} // expected-error {{only virtual member functions can be marked 'final'}}
+ };
+}
diff --git a/test/CXX/class/class.nest/p1-cxx0x.cpp b/test/CXX/class/class.nest/p1-cxx0x.cpp
new file mode 100644
index 0000000..f8b06ac
--- /dev/null
+++ b/test/CXX/class/class.nest/p1-cxx0x.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++0x -verify %s
+
+class Outer {
+ int x;
+ static int sx;
+ int f();
+
+ // The first case is invalid in the C++03 mode but valid in C++0x (see 5.1.1.10).
+ class Inner {
+ static char a[sizeof(x)]; // okay
+ static char b[sizeof(sx)]; // okay
+ static char c[sizeof(f)]; // expected-error {{ call to non-static member function without an object argument }}
+ };
+};
diff --git a/test/CXX/class/class.nest/p1.cpp b/test/CXX/class/class.nest/p1.cpp
index f1f5496..350cc81 100644
--- a/test/CXX/class/class.nest/p1.cpp
+++ b/test/CXX/class/class.nest/p1.cpp
@@ -3,12 +3,12 @@
class Outer {
int x;
static int sx;
+ int f();
- // C++0x will likely relax this rule in this specific case, but
- // we'll still need to enforce it in C++03 mode. See N2253 (or
- // successor).
+ // C++0x does relax this rule (see 5.1.1.10) in the first case, but we need to enforce it in C++03 mode.
class Inner {
static char a[sizeof(x)]; // expected-error {{ invalid use of nonstatic data member 'x' }}
static char b[sizeof(sx)]; // okay
+ static char c[sizeof(f)]; // expected-error {{ call to non-static member function without an object argument }}
};
};
diff --git a/test/CXX/class/class.union/p1.cpp b/test/CXX/class/class.union/p1.cpp
index e974d82..b5dd4df 100644
--- a/test/CXX/class/class.union/p1.cpp
+++ b/test/CXX/class/class.union/p1.cpp
@@ -90,6 +90,14 @@ union U3 {
} m7;
};
+union U4 {
+ static int i1; // expected-error {{static data member 'i1' not allowed in union}}
+};
+
+union U5 {
+ int& i1; // expected-error {{union member 'i1' has reference type 'int &'}}
+};
+
template <class A, class B> struct Either {
bool tag;
union {
diff --git a/test/CXX/class/p1-0x.cpp b/test/CXX/class/p1-0x.cpp
new file mode 100644
index 0000000..5851de6
--- /dev/null
+++ b/test/CXX/class/p1-0x.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+namespace Test1 {
+
+class A final { };
+class B explicit { };
+class C final explicit { };
+class D final final { }; // expected-error {{class already marked 'final'}}
+class E explicit explicit { }; // expected-error {{class already marked 'explicit'}}
+
+}
diff --git a/test/CXX/class/p2-0x.cpp b/test/CXX/class/p2-0x.cpp
new file mode 100644
index 0000000..630aa7e
--- /dev/null
+++ b/test/CXX/class/p2-0x.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+namespace Test1 {
+
+class A final { }; // expected-note {{'A' declared here}}
+class B : A { }; // expected-error {{base 'A' is marked 'final'}}
+
+}
+
+namespace Test2 {
+
+template<typename T> struct A final { }; // expected-note 2 {{'A' declared here}}
+struct B : A<int> { }; // expected-error {{base 'A' is marked 'final'}}
+
+template<typename T> struct C : A<T> { }; // expected-error {{base 'A' is marked 'final'}}
+struct D : C<int> { }; // expected-note {{in instantiation of template class 'Test2::C<int>' requested here}}
+
+}
+
+namespace Test3 {
+
+template<typename T> struct A { };
+template<> struct A<int> final { }; // expected-note {{'A' declared here}}
+
+struct B : A<bool> { };
+struct C : A<int> { }; // expected-error {{base 'A' is marked 'final'}}
+
+}
+
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
index ddcbe78..069ca0a 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/namespace.memdef/p3.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only %s
+// RUN: %clang_cc1 -fsyntax-only %s -verify
// C++'0x [namespace.memdef] p3:
// Every name first declared in a namespace is a member of that namespace. If
@@ -66,3 +66,28 @@ namespace N3 {
}
// FIXME: Woefully inadequate for testing
+
+// Friends declared as template-ids aren't subject to the restriction
+// on innermost namespaces.
+// rdar://problem/8552377
+namespace test5 {
+ template <class T> void f(T);
+ namespace ns {
+ class A {
+ friend void f<int>(int);
+ static void foo(); // expected-note 2 {{declared private here}}
+ };
+
+ // Note that this happens without instantiation.
+ template <class T> void f(T) {
+ A::foo(); // expected-error {{'foo' is a private member of 'test5::ns::A'}}
+ }
+ }
+
+ template <class T> void f(T) {
+ ns::A::foo(); // expected-error {{'foo' is a private member of 'test5::ns::A'}}
+ }
+
+ template void f<int>(int);
+ template void f<long>(long); //expected-note {{instantiation}}
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.def/p2.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.def/p2.cpp
new file mode 100644
index 0000000..411c16c
--- /dev/null
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.def/p2.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR8430
+namespace N {
+ class A { };
+}
+
+namespace M { }
+
+using namespace M;
+
+namespace N {
+ namespace M {
+ }
+}
+
+namespace M {
+ namespace N {
+ }
+}
+
+namespace N {
+ A *getA();
+}
diff --git a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp
index bb1d67f..634369d 100644
--- a/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp
+++ b/test/CXX/dcl.dcl/basic.namespace/namespace.udecl/p1.cpp
@@ -89,6 +89,7 @@ namespace test2 {
namespace test3 {
class A {
+ public:
~A();
};
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
index 082a32d..24780c6 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p3.cpp
@@ -1,6 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
void f() {
auto a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}}
+ auto *b = b; // expected-error{{variable 'b' declared with 'auto' type cannot appear in its own initializer}}
+ const auto c = c; // expected-error{{variable 'c' declared with 'auto' type cannot appear in its own initializer}}
}
void g() {
@@ -8,3 +10,32 @@ void g() {
auto *b; // expected-error{{declaration of variable 'b' with type 'auto *' requires an initializer}}
}
+
+auto n(1,2,3); // expected-error{{initializer for variable 'n' with type 'auto' contains multiple expressions}}
+
+namespace N
+{
+ auto a = "const char [16]", *p = &a;
+}
+
+void h() {
+ auto b = 42ULL;
+
+ for (auto c = 0; c < 100; ++c) {
+ }
+}
+
+template<typename T, typename U> struct same;
+template<typename T> struct same<T, T> {};
+
+void p3example() {
+ auto x = 5;
+ const auto *v = &x, u = 6;
+ static auto y = 0.0;
+ auto int r; // expected-error{{cannot combine with previous}} expected-error{{requires an initializer}}
+
+ same<decltype(x), int> xHasTypeInt;
+ same<decltype(v), const int*> vHasTypeConstIntPtr;
+ same<decltype(u), const int> uHasTypeConstInt;
+ same<decltype(y), double> yHasTypeDouble;
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
new file mode 100644
index 0000000..34a1784
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p4.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+template<typename T>
+struct only {
+ only(T);
+ template<typename U> only(U) = delete;
+};
+
+void f() {
+ if (auto a = true) {
+ }
+
+ switch (auto a = 0) {
+ }
+
+ while (auto a = false) {
+ }
+
+ for (; auto a = false; ) {
+ }
+
+ new const auto (0);
+ new (auto) (0.0);
+
+#if 0
+ // When clang supports for-range:
+ for (auto i : {1,2,3}) {
+ }
+
+ // When clang supports inline initialization of members.
+ class X {
+ static const auto &n = 'x';
+ };
+#endif
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
index e739254..836ccda 100644
--- a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p5.cpp
@@ -1,13 +1,72 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
-void f() {
- auto a = a; // expected-error{{variable 'a' declared with 'auto' type cannot appear in its own initializer}}
+// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify %s -std=c++0x
+
+struct S {
+ virtual ~S();
+
+ auto a; // expected-error{{'auto' not allowed in struct member}}
+ auto *b; // expected-error{{'auto' not allowed in struct member}}
+ const auto c; // expected-error{{'auto' not allowed in struct member}}
+
+ void f() throw (auto); // expected-error{{'auto' not allowed here}}
+
+ friend auto; // expected-error{{'auto' not allowed in struct member}}
+
+ operator auto(); // expected-error{{'auto' not allowed here}}
+};
+
+void g(auto a) { // expected-error{{'auto' not allowed in function prototype}}
+ try { }
+ catch (auto &a) { } // expected-error{{'auto' not allowed in exception declaration}}
+ catch (const auto a) { } // expected-error{{'auto' not allowed in exception declaration}}
+ try { } catch (auto a) { } // expected-error{{'auto' not allowed in exception declaration}}
+}
+
+void h(auto a[10]) { // expected-error{{'auto' not allowed in function prototype}}
}
-struct S { auto a; }; // expected-error{{'auto' not allowed in struct member}}
+void i(const auto a) { // expected-error{{'auto' not allowed in function prototype}}
+}
-void f(auto a) // expected-error{{'auto' not allowed in function prototype}}
-{
- try { } catch (auto a) { } // expected-error{{'auto' not allowed in exception declaration}}
+namespace std {
+ class type_info;
+}
+
+template<typename T> struct U {};
+
+void j() {
+ (void)typeid(auto); // expected-error{{'auto' not allowed here}}
+ (void)sizeof(auto); // expected-error{{'auto' not allowed here}}
+ (void)__alignof(auto); // expected-error{{'auto' not allowed here}}
+
+ // FIXME: don't issue the second diagnostic for this error.
+ U<auto> v; // expected-error{{'auto' not allowed in template argument}} unexpected-error{{C++ requires a type specifier}}
+
+ int n;
+ (void)dynamic_cast<auto&>(S()); // expected-error{{'auto' not allowed here}}
+ (void)static_cast<auto*>(&n); // expected-error{{'auto' not allowed here}}
+ (void)reinterpret_cast<auto*>(&n); // expected-error{{'auto' not allowed here}}
+ (void)const_cast<auto>(n); // expected-error{{'auto' not allowed here}}
+ (void)*(auto*)(&n); // expected-error{{'auto' not allowed here}}
+ (void)auto(n); // expected-error{{expected expression}}
+ (void)auto{n}; // expected-error{{expected expression}}
}
template <auto a = 10> class C { }; // expected-error{{'auto' not allowed in template parameter}}
+int ints[] = {1, 2, 3};
+template <const auto (*a)[3] = &ints> class D { }; // expected-error{{'auto' not allowed in template parameter}}
+enum E : auto {}; // expected-error{{'auto' not allowed here}}
+struct F : auto {}; // expected-error{{expected class name}}
+template<typename T = auto> struct G { }; // expected-error{{'auto' not allowed here}}
+
+using A = auto; // expected-error{{expected ';'}} expected-error{{requires a qualified name}}
+
+// Whether this is illegal depends on the interpretation of [decl.spec.auto]p2 and p3,
+// and in particular the "Otherwise, ..." at the start of p3.
+namespace TrailingReturnType {
+ // FIXME: don't issue the second diagnostic for this error.
+ auto f() -> auto; // expected-error{{'auto' not allowed here}} unexpected-error{{without trailing return type}}
+ int g();
+ auto (*h)() -> auto = &g; // expected-error{{'auto' not allowed here}}
+ auto (*i)() = &g; // ok; auto deduced as int.
+ auto (*j)() -> int = i; // ok; no deduction.
+}
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
new file mode 100644
index 0000000..06aeaa6
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p6.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+template<typename T>
+struct only {
+ only(T);
+ template<typename U> only(U) = delete;
+};
+
+namespace N
+{
+ auto a = "const char [16]", *p = &a;
+
+ only<const char [16]> testA = a;
+ only<const char **> testP = p;
+}
+
+void h() {
+ auto b = 42ULL;
+ only<unsigned long long> testB = b;
+
+ for (auto c = 0; c < 100; ++c) {
+ only<int> testC = c;
+ }
+}
+
+void p3example() {
+ auto x = 5;
+ const auto *v = &x, u = 6;
+ static auto y = 0.0;
+
+ only<int> testX = x;
+ only<const int*> testV = v;
+ only<const int> testU = u;
+ only<double> testY = y;
+}
+
+void f() {
+ if (auto a = true) {
+ only<bool> testA = a;
+ }
+
+ switch (auto a = 0) {
+ case 0:
+ only<int> testA = a;
+ }
+
+ while (auto a = false) {
+ only<bool> testA = a;
+ }
+
+ for (; auto a = "test"; ) {
+ only<const char[5]> testA = a;
+ }
+
+ auto *fail1 = 0; // expected-error {{variable 'fail1' with type 'auto *' has incompatible initializer of type 'int'}}
+ int **p;
+ // FIXME: due to PR9233, we get the wrong diagnostic here.
+ const auto **fail2(p); // desired-error {{variable 'fail2' with type 'auto const **' has incompatible initializer of type 'int **'}} expected-error {{cannot initialize}}
+}
+
+struct S {
+ void f();
+ char g(int);
+ float g(double);
+ int m;
+
+ void test() {
+ auto p1 = &S::f;
+ auto S::*p2 = &S::f;
+ auto (S::*p3)() = &S::f;
+ auto p4 = &S::g; // expected-error {{incompatible initializer of type '<overloaded function type>'}}
+ auto S::*p5 = &S::g; // expected-error {{incompatible initializer of type '<overloaded function type>'}}
+ auto (S::*p6)(int) = &S::g;
+ auto p7 = &S::m;
+ auto S::*p8 = &S::m;
+
+ only<void (S::*)()> test1 = p1;
+ only<void (S::*)()> test2 = p2;
+ only<void (S::*)()> test3 = p3;
+ only<char (S::*)(int)> test6 = p6;
+ only<int (S::*)> test7 = p7;
+ only<int (S::*)> test8 = p8;
+ }
+};
+
+// TODO: if the initializer is a braced-init-list, deduce auto as std::initializer_list<T>.
diff --git a/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp
new file mode 100644
index 0000000..de87a93
--- /dev/null
+++ b/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.spec.auto/p7.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+void f() {
+ auto a = 0, b = 0, c = 0;
+ auto d = 0, e = 0.0; // expected-error {{'int' in declaration of 'd' and deduced as 'double' in declaration of 'e'}}
+
+ auto v1 = 0, *p1 = &v1;
+ auto *p2 = 0, v2 = *p2; // expected-error {{incompatible initializer}}
+
+ const int k = 0;
+ auto &f = k, &g = a; // expected-error {{'const int' in declaration of 'f' and deduced as 'int' in declaration of 'g'}}
+
+ typedef int I;
+ I x;
+ auto xa = x, xb = 0;
+
+ auto &&ra1 = a, rb1 = b; // expected-error {{'int &' in declaration of 'ra1' and deduced as 'int' in declaration of 'rb1'}}
+ auto &&ra2 = +a, rb2 = b;
+}
+
+void g() {
+ auto a = 0, (*b)() -> void, c = 0;
+ auto d = 0, (*e)() -> void, f = 0.0; // expected-error {{'auto' deduced as 'int' in declaration of 'd' and deduced as 'double' in declaration of 'f'}}
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
new file mode 100644
index 0000000..7b0fb9c
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-0x.cpp
@@ -0,0 +1,164 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify -pedantic %s
+
+// Test the C++0x-specific reference initialization rules, e.g., the
+// rules for rvalue references.
+template<typename T> T prvalue();
+template<typename T> T&& xvalue();
+template<typename T> T& lvalue();
+
+struct Base { };
+struct Derived : Base { };
+
+struct HasArray {
+ int array[5];
+};
+
+int f(int);
+
+template<typename T>
+struct ConvertsTo {
+ operator T(); // expected-note 4{{candidate function}}
+};
+
+void test_rvalue_refs() {
+ // If the initializer expression...
+ // - is an xvalue, class prvalue, array prvalue or function lvalue
+ // and "cv1 T1" is reference-compatible with "cv2 T2", or
+
+ // xvalue case
+ Base&& base0 = xvalue<Base>();
+ Base&& base1 = xvalue<Derived>();
+ int&& int0 = xvalue<int>();
+
+ // class prvalue case
+ Base&& base2 = prvalue<Base>();
+ Base&& base3 = prvalue<Derived>();
+
+ // array prvalue case
+ int (&&array0)[5] = HasArray().array;
+
+ // function lvalue case
+ int (&&function0)(int) = f;
+
+ // - has a class type (i.e., T2 is a class type), where T1 is not
+ // reference-related to T2, and can be implicitly converted to
+ // an xvalue, class prvalue, or function lvalue of type "cv3
+ // T3", where "cv1 T1" is reference-compatible with "cv3 T3",
+
+ // xvalue
+ Base&& base4 = ConvertsTo<Base&&>();
+ Base&& base5 = ConvertsTo<Derived&&>();
+ int && int1 = ConvertsTo<int&&>();
+
+ // class prvalue
+ Base&& base6 = ConvertsTo<Base>();
+ Base&& base7 = ConvertsTo<Derived>();
+
+ // function lvalue
+ int (&&function1)(int) = ConvertsTo<int(&)(int)>();
+
+ // In the second case, if the reference is an rvalue reference and
+ // the second standard conversion sequence of the user-defined
+ // conversion sequence includes an lvalue-to-rvalue conversion, the
+ // program is ill-formed.
+ int &&int2 = ConvertsTo<int&>(); // expected-error{{no viable conversion from 'ConvertsTo<int &>' to 'int'}}
+ int &&int3 = ConvertsTo<float&>(); // expected-error{{no viable conversion from 'ConvertsTo<float &>' to 'int'}}
+}
+
+class NonCopyable {
+ NonCopyable(const NonCopyable&);
+};
+
+class NonCopyableDerived : public NonCopyable {
+ NonCopyableDerived(const NonCopyableDerived&);
+};
+
+// Make sure we get direct bindings with no copies.
+void test_direct_binding() {
+ NonCopyable &&nc0 = prvalue<NonCopyable>();
+ NonCopyable &&nc1 = prvalue<NonCopyableDerived>();
+ NonCopyable &&nc2 = xvalue<NonCopyable>();
+ NonCopyable &&nc3 = xvalue<NonCopyableDerived>();
+ const NonCopyable &nc4 = prvalue<NonCopyable>();
+ const NonCopyable &nc5 = prvalue<NonCopyableDerived>();
+ const NonCopyable &nc6 = xvalue<NonCopyable>();
+ const NonCopyable &nc7 = xvalue<NonCopyableDerived>();
+ NonCopyable &&nc8 = ConvertsTo<NonCopyable&&>();
+ NonCopyable &&nc9 = ConvertsTo<NonCopyableDerived&&>();
+ const NonCopyable &nc10 = ConvertsTo<NonCopyable&&>();
+ const NonCopyable &nc11 = ConvertsTo<NonCopyableDerived&&>();
+}
+
+namespace std_example_1 {
+ double d = 2.0;
+ double& rd = d;
+ const double& rcd = d;
+ struct A { };
+ struct B : A {
+ operator int&();
+ } b;
+ A& ra = b;
+ const A& rca = b;
+ int& ir = B();
+}
+
+namespace std_example_2 {
+ double& rd2 = 2.0; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a temporary of type 'double'}}
+ int i = 2;
+ double& rd3 = i; // expected-error{{non-const lvalue reference to type 'double' cannot bind to a value of unrelated type 'int'}}
+ struct A { };
+ struct B : A { } b;
+ extern B f();
+ const A& rca = f();
+ A&& rra = f();
+ struct X {
+ operator B(); // expected-note{{candidate function}}
+ operator int&(); // expected-note{{candidate function}}
+ } x;
+ const A& r = x;
+ int&& rri = static_cast<int&&>(i);
+ B&& rrb = x;
+ int&& rri2 = X(); // expected-error{{no viable conversion from 'std_example_2::X' to 'int'}}
+
+ const double& rcd2 = 2;
+ double&& rrd = 2;
+ const volatile int cvi = 1;
+ const int& r2 = cvi; // expected-error{{binding of reference to type 'const int' to a value of type 'const volatile int' drops qualifiers}}
+
+ double d;
+ double&& rrd2 = d; // expected-error{{rvalue reference to type 'double' cannot bind to lvalue of type 'double'}}
+ double&& rrd3 = i;
+}
+
+namespace argument_passing {
+ void base_rvalue_ref(Base&&);
+ void int_rvalue_ref(int&&); // expected-note 2{{passing argument to parameter here}}
+ void array_rvalue_ref(int (&&)[5]);
+ void function_rvalue_ref(int (&&)(int));
+
+ void test() {
+ base_rvalue_ref(xvalue<Base>());
+ base_rvalue_ref(xvalue<Derived>());
+ int_rvalue_ref(xvalue<int>());
+
+ base_rvalue_ref(prvalue<Base>());
+ base_rvalue_ref(prvalue<Derived>());
+
+ array_rvalue_ref(HasArray().array);
+
+ function_rvalue_ref(f);
+
+ base_rvalue_ref(ConvertsTo<Base&&>());
+ base_rvalue_ref(ConvertsTo<Derived&&>());
+ int_rvalue_ref(ConvertsTo<int&&>());
+
+ base_rvalue_ref(ConvertsTo<Base>());
+ base_rvalue_ref(ConvertsTo<Derived>());
+
+ function_rvalue_ref(ConvertsTo<int(&)(int)>());
+
+ int_rvalue_ref(ConvertsTo<int&>()); // expected-error{{no viable conversion from 'ConvertsTo<int &>' to 'int'}}
+ int_rvalue_ref(ConvertsTo<float&>()); // expected-error{{no viable conversion from 'ConvertsTo<float &>' to 'int'}}
+ }
+
+}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
index ae59598..8c65411 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-cxx03-extra-copy.cpp
@@ -53,7 +53,7 @@ void g4(const X4<int>&);
void g5(const X5&);
void test() {
- g1(X1()); // expected-warning{{no viable constructor copying parameter of type 'X1'; C++98 requires a copy constructor when binding a reference to a temporary [-Wbind-to-temporary-copy]}}
+ g1(X1());
g2(X2()); // expected-warning{{C++98 requires an accessible copy constructor for class 'X2' when binding a reference to a temporary; was private [-Wbind-to-temporary-copy]}}
g3(X3()); // expected-warning{{no viable constructor copying parameter of type 'X3'}}
g4(X4<int>());
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
index 9b39259..08d9639 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
@@ -6,8 +6,8 @@ void example0() {
// CHECK: double &rd =
// CHECK-NEXT: DeclRefExpr
double &rd = d;
- // CHECK: double const &rcd =
- // CHECK-NEXT: ImplicitCastExpr{{.*}}'double const' <NoOp>
+ // CHECK: const double &rcd =
+ // CHECK-NEXT: ImplicitCastExpr{{.*}}'const double' lvalue <NoOp>
const double &rcd = d;
}
@@ -17,11 +17,11 @@ struct B : A { } b;
// CHECK: example1
void example1() {
// CHECK: A &ra =
- // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)> lvalue
+ // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)>
A &ra = b;
- // CHECK: A const &rca =
- // CHECK: ImplicitCastExpr{{.*}}'struct A const' <NoOp>
- // CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
+ // CHECK: const A &rca =
+ // CHECK: ImplicitCastExpr{{.*}}'const struct A' lvalue <NoOp>
+ // CHECK: ImplicitCastExpr{{.*}}'struct A' lvalue <DerivedToBase (A)>
const A& rca = b;
}
@@ -33,13 +33,13 @@ struct X {
// CHECK: example2
void example2() {
- // CHECK: A const &rca =
- // CHECK: ImplicitCastExpr{{.*}}'struct A const' <NoOp>
+ // CHECK: const A &rca =
+ // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp>
// CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
// CHECK: CallExpr{{.*}}B
const A &rca = f();
- // CHECK: A const &r =
- // CHECK: ImplicitCastExpr{{.*}}'struct A const' <NoOp>
+ // CHECK: const A &r =
+ // CHECK: ImplicitCastExpr{{.*}}'const struct A' <NoOp>
// CHECK: ImplicitCastExpr{{.*}}'struct A' <DerivedToBase (A)>
// CHECK: CXXMemberCallExpr{{.*}}'struct B'
const A& r = x;
@@ -47,7 +47,7 @@ void example2() {
// CHECK: example3
void example3() {
- // CHECK: double const &rcd2 =
- // CHECK: ImplicitCastExpr{{.*}}<IntegralToFloating>
+ // CHECK: const double &rcd2 =
+ // CHECK: ImplicitCastExpr{{.*}} <IntegralToFloating>
const double& rcd2 = 2;
}
diff --git a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
index 6a039b9..fee5f96 100644
--- a/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
+++ b/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-var.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-struct Base { }; // expected-note{{candidate is the implicit copy constructor}}
+struct Base { };
struct Derived : Base { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
struct Unrelated { };
struct Derived2 : Base { };
@@ -64,10 +64,10 @@ void bind_lvalue_quals(volatile Base b, volatile Derived d,
volatile const int ivc) {
volatile Base &bvr1 = b;
volatile Base &bvr2 = d;
- volatile Base &bvr3 = bvc; // expected-error{{binding of reference to type 'Base volatile' to a value of type 'Base const volatile' drops qualifiers}}
- volatile Base &bvr4 = dvc; // expected-error{{binding of reference to type 'Base volatile' to a value of type 'Derived const volatile' drops qualifiers}}
+ volatile Base &bvr3 = bvc; // expected-error{{binding of reference to type 'volatile Base' to a value of type 'const volatile Base' drops qualifiers}}
+ volatile Base &bvr4 = dvc; // expected-error{{binding of reference to type 'volatile Base' to a value of type 'const volatile Derived' drops qualifiers}}
- volatile int &ir = ivc; // expected-error{{binding of reference to type 'int volatile' to a value of type 'int const volatile' drops qualifiers}}
+ volatile int &ir = ivc; // expected-error{{binding of reference to type 'volatile int' to a value of type 'const volatile int' drops qualifiers}}
const volatile Base &bcvr1 = b;
const volatile Base &bcvr2 = d;
@@ -76,15 +76,15 @@ void bind_lvalue_quals(volatile Base b, volatile Derived d,
void bind_lvalue_to_rvalue() {
Base &br1 = Base(); // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a temporary of type 'Base'}}
Base &br2 = Derived(); // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a temporary of type 'Derived'}}
- const volatile Base &br3 = Base(); // expected-error{{volatile lvalue reference to type 'Base const volatile' cannot bind to a temporary of type 'Base'}}
- const volatile Base &br4 = Derived(); // expected-error{{volatile lvalue reference to type 'Base const volatile' cannot bind to a temporary of type 'Derived'}}
+ const volatile Base &br3 = Base(); // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a temporary of type 'Base'}}
+ const volatile Base &br4 = Derived(); // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a temporary of type 'Derived'}}
int &ir = 17; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a temporary of type 'int'}}
}
void bind_lvalue_to_unrelated(Unrelated ur) {
Base &br1 = ur; // expected-error{{non-const lvalue reference to type 'Base' cannot bind to a value of unrelated type 'Unrelated'}}
- const volatile Base &br2 = ur; // expected-error{{volatile lvalue reference to type 'Base const volatile' cannot bind to a value of unrelated type 'Unrelated'}}
+ const volatile Base &br2 = ur; // expected-error{{volatile lvalue reference to type 'const volatile Base' cannot bind to a value of unrelated type 'Unrelated'}}
}
void bind_lvalue_to_conv_lvalue() {
@@ -118,8 +118,8 @@ void bind_const_lvalue_to_rvalue() {
const Base &br3 = create<const Base>();
const Base &br4 = create<const Derived>();
- const Base &br5 = create<const volatile Base>(); // expected-error{{binding of reference to type 'Base const' to a value of type 'Base const volatile' drops qualifiers}}
- const Base &br6 = create<const volatile Derived>(); // expected-error{{binding of reference to type 'Base const' to a value of type 'Derived const volatile' drops qualifiers}}
+ const Base &br5 = create<const volatile Base>(); // expected-error{{binding of reference to type 'const Base' to a value of type 'const volatile Base' drops qualifiers}}
+ const Base &br6 = create<const volatile Derived>(); // expected-error{{binding of reference to type 'const Base' to a value of type 'const volatile Derived' drops qualifiers}}
const int &ir = create<int>();
}
@@ -131,5 +131,5 @@ void bind_const_lvalue_to_class_conv_temporary() {
}
void bind_lvalue_to_conv_rvalue_ambig(ConvertibleToBothDerived both) {
const Derived &dr1 = both;
- const Base &br1 = both; // expected-error{{reference initialization of type 'Base const &' with initializer of type 'ConvertibleToBothDerived' is ambiguous}}
+ const Base &br1 = both; // expected-error{{reference initialization of type 'const Base &' with initializer of type 'ConvertibleToBothDerived' is ambiguous}}
}
diff --git a/test/CXX/dcl.decl/dcl.init/p6.cpp b/test/CXX/dcl.decl/dcl.init/p6.cpp
index c542dac..da6f5b5 100644
--- a/test/CXX/dcl.decl/dcl.init/p6.cpp
+++ b/test/CXX/dcl.decl/dcl.init/p6.cpp
@@ -10,7 +10,7 @@ struct NoUserDefault : public MakeNonPOD { };
struct HasUserDefault { HasUserDefault(); };
void test_const_default_init() {
- const NoUserDefault x1; // expected-error{{default initialization of an object of const type 'NoUserDefault const' requires a user-provided default constructor}}
+ const NoUserDefault x1; // expected-error{{default initialization of an object of const type 'const NoUserDefault' requires a user-provided default constructor}}
const HasUserDefault x2;
- const int x3; // expected-error{{default initialization of an object of const type 'int const'}}
+ const int x3; // expected-error{{default initialization of an object of const type 'const int'}}
}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp
index 00e59e0..b0575b8 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1-cxx0x.cpp
@@ -3,4 +3,5 @@
void f() {
int b[5];
auto a[5] = b; // expected-error{{'a' declared as array of 'auto'}}
+ auto *c[5] = b; // expected-error{{'c' declared as array of 'auto *'}}
}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp
index ac0ec85..bb4a48e 100644
--- a/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.array/p1.cpp
@@ -5,7 +5,7 @@ int ar1[10];
// Element type cannot be:
// - (cv) void
-volatile void ar2[10]; // expected-error {{incomplete element type 'void volatile'}}
+volatile void ar2[10]; // expected-error {{incomplete element type 'volatile void'}}
// - a reference
int& ar3[10]; // expected-error {{array of references}}
// - a function type
@@ -16,7 +16,7 @@ struct Abstract { virtual void fn() = 0; }; // expected-note {{pure virtual}}
Abstract ar5[10]; // expected-error {{abstract class}}
// If we have a size, it must be greater than zero.
-int ar6[-1]; // expected-error {{array size is negative}}
+int ar6[-1]; // expected-error {{array with a negative size}}
int ar7[0u]; // expected-warning {{zero size arrays are an extension}}
// An array with unknown bound is incomplete.
@@ -42,3 +42,13 @@ template <typename T> struct S {
typename T::type x; // expected-error {{has no members}}
};
S<int> ar10[10]; // expected-note {{requested here}}
+
+// Ensure that negative array size errors include the name of the declared
+// array as this is often used to simulate static_assert with template
+// instantiations, placing the 'error message' in the declarator name.
+int
+user_error_message
+[-1]; // expected-error {{user_error_message}}
+typedef int
+another_user_error_message
+[-1]; // expected-error {{another_user_error_message}}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp
new file mode 100644
index 0000000..5fb35ba
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p13.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -fexceptions -verify %s
+
+// When it is part of a parameter-declaration-clause, the parameter
+// pack is a function parameter pack.
+template<typename ...Types>
+void f0(Types ...args);
+
+template<typename ...Types>
+void f1(const Types &...args);
+
+// [ Note: Otherwise, the parameter-declaration is part of a
+// template-parameter-list and the parameter pack is a template
+// parameter pack; see 14.1. -- end note ]
+template<int ...N>
+struct X0 { };
+
+template<typename ...Types>
+struct X1 {
+ template<Types ...Values> struct Inner;
+};
+
+// A declarator-id or abstract-declarator containing an ellipsis shall
+// only be used in a parameter-declaration.
+int (...f2)(int); // expected-error{{only function and template parameters can be parameter packs}}
+
+void f3() {
+ int ...x; // expected-error{{only function and template parameters can be parameter packs}}
+ if (int ...y = 17) { } // expected-error{{only function and template parameters can be parameter packs}}
+
+ for (int ...z = 0; z < 10; ++z) { } // expected-error{{only function and template parameters can be parameter packs}}
+
+ try {
+ } catch (int ...e) { // expected-error{{only function and template parameters can be parameter packs}}
+ }
+}
+
+template<typename ...Types>
+struct X2 {
+ Types ...members; // expected-error{{only function and template parameters can be parameter packs}} \
+ // expected-error{{data member type contains unexpanded parameter pack}}
+};
+
+// The type T of the declarator-id of the function parameter pack
+// shall contain a template parameter pack; each template parameter
+// pack in T is expanded by the function parameter pack.
+template<typename T>
+void f4(T ...args); // expected-error{{type 'T' of function parameter pack does not contain any unexpanded parameter packs}}
+
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p14.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p14.cpp
new file mode 100644
index 0000000..1293a06
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p14.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<typename T> struct identity;
+template<typename ...Types> struct tuple;
+
+template<typename T, typename U> struct is_same {
+ static const bool value = false;
+};
+
+template<typename T> struct is_same<T, T> {
+ static const bool value = true;
+};
+
+// There is a syntactic ambiguity when an ellipsis occurs at the end
+// of a parameter-declaration-clause without a preceding comma. In
+// this case, the ellipsis is parsed as part of the
+// abstract-declarator if the type of the parameter names a template
+// parameter pack that has not been expanded; otherwise, it is parsed
+// as part of the parameter-declaration-clause.
+
+template<typename T, typename ...Types>
+struct X0 {
+ typedef identity<T(Types...)> function_pack_1;
+ typedef identity<T(Types......)> variadic_function_pack_1;
+ typedef identity<T(T...)> variadic_1;
+ typedef tuple<T(Types, ...)...> template_arg_expansion_1;
+};
+
+
+
+// FIXME: Once function parameter packs are implemented, we can test all of the disambiguation
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p2-cxx0x.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p2-cxx0x.cpp
new file mode 100644
index 0000000..4dc393d
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p2-cxx0x.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+auto a() -> int; // ok
+const auto b() -> int; // expected-error {{function with trailing return type must specify return type 'auto', not 'auto const'}}
+auto *c() -> int; // expected-error {{function with trailing return type must specify return type 'auto', not 'auto *'}}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp
new file mode 100644
index 0000000..c81c844
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6-0x.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+void f0() &; // expected-error{{ref-qualifier '&' is only allowed on non-static member functions, member function pointers, and typedefs of function types}}
+void f1() &&; // expected-error{{ref-qualifier '&&' is only allowed on non-static member functions, member function pointers, and typedefs of function types}}
+
+struct X {
+ void f0() &;
+ void f1() &&;
+ static void f2() &; // expected-error{{ref-qualifier '&' is only allowed on non-static member functions, member function pointers, and typedefs of function types}}
+ static void f3() &&; // expected-error{{ref-qualifier '&&' is only allowed on non-static member functions, member function pointers, and typedefs of function types}}
+};
+
+typedef void func_type_lvalue() &;
+typedef void func_type_rvalue() &&;
+
+func_type_lvalue f2; // expected-error{{nonmember function cannot have a ref-qualifier '&'}}
+func_type_rvalue f3; // expected-error{{nonmember function cannot have a ref-qualifier '&&'}}
+
+struct Y {
+ func_type_lvalue f0;
+ func_type_rvalue f1;
+};
+
+void (X::*mpf1)() & = &X::f0;
+void (X::*mpf2)() && = &X::f1;
+
+
+void (f() &&); // expected-error{{ref-qualifier '&&' is only allowed on non-static member functions, member function pointers, and typedefs of function types}}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp
new file mode 100644
index 0000000..4873c09
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p6.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f() const; // expected-error{{type qualifier is not allowed on this function}}
+
+struct X {
+ void f() const;
+ friend void g() const; // expected-error{{type qualifier is not allowed on this function}}
+ static void h() const; // expected-error{{type qualifier is not allowed on this function}}
+};
+
+struct Y {
+ friend void X::f() const;
+ friend void ::f() const; // expected-error{{type qualifier is not allowed on this function}}
+};
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp
new file mode 100644
index 0000000..34a8c85
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.fct/p8.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A { };
+A::A (enum { e1 }) {} // expected-error{{can not be defined in a parameter}} \
+// expected-error{{out-of-line definition}}
+void A::f(enum { e2 }) {} // expected-error{{can not be defined in a parameter}} \
+// expected-error{{out-of-line definition}}
+
+enum { e3 } A::g() { } // expected-error{{can not be defined in the result type}} \
+// expected-error{{out-of-line definition}}
diff --git a/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp b/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp
new file mode 100644
index 0000000..789cde7
--- /dev/null
+++ b/test/CXX/dcl.decl/dcl.meaning/dcl.ref/p6-0x.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+#define JOIN2(X,Y) X##Y
+#define JOIN(X,Y) JOIN2(X,Y)
+#define CHECK_EQUAL_TYPES(T1, T2) \
+ int JOIN(array,__LINE__)[is_same<T1, T2>::value? 1 : -1]
+
+int i;
+typedef int& LRI;
+typedef int&& RRI;
+
+typedef LRI& r1; CHECK_EQUAL_TYPES(r1, int&);
+typedef const LRI& r2; CHECK_EQUAL_TYPES(r2, int&);
+typedef const LRI&& r3; CHECK_EQUAL_TYPES(r3, int&);
+
+typedef RRI& r4; CHECK_EQUAL_TYPES(r4, int&);
+typedef RRI&& r5; CHECK_EQUAL_TYPES(r5, int&&);
diff --git a/test/CXX/dcl.decl/p4-0x.cpp b/test/CXX/dcl.decl/p4-0x.cpp
new file mode 100644
index 0000000..9fa2ea1
--- /dev/null
+++ b/test/CXX/dcl.decl/p4-0x.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+struct X {
+ void f() &;
+ void g() &&;
+};
+
+void (X::*pmf)() & = &X::f;
diff --git a/test/CXX/except/except.handle/p16.cpp b/test/CXX/except/except.handle/p16.cpp
index 4950a2f..24f0db0 100644
--- a/test/CXX/except/except.handle/p16.cpp
+++ b/test/CXX/except/except.handle/p16.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify %s
// The object declared in an exception-declaration or, if the
// exception-declaration does not specify a name, a temporary (12.2)
diff --git a/test/CXX/except/except.spec/p14-ir.cpp b/test/CXX/except/except.spec/p14-ir.cpp
index 4d8d1f7..c681727 100644
--- a/test/CXX/except/except.spec/p14-ir.cpp
+++ b/test/CXX/except/except.spec/p14-ir.cpp
@@ -26,17 +26,17 @@ struct X4 {
struct X5 : X0, X4 { };
void test(X2 x2, X3 x3, X5 x5) {
- // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_
+ // CHECK: define linkonce_odr void @_ZN2X2C1ERKS_(%struct.X0* %this, %struct.X0*) unnamed_addr
// CHECK: call void @_ZN2X2C2ERKS_({{.*}}) nounwind
// CHECK-NEXT: ret void
// CHECK-NEXT: }
X2 x2a(x2);
- // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_
+ // CHECK: define linkonce_odr void @_ZN2X3C1ERKS_(%struct.X0* %this, %struct.X0*) unnamed_addr
// CHECK: call void @_ZN2X3C2ERKS_({{.*}}) nounwind
// CHECK-NEXT: ret void
// CHECK-NEXT: }
X3 x3a(x3);
- // CHECK: define linkonce_odr void @_ZN2X5C1ERS_
+ // CHECK: define linkonce_odr void @_ZN2X5C1ERS_({{.*}}) unnamed_addr
// CHECK-NOT: call void @__cxa_call_unexpected
// CHECK: ret void
X5 x5a(x5);
@@ -55,24 +55,24 @@ struct X8 : X6 { };
struct X9 : X6, X7 { };
void test() {
- // CHECK: define linkonce_odr void @_ZN2X8C1Ev
+ // CHECK: define linkonce_odr void @_ZN2X8C1Ev(%struct.X0* %this) unnamed_addr
// CHECK: call void @_ZN2X8C2Ev({{.*}}) nounwind
// CHECK-NEXT: ret void
X8();
- // CHECK: define linkonce_odr void @_ZN2X9C1Ev
+ // CHECK: define linkonce_odr void @_ZN2X9C1Ev(%struct.X0* %this) unnamed_addr
// FIXME: check that this is the end of the line here:
// CHECK: call void @_ZN2X9C2Ev({{.*}})
// CHECK-NEXT: ret void
X9();
- // CHECK: define linkonce_odr void @_ZN2X9C2Ev
+ // CHECK: define linkonce_odr void @_ZN2X9C2Ev(%struct.X0* %this) unnamed_addr
// CHECK: call void @_ZN2X6C2Ev({{.*}}) nounwind
// FIXME: and here:
// CHECK-NEXT: call void @_ZN2X7C2Ev({{.*}})
// CHECK: ret void
- // CHECK: define linkonce_odr void @_ZN2X8C2Ev
+ // CHECK: define linkonce_odr void @_ZN2X8C2Ev(%struct.X0* %this) unnamed_addr
// CHECK: call void @_ZN2X6C2Ev({{.*}}) nounwind
// CHECK-NEXT: ret void
}
diff --git a/test/CXX/expr/expr.cast/p4-0x.cpp b/test/CXX/expr/expr.cast/p4-0x.cpp
new file mode 100644
index 0000000..5824cd2
--- /dev/null
+++ b/test/CXX/expr/expr.cast/p4-0x.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+struct X { };
+struct Y : X { };
+
+void test_lvalue_to_rvalue_drop_cvquals(const X &x, const Y &y, const int &i) {
+ (void)(X&&)x;
+ (void)(int&&)i;
+ (void)(X&&)y;
+ (void)(Y&&)x;
+}
diff --git a/test/CXX/expr/expr.cast/p4.cpp b/test/CXX/expr/expr.cast/p4.cpp
new file mode 100644
index 0000000..907e008
--- /dev/null
+++ b/test/CXX/expr/expr.cast/p4.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -ast-dump %s | FileCheck %s
+
+struct A { int x; };
+struct B { int y; };
+struct C : A, B { };
+
+// CHECK: casting_away_constness
+void casting_away_constness(const B &b, const C &c, const B *bp, const C *cp) {
+ // CHECK: DerivedToBase (B)
+ // CHECK: DeclRefExpr {{.*}} ParmVar {{.*}} 'c'
+ (void)(B&)c;
+ // CHECK: BaseToDerived (B)
+ // CHECK: DeclRefExpr {{.*}} ParmVar {{.*}} 'b'
+ (void)(C&)b;
+ // CHECK: DerivedToBase (B)
+ // CHECK: DeclRefExpr {{.*}} ParmVar {{.*}} 'cp'
+ (void)(B*)cp;
+ // CHECK: BaseToDerived (B)
+ // CHECK: DeclRefExpr {{.*}} ParmVar {{.*}} 'bp'
+ (void)(C*)bp;
+ // CHECK: ReturnStmt
+ return;
+}
diff --git a/test/CXX/expr/expr.mptr.oper/p5.cpp b/test/CXX/expr/expr.mptr.oper/p5.cpp
new file mode 100644
index 0000000..7380b5d
--- /dev/null
+++ b/test/CXX/expr/expr.mptr.oper/p5.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct X0 {
+ void f0();
+ void f1() const;
+ void f2() volatile;
+ void f3() const volatile;
+};
+
+void test_object_cvquals(void (X0::*pm)(),
+ void (X0::*pmc)() const,
+ void (X0::*pmv)() volatile,
+ void (X0::*pmcv)() const volatile,
+ X0 *p,
+ const X0 *pc,
+ volatile X0 *pv,
+ const volatile X0 *pcv,
+ X0 &o,
+ const X0 &oc,
+ volatile X0 &ov,
+ const volatile X0 &ocv) {
+ (p->*pm)();
+ (p->*pmc)();
+ (p->*pmv)();
+ (p->*pmcv)();
+
+ (pc->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const' qualifier}}
+ (pc->*pmc)();
+ (pc->*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}}
+ (pc->*pmcv)();
+
+ (pv->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'volatile' qualifier}}
+ (pv->*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}}
+ (pv->*pmv)();
+ (pv->*pmcv)();
+
+ (pcv->*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const volatile' qualifiers}}
+ (pcv->*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}}
+ (pcv->*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}}
+ (pcv->*pmcv)();
+
+ (o.*pm)();
+ (o.*pmc)();
+ (o.*pmv)();
+ (o.*pmcv)();
+
+ (oc.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const' qualifier}}
+ (oc.*pmc)();
+ (oc.*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}}
+ (oc.*pmcv)();
+
+ (ov.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'volatile' qualifier}}
+ (ov.*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}}
+ (ov.*pmv)();
+ (ov.*pmcv)();
+
+ (ocv.*pm)(); // expected-error{{call to pointer to member function of type 'void ()' drops 'const volatile' qualifiers}}
+ (ocv.*pmc)(); // expected-error{{call to pointer to member function of type 'void () const' drops 'volatile' qualifier}}
+ (ocv.*pmv)(); // expected-error{{call to pointer to member function of type 'void () volatile' drops 'const' qualifier}}
+ (ocv.*pmcv)();
+}
diff --git a/test/CXX/expr/expr.mptr.oper/p6-0x.cpp b/test/CXX/expr/expr.mptr.oper/p6-0x.cpp
new file mode 100644
index 0000000..d5dc7d2
--- /dev/null
+++ b/test/CXX/expr/expr.mptr.oper/p6-0x.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+struct X { };
+
+template<typename T> T& lvalue();
+template<typename T> T&& xvalue();
+template<typename T> T prvalue();
+
+// In a .* expression whose object expression is an rvalue, the
+// program is ill-formed if the second operand is a pointer to member
+// function with ref-qualifier &. In a ->* expression or in a .*
+// expression whose object expression is an lvalue, the program is
+// ill-formed if the second operand is a pointer to member function
+// with ref-qualifier &&.
+void test(X *xp, int (X::*pmf)(int), int (X::*l_pmf)(int) &,
+ int (X::*r_pmf)(int) &&) {
+ // No ref-qualifier.
+ (lvalue<X>().*pmf)(17);
+ (xvalue<X>().*pmf)(17);
+ (prvalue<X>().*pmf)(17);
+ (xp->*pmf)(17);
+
+ // Lvalue ref-qualifier.
+ (lvalue<X>().*l_pmf)(17);
+ (xvalue<X>().*l_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &' can only be called on an lvalue}}
+ (prvalue<X>().*l_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &' can only be called on an lvalue}}
+ (xp->*l_pmf)(17);
+
+ // Rvalue ref-qualifier.
+ (lvalue<X>().*r_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &&' can only be called on an rvalue}}
+ (xvalue<X>().*r_pmf)(17);
+ (prvalue<X>().*r_pmf)(17);
+ (xp->*r_pmf)(17); // expected-error{{pointer-to-member function type 'int (X::*)(int) &&' can only be called on an rvalue}}
+}
diff --git a/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp b/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp
new file mode 100644
index 0000000..d464881
--- /dev/null
+++ b/test/CXX/expr/expr.post/expr.const.cast/p1-0x.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// The result of the expression const_cast<T>(v) is of type T. If T is
+// an lvalue reference to object type, the result is an lvalue; if T
+// is an rvalue reference to object type, the result is an xvalue;.
+
+unsigned int f(int);
+
+template<typename T> T& lvalue();
+template<typename T> T&& xvalue();
+template<typename T> T prvalue();
+
+void test_classification(const int *ptr) {
+ int *ptr0 = const_cast<int *&&>(ptr);
+ int *ptr1 = const_cast<int *&&>(xvalue<const int*>());
+ int *ptr2 = const_cast<int *&&>(prvalue<const int*>());
+}
diff --git a/test/CXX/expr/expr.post/expr.dynamic.cast/p3-0x.cpp b/test/CXX/expr/expr.post/expr.dynamic.cast/p3-0x.cpp
new file mode 100644
index 0000000..3b448a8
--- /dev/null
+++ b/test/CXX/expr/expr.post/expr.dynamic.cast/p3-0x.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+struct X { virtual ~X(); };
+struct Y : public X { };
+struct Z; // expected-note{{forward declaration of 'Z'}}
+
+void test(X &x, Y &y, Z &z) {
+ // If T is an rvalue reference type, v shall be an expression having
+ // a complete class type, and the result is an xvalue of the type
+ // referred to by T.
+ Y &&yr0 = dynamic_cast<Y&&>(x);
+ Y &&yr1 = dynamic_cast<Y&&>(static_cast<X&&>(x));
+ Y &&yr2 = dynamic_cast<Y&&>(z); // expected-error{{'Z' is an incomplete type}}
+}
diff --git a/test/CXX/expr/expr.post/expr.reinterpret.cast/p1-0x.cpp b/test/CXX/expr/expr.post/expr.reinterpret.cast/p1-0x.cpp
new file mode 100644
index 0000000..e80082a
--- /dev/null
+++ b/test/CXX/expr/expr.post/expr.reinterpret.cast/p1-0x.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// If T is an lvalue reference type or an rvalue reference to function
+// type, the result is an lvalue; if T is an rvalue reference to
+// object type, the result is an xvalue;
+
+unsigned int f(int);
+
+template<typename T> T&& xvalue();
+void test_classification(char *ptr) {
+ int (&fr0)(int) = reinterpret_cast<int (&&)(int)>(f);
+ int &&ir0 = reinterpret_cast<int &&>(*ptr);
+ int &&ir1 = reinterpret_cast<int &&>(0);
+ int &&ir2 = reinterpret_cast<int &&>('a');
+ int &&ir3 = reinterpret_cast<int &&>(xvalue<char>());
+}
diff --git a/test/CXX/expr/expr.post/expr.static.cast/p3-0x.cpp b/test/CXX/expr/expr.post/expr.static.cast/p3-0x.cpp
new file mode 100644
index 0000000..c103351
--- /dev/null
+++ b/test/CXX/expr/expr.post/expr.static.cast/p3-0x.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// A glvalue of type "cv1 T1" can be cast to type "rvalue reference to
+// cv2 T2" if "cv2 T2" is reference-compatible with "cv1 T1" (8.5.3).
+struct A { };
+struct B : A { };
+
+template<typename T> T& lvalue();
+template<typename T> T&& xvalue();
+
+void test(A &a, B &b) {
+ A &&ar0 = static_cast<A&&>(a);
+ A &&ar1 = static_cast<A&&>(b);
+ A &&ar2 = static_cast<A&&>(lvalue<A>());
+ A &&ar3 = static_cast<A&&>(lvalue<B>());
+ A &&ar4 = static_cast<A&&>(xvalue<A>());
+ A &&ar5 = static_cast<A&&>(xvalue<B>());
+ const A &&ar6 = static_cast<const A&&>(a);
+ const A &&ar7 = static_cast<const A&&>(b);
+ const A &&ar8 = static_cast<const A&&>(lvalue<A>());
+ const A &&ar9 = static_cast<const A&&>(lvalue<B>());
+ const A &&ar10 = static_cast<const A&&>(xvalue<A>());
+ const A &&ar11 = static_cast<const A&&>(xvalue<B>());
+}
diff --git a/test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp b/test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp
new file mode 100644
index 0000000..4acafb8
--- /dev/null
+++ b/test/CXX/expr/expr.post/expr.static.cast/p9-0x.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+enum class EC { ec1 };
+
+void test0(EC ec) {
+ (void)static_cast<bool>(ec);
+ (void)static_cast<bool>(EC::ec1);
+ (void)static_cast<char>(ec);
+ (void)static_cast<char>(EC::ec1);
+ (void)static_cast<int>(ec);
+ (void)static_cast<int>(EC::ec1);
+ (void)static_cast<unsigned long>(ec);
+ (void)static_cast<unsigned long>(EC::ec1);
+ (void)static_cast<float>(ec);
+ (void)static_cast<float>(EC::ec1);
+ (void)static_cast<double>(ec);
+ (void)static_cast<double>(EC::ec1);
+}
+
+namespace PR9107 {
+ enum E {};
+ template <class _Tp> inline _Tp* addressof(_Tp& __x) {
+ return (_Tp*)&(char&)__x;
+ }
+ void test() {
+ E a;
+ addressof(a);
+ }
+}
diff --git a/test/CXX/expr/expr.unary/expr.delete/p5.cpp b/test/CXX/expr/expr.unary/expr.delete/p5.cpp
index 2fa30e5..ecb2918 100644
--- a/test/CXX/expr/expr.unary/expr.delete/p5.cpp
+++ b/test/CXX/expr/expr.unary/expr.delete/p5.cpp
@@ -24,11 +24,23 @@ void f0(T2_A *a) { T2_C x; x.f0(a); }
class T2_A { };
// An alternate version of the same.
-//
-// FIXME: Revisit this case when we have access control.
class T3_A;
template<typename T>
-struct T3_B { void f0(T *a) { delete a; } };
-struct T3_C { T3_B<T3_A> x; void f0(T3_A *a) { x.f0(a); } };
+struct T3_B {
+ void f0(T *a) {
+ delete a; // expected-error{{calling a private destructor of class 'T3_A'}}
+ }
+};
+
+struct T3_C {
+ T3_B<T3_A> x;
+ void f0(T3_A *a) {
+ x.f0(a); // expected-note{{in instantiation of member function 'T3_B<T3_A>::f0' requested here}}
+ }
+};
+
void f0(T3_A *a) { T3_C x; x.f0(a); }
-class T3_A { private: ~T3_A(); };
+class T3_A {
+private:
+ ~T3_A(); // expected-note{{declared private here}}
+};
diff --git a/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp b/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
new file mode 100644
index 0000000..c9a8887
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.new/p2-cxx0x.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++0x
+
+template<typename T>
+struct only {
+ only(T);
+ template<typename U> only(U) = delete;
+};
+
+void f() {
+ only<const int*> p = new const auto (0);
+ only<double*> q = new (auto) (0.0);
+
+ new auto; // expected-error{{new expression for type 'auto' requires a constructor argument}}
+ new (const auto)(); // expected-error{{new expression for type 'auto const' requires a constructor argument}}
+ new (auto) (1,2,3); // expected-error{{new expression for type 'auto' contains multiple constructor arguments}}
+}
+
+void p2example() {
+ only<int*> r = new auto(1);
+ auto x = new auto('a');
+
+ only<char*> testX = x;
+}
diff --git a/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp b/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp
new file mode 100644
index 0000000..3824615
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.sizeof/p5-0x.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Test parsing + semantic analysis
+template<typename ...Types> struct count_types {
+ static const unsigned value = sizeof...(Types);
+};
+
+template<int ...Values> struct count_ints {
+ static const unsigned value = sizeof...(Values);
+};
+
+// Test instantiation
+int check_types[count_types<short, int, long>::value == 3? 1 : -1];
+int check_ints[count_ints<1, 2, 3, 4, 5>::value == 5? 1 : -1];
+
+// Test instantiation involving function parameter packs.
+struct any {
+ template<typename T> any(T);
+};
+
+template<typename ...Inits>
+void init_me(Inits ...inits) {
+ any array[sizeof...(inits)] = { inits... };
+}
+
+template void init_me<int, float, double*>(int, float, double*);
+
+// Test parser and semantic recovery.
+template<int Value> struct count_ints_2 {
+ static const unsigned value = sizeof...(Value); // expected-error{{'Value' does not refer to the name of a parameter pack}}
+};
+
+template<typename ...Types> // expected-note{{parameter pack 'Types' declared here}}
+struct count_types_2 {
+ static const unsigned value = sizeof... Type; // expected-error{{missing parentheses around the size of parameter pack 'Type'}} \
+ // expected-error{{Type' does not refer to the name of a parameter pack; did you mean 'Types'?}}
+};
+
diff --git a/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp b/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp
new file mode 100644
index 0000000..6aec3a2
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.unary.noexcept/cg.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fexceptions -triple x86_64-apple-darwin10 -S -emit-llvm -std=c++0x -include %S/ser.h %s -o - | FileCheck %s
+// RUN: %clang_cc1 -fexceptions -triple x86_64-apple-darwin10 -emit-pch -o %t-ser.pch -std=c++0x -x c++ %S/ser.h
+// RUN: %clang_cc1 -fexceptions -triple x86_64-apple-darwin10 -S -emit-llvm -std=c++0x -include-pch %t-ser.pch %s -o - | FileCheck %s
+
+struct D {
+ ~D() throw();
+};
+struct E {
+ ~E() throw();
+};
+
+void test() {
+ bool b;
+ // CHECK: store i8 1
+ b = noexcept(0);
+ // CHECK: store i8 0
+ b = noexcept(throw 0);
+ b = f1();
+ b = f2();
+
+ // CHECK-NOT: call void @_ZN1ED1Ev
+ // CHECK: call void @_ZN1DD1Ev
+ D(), noexcept(E());
+}
+// CHECK: ret i1 true
+// CHECK: ret i1 false
diff --git a/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp b/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
new file mode 100644
index 0000000..98c6f4e
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.unary.noexcept/sema.cpp
@@ -0,0 +1,172 @@
+// RUN: %clang_cc1 -fexceptions -fsyntax-only -verify -std=c++0x -fms-extensions %s
+
+#define P(e) static_assert(noexcept(e), "expected nothrow")
+#define N(e) static_assert(!noexcept(e), "expected throw")
+#define B(b, e) static_assert(b == noexcept(e), "expectation failed")
+
+void simple() {
+ P(0);
+ P(0 + 0);
+ int i;
+ P(i);
+ P(sizeof(0));
+ P(static_cast<int>(0));
+ N(throw 0);
+ N((throw 0, 0));
+}
+
+void nospec();
+void allspec() throw(...);
+void intspec() throw(int);
+void emptyspec() throw();
+void nothrowattr() __attribute__((nothrow));
+
+void call() {
+ N(nospec());
+ N(allspec());
+ N(intspec());
+ P(emptyspec());
+ P(nothrowattr());
+}
+
+void (*pnospec)();
+void (*pallspec)() throw(...);
+void (*pintspec)() throw(int);
+void (*pemptyspec)() throw();
+
+void callptr() {
+ N(pnospec());
+ N((*pnospec)());
+ N(pallspec());
+ N((*pallspec)());
+ N(pintspec());
+ N((*pintspec)());
+ P(pemptyspec());
+ P((*pemptyspec)());
+}
+
+struct S1 {
+ void nospec();
+ void allspec() throw(...);
+ void intspec() throw(int);
+ void emptyspec() throw();
+};
+
+void callmem() {
+ S1 s;
+ N(s.nospec());
+ N(s.allspec());
+ N(s.intspec());
+ P(s.emptyspec());
+}
+
+void (S1::*mpnospec)();
+void (S1::*mpallspec)() throw(...);
+void (S1::*mpintspec)() throw(int);
+void (S1::*mpemptyspec)() throw();
+
+void callmemptr() {
+ S1 s;
+ N((s.*mpnospec)());
+ N((s.*mpallspec)());
+ N((s.*mpintspec)());
+ P((s.*mpemptyspec)());
+}
+
+struct S2 {
+ S2();
+ S2(int, int) throw();
+ void operator +();
+ void operator -() throw();
+ void operator +(int);
+ void operator -(int) throw();
+ operator int();
+ operator float() throw();
+};
+
+void *operator new(__typeof__(sizeof(int)) sz, int) throw();
+
+struct Bad1 {
+ ~Bad1() throw(int);
+};
+struct Bad2 {
+ void operator delete(void*) throw(int);
+};
+
+void implicits() {
+ N(new int);
+ P(new (0) int);
+ P(delete (int*)0);
+ N(delete (Bad1*)0);
+ N(delete (Bad2*)0);
+ N(S2());
+ P(S2(0, 0));
+ S2 s;
+ N(+s);
+ P(-s);
+ N(s + 0);
+ P(s - 0);
+ N(static_cast<int>(s));
+ P(static_cast<float>(s));
+ N(Bad1());
+}
+
+struct V {
+ virtual ~V() throw();
+};
+struct D : V {};
+
+void dyncast() {
+ V *pv = 0;
+ D *pd = 0;
+ P(dynamic_cast<V&>(*pd));
+ P(dynamic_cast<V*>(pd));
+ N(dynamic_cast<D&>(*pv));
+ P(dynamic_cast<D*>(pv));
+}
+
+namespace std {
+ struct type_info {};
+}
+
+void idtype() {
+ P(typeid(V));
+ P(typeid((V*)0));
+ P(typeid(*(S1*)0));
+ N(typeid(*(V*)0));
+}
+
+void uneval() {
+ P(sizeof(typeid(*(V*)0)));
+ P(typeid(typeid(*(V*)0)));
+}
+
+struct G1 {};
+struct G2 { int i; };
+struct G3 { S2 s; };
+
+void gencon() {
+ P(G1());
+ P(G2());
+ N(G3());
+}
+
+template <typename T, bool b>
+void late() {
+ B(b, typeid(*(T*)0));
+ B(b, T(1));
+ B(b, static_cast<T>(S2(0, 0)));
+ B(b, S1() + T());
+}
+struct S3 {
+ virtual ~S3() throw();
+ S3() throw();
+ explicit S3(int);
+ S3(const S2&);
+};
+void operator +(const S1&, float) throw();
+void operator +(const S1&, const S3&);
+void tlate() {
+ late<float, true>();
+ late<S3, false>();
+}
diff --git a/test/CXX/expr/expr.unary/expr.unary.noexcept/ser.h b/test/CXX/expr/expr.unary/expr.unary.noexcept/ser.h
new file mode 100644
index 0000000..e6e7b79
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.unary.noexcept/ser.h
@@ -0,0 +1,8 @@
+// Serialization testing helper for noexcept, included by cg.cpp.
+
+inline bool f1() {
+ return noexcept(0);
+}
+inline bool f2() {
+ return noexcept(throw 0);
+}
diff --git a/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp b/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp
index 170c734..06cc610 100644
--- a/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp
+++ b/test/CXX/expr/expr.unary/expr.unary.op/p4.cpp
@@ -7,8 +7,7 @@ namespace test0 {
template<typename T> void g(T);
void test() {
- // FIXME: this diagnostic is terrible
- foo(&g<int>); // expected-error {{cannot initialize a parameter of type 'void (test0::A::*)(int)' with an rvalue of type '<overloaded function type>'}}
+ foo(&g<int>); // expected-error {{can't form member pointer of type 'void (test0::A::*)(int)' without '&' and class name}}
}
};
}
@@ -39,7 +38,6 @@ namespace test2 {
};
void A::test() {
- // FIXME: This diagnostic is terrible.
- int (A::*ptr)(int) = &(A::foo); // expected-error {{cannot initialize a variable of type 'int (test2::A::*)(int)' with an rvalue of type '<overloaded function type>'}}
+ int (A::*ptr)(int) = &(A::foo); // expected-error {{can't form member pointer of type 'int (test2::A::*)(int)' without '&' and class name}}
}
}
diff --git a/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
new file mode 100644
index 0000000..543a86d
--- /dev/null
+++ b/test/CXX/expr/expr.unary/expr.unary.op/p6.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// -- prvalue of arithmetic
+
+bool b = !0;
+
+bool b2 = !1.2;
+
+bool b3 = !4;
+
+// -- unscoped enumeration
+enum { E, F };
+
+bool b4 = !E;
+bool b5 = !F;
+
+// -- pointer,
+bool b6 = !&b4;
+void f();
+bool b61 = !&f;
+
+// -- or pointer to member type can be converted to a prvalue of type bool.
+struct S { void f() { } };
+
+bool b7 = !&S::f;
+
+
+bool b8 = !S(); //expected-error {{invalid argument type 'S'}}
+
+namespace PR8181
+{
+ void f() { }
+ void f(char) { }
+ bool b = !&f; //expected-error {{cannot resolve overloaded function from context}}
+
+}
diff --git a/test/CXX/over/over.built/p1.cpp b/test/CXX/over/over.built/p1.cpp
new file mode 100644
index 0000000..6000f5b
--- /dev/null
+++ b/test/CXX/over/over.built/p1.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+enum E1 { one };
+enum E2 { two };
+
+bool operator >= (E1, E1) {
+ return false;
+}
+
+bool operator >= (E1, const E2) {
+ return false;
+}
+
+bool test(E1 a, E1 b, E2 c) {
+ return a >= b || a >= c;
+}
diff --git a/test/CXX/over/over.built/p25.cpp b/test/CXX/over/over.built/p25.cpp
new file mode 100644
index 0000000..c185fb4
--- /dev/null
+++ b/test/CXX/over/over.built/p25.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+enum class Color { Red, Green, Blue };
+
+struct ConvertsToColorA {
+ operator Color();
+};
+
+struct ConvertsToColorB {
+ operator Color();
+};
+
+Color foo(bool cond, ConvertsToColorA ca, ConvertsToColorB cb) {
+ return cond? ca : cb;
+}
diff --git a/test/CXX/over/over.load/p2-0x.cpp b/test/CXX/over/over.load/p2-0x.cpp
new file mode 100644
index 0000000..f0ace90
--- /dev/null
+++ b/test/CXX/over/over.load/p2-0x.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Member function declarations with the same name and the same
+// parameter-type-list as well as mem- ber function template
+// declarations with the same name, the same parameter-type-list, and
+// the same template parameter lists cannot be overloaded if any of
+// them, but not all, have a ref-qualifier (8.3.5).
+
+class Y {
+ void h() &;
+ void h() const &;
+ void h() &&;
+ void i() &; // expected-note{{previous declaration}}
+ void i() const; // expected-error{{cannot overload a member function without a ref-qualifier with a member function with ref-qualifier '&'}}
+
+ template<typename T> void f(T*) &;
+ template<typename T> void f(T*) &&;
+
+ template<typename T> void g(T*) &; // expected-note{{previous declaration}}
+ template<typename T> void g(T*); // expected-error{{cannot overload a member function without a ref-qualifier with a member function with ref-qualifier '&'}}
+
+ void k(); // expected-note{{previous declaration}}
+ void k() &&; // expected-error{{cannot overload a member function with ref-qualifier '&&' with a member function without a ref-qualifier}}
+};
diff --git a/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp b/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp
new file mode 100644
index 0000000..ab171bc
--- /dev/null
+++ b/test/CXX/over/over.match/over.match.best/over.ics.rank/p3-0x.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+namespace std_example {
+ int i;
+ int f1();
+ int&& f2();
+ int &g(const int &);
+ float &g(const int &&);
+ int &j = g(i);
+ float &k = g(f1());
+ float &l = g(f2());
+
+ int &g2(const int &);
+ float &g2(int &&);
+ int &j2 = g2(i);
+ float &k2 = g2(f1());
+ float &l2 = g2(f2());
+
+ // FIXME: We don't support ref-qualifiers yet.
+#if 0
+ struct A {
+ A& operator<<(int);
+ void p() &;
+ void p() &&;
+ };
+
+ A& operator<<(A&&, char);
+ A() << 1;
+ A() << 'c';
+ A a;
+ a << 1;
+ a << 'c';
+ A().p();
+ a.p();
+#endif
+}
+
+template<typename T>
+struct remove_reference {
+ typedef T type;
+};
+
+template<typename T>
+struct remove_reference<T&> {
+ typedef T type;
+};
+
+template<typename T>
+struct remove_reference<T&&> {
+ typedef T type;
+};
+
+namespace FunctionReferencesOverloading {
+ template<typename T> int &f(typename remove_reference<T>::type&);
+ template<typename T> float &f(typename remove_reference<T>::type&&);
+
+ void test_f(int (&func_ref)(int)) {
+ int &ir = f<int (&)(int)>(func_ref);
+ }
+}
diff --git a/test/CXX/over/over.match/over.match.funcs/p4-0x.cpp b/test/CXX/over/over.match/over.match.funcs/p4-0x.cpp
new file mode 100644
index 0000000..8ccc5b6
--- /dev/null
+++ b/test/CXX/over/over.match/over.match.funcs/p4-0x.cpp
@@ -0,0 +1,70 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<typename T> T &lvalue();
+template<typename T> T &&xvalue();
+template<typename T> T prvalue();
+
+struct X0 {
+ int &f() &;
+ float &f() &&;
+
+ template<typename T> int &ft(T) &;
+ template<typename T> float &ft(T) &&;
+
+ typedef int &(*func_int_ref)();
+ typedef float &(*func_float_ref)();
+
+ operator func_int_ref() &;
+ operator func_float_ref() &&;
+
+ void g();
+
+ int &operator+(const X0&) &;
+ float &operator+(const X0&) &&;
+
+ template<typename T> int &operator+(const T&) &;
+ template<typename T> float &operator+(const T&) &&;
+
+ int &h() const&;
+ float &h() &&;
+ int &h2() const&;
+ float &h2() const&&;
+};
+
+void X0::g() {
+ int &ir1 = f();
+ int &ir2 = X0::f();
+}
+
+void test_ref_qualifier_binding() {
+ int &ir1 = lvalue<X0>().f();
+ float &fr1 = xvalue<X0>().f();
+ float &fr2 = prvalue<X0>().f();
+ int &ir2 = lvalue<X0>().ft(1);
+ float &fr3 = xvalue<X0>().ft(2);
+ float &fr4 = prvalue<X0>().ft(3);
+}
+
+void test_ref_qualifier_binding_with_surrogates() {
+ int &ir1 = lvalue<X0>()();
+ float &fr1 = xvalue<X0>()();
+ float &fr2 = prvalue<X0>()();
+}
+
+void test_ref_qualifier_binding_operators() {
+ int &ir1 = lvalue<X0>() + prvalue<X0>();
+ float &fr1 = xvalue<X0>() + prvalue<X0>();
+ float &fr2 = prvalue<X0>() + prvalue<X0>();
+ int &ir2 = lvalue<X0>() + 1;
+ float &fr3 = xvalue<X0>() + 2;
+ float &fr4 = prvalue<X0>() + 3;
+}
+
+void test_ref_qualifier_overloading() {
+ int &ir1 = lvalue<X0>().h();
+ float &fr1 = xvalue<X0>().h();
+ float &fr2 = prvalue<X0>().h();
+ int &ir2 = lvalue<X0>().h2();
+ float &fr3 = xvalue<X0>().h2();
+ float &fr4 = prvalue<X0>().h2();
+}
diff --git a/test/CXX/over/over.over/p2-resolve-single-template-id.cpp b/test/CXX/over/over.over/p2-resolve-single-template-id.cpp
new file mode 100644
index 0000000..f38a74e
--- /dev/null
+++ b/test/CXX/over/over.over/p2-resolve-single-template-id.cpp
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+typedef __typeof__(((int*)0)-((int*)0)) ptrdiff_t;
+
+namespace DontResolveTooEarly_WaitForOverloadResolution
+{
+ template <class T> T* f(int); // #1
+ template <class T, class U> T& f(U); // #2
+
+ void g() {
+ int *ip = f<int>(1); // calls #1
+ }
+
+ template <class T>
+ T* f2(int);
+ template <class T, class U>
+ T& f2(U);
+
+ void g2() {
+ int*ip = (f2<int>)(1); // ok
+ }
+
+} // End namespace
+
+ template<typename T>
+ void twoT() { }
+ template<typename T, typename U>
+ void twoT(T) { }
+
+
+ void two() { }; //expected-note 5{{candidate}}
+ void two(int) { }; //expected-note 5{{candidate}}
+
+
+
+ void one() { }
+ template<class T>
+ void oneT() { }
+
+ template<class T>
+ void cant_resolve() { } //expected-note 3{{candidate}}
+
+ template<class T> void cant_resolve(T) { }//expected-note 3{{candidate}}
+
+
+int main()
+{
+ { static_cast<void>(one); }
+ { (void)(one); }
+ { static_cast<void>(oneT<int>); }
+ { (void)(oneT<int>); }
+
+ { static_cast<void>(two); } // expected-error {{address of overloaded}}
+ { (void)(two); } // expected-error {{address of overloaded}}
+ { static_cast<void>(twoT<int>); }
+ { (void)(twoT<int>); }
+
+
+ { ptrdiff_t x = reinterpret_cast<ptrdiff_t>(oneT<int>); }
+ { (void) reinterpret_cast<int (*)(char, double)>(oneT<int>); }
+ { (void) reinterpret_cast<ptrdiff_t>(one); }
+ { (void) reinterpret_cast<int (*)(char, double)>(one); }
+
+ { ptrdiff_t x = reinterpret_cast<ptrdiff_t>(twoT<int>); }
+ { (void) reinterpret_cast<int (*)(char, double)>(twoT<int>); }
+ { (void) reinterpret_cast<void (*)(int)>(two); } //expected-error {{reinterpret_cast}}
+ { (void) static_cast<void (*)(int)>(two); } //ok
+
+ { (void) reinterpret_cast<int>(two); } //expected-error {{reinterpret_cast}}
+ { (void) reinterpret_cast<int (*)(char, double)>(two); } //expected-error {{reinterpret_cast}}
+
+ { bool b = (twoT<int>); } // ok
+ { bool b = (twoT<int, int>); } //ok
+
+ { bool b = &twoT<int>; //&foo<int>; }
+ b = &(twoT<int>); }
+
+ { ptrdiff_t x = (ptrdiff_t) &twoT<int>;
+ x = (ptrdiff_t) &twoT<int>; }
+
+ { ptrdiff_t x = (ptrdiff_t) twoT<int>;
+ x = (ptrdiff_t) twoT<int>; }
+
+
+ { ptrdiff_t x = (ptrdiff_t) &twoT<int,int>;
+ x = (ptrdiff_t) &twoT<int>; }
+
+ { oneT<int>; &oneT<int>; } //expected-warning 2{{ expression result unused }}
+ { static_cast<void>(cant_resolve<int>); } // expected-error {{address of overload}}
+ { bool b = cant_resolve<int>; } // expected-error {{address of overload}}
+ { (void) cant_resolve<int>; } // expected-error {{address of overload}}
+
+}
+
+
diff --git a/test/CXX/over/over.over/p2.cpp b/test/CXX/over/over.over/p2.cpp
index e8840d2..3e8d0f1 100644
--- a/test/CXX/over/over.over/p2.cpp
+++ b/test/CXX/over/over.over/p2.cpp
@@ -1,10 +1,9 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-template<typename T> T f0(T, T);
+template<typename T> T f0(T, T); //expected-note{{candidate}}
void test_f0() {
int (*f0a)(int, int) = f0;
int (*f0b)(int, int) = &f0;
- int (*f0c)(int, float) = f0; // expected-error{{cannot initialize}}
- // FIXME: poor error message above!
+ int (*f0c)(int, float) = f0; // expected-error{{address of overloaded function 'f0' does not match required type 'int (int, float)'}}
}
diff --git a/test/CXX/over/over.over/p4.cpp b/test/CXX/over/over.over/p4.cpp
index 4189218..27d070e 100644
--- a/test/CXX/over/over.over/p4.cpp
+++ b/test/CXX/over/over.over/p4.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-template<typename T> T f0(T);
+template<typename T> T f0(T); // expected-note{{candidate function}}
int f0(int); // expected-note{{candidate function}}
void test_f0() {
@@ -13,11 +13,8 @@ namespace N {
int f0(int); // expected-note{{candidate function}}
}
-int f0(int);
-
void test_f0_2() {
using namespace N;
- int (*fp0)(int) = f0; // expected-error{{ambiguous}} \
- // expected-error{{cannot initialize}}
+ int (*fp0)(int) = f0; // expected-error{{address of overloaded function 'f0' is ambiguous}}
float (*fp1)(float) = f0;
}
diff --git a/test/CXX/special/class.copy/p33-0x.cpp b/test/CXX/special/class.copy/p33-0x.cpp
new file mode 100644
index 0000000..262809e
--- /dev/null
+++ b/test/CXX/special/class.copy/p33-0x.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fexceptions -std=c++0x -fsyntax-only -verify %s
+class X {
+ X(const X&);
+
+public:
+ X();
+ X(X&&);
+};
+
+X return_by_move(int i, X x) {
+ X x2;
+ if (i == 0)
+ return x;
+ else if (i == 1)
+ return x2;
+ else
+ return x;
+}
+
+void throw_move_only(X x) {
+ X x2;
+ throw x;
+ throw x2;
+}
+
diff --git a/test/CXX/special/class.copy/p9.cpp b/test/CXX/special/class.copy/p9.cpp
index d037944..77ab19e 100644
--- a/test/CXX/special/class.copy/p9.cpp
+++ b/test/CXX/special/class.copy/p9.cpp
@@ -15,30 +15,30 @@ struct VirtualInheritsNonConstCopy : virtual NonConstCopy {
VirtualInheritsNonConstCopy(const VirtualInheritsNonConstCopy&);
};
-struct ImplicitNonConstCopy1 : NonConstCopy {
- ImplicitNonConstCopy1();
+struct ImplicitNonConstCopy1 : NonConstCopy { // expected-note {{candidate constructor}}
+ ImplicitNonConstCopy1(); // expected-note {{candidate constructor}}
};
-struct ImplicitNonConstCopy2 {
- ImplicitNonConstCopy2();
+struct ImplicitNonConstCopy2 { // expected-note {{candidate constructor}}
+ ImplicitNonConstCopy2(); // expected-note {{candidate constructor}}
NonConstCopy ncc;
};
-struct ImplicitNonConstCopy3 {
- ImplicitNonConstCopy3();
+struct ImplicitNonConstCopy3 { // expected-note {{candidate constructor}}
+ ImplicitNonConstCopy3(); // expected-note {{candidate constructor}}
NonConstCopy ncc_array[2][3];
};
-struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy {
- ImplicitNonConstCopy4();
+struct ImplicitNonConstCopy4 : VirtualInheritsNonConstCopy { // expected-note {{candidate constructor}}
+ ImplicitNonConstCopy4(); // expected-note {{candidate constructor}}
};
void test_non_const_copy(const ImplicitNonConstCopy1 &cincc1,
const ImplicitNonConstCopy2 &cincc2,
const ImplicitNonConstCopy3 &cincc3,
const ImplicitNonConstCopy4 &cincc4) {
- (void)sizeof(ImplicitNonConstCopy1(cincc1)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy1 const' to 'ImplicitNonConstCopy1' is not allowed}}
- (void)sizeof(ImplicitNonConstCopy2(cincc2)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy2 const' to 'ImplicitNonConstCopy2' is not allowed}}
- (void)sizeof(ImplicitNonConstCopy3(cincc3)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy3 const' to 'ImplicitNonConstCopy3' is not allowed}}
- (void)sizeof(ImplicitNonConstCopy4(cincc4)); // expected-error{{functional-style cast from 'ImplicitNonConstCopy4 const' to 'ImplicitNonConstCopy4' is not allowed}}
+ (void)sizeof(ImplicitNonConstCopy1(cincc1)); // expected-error{{no matching conversion for functional-style cast from 'const ImplicitNonConstCopy1' to 'ImplicitNonConstCopy1'}}
+ (void)sizeof(ImplicitNonConstCopy2(cincc2)); // expected-error{{no matching conversion for functional-style cast from 'const ImplicitNonConstCopy2' to 'ImplicitNonConstCopy2'}}
+ (void)sizeof(ImplicitNonConstCopy3(cincc3)); // expected-error{{no matching conversion for functional-style cast from 'const ImplicitNonConstCopy3' to 'ImplicitNonConstCopy3'}}
+ (void)sizeof(ImplicitNonConstCopy4(cincc4)); // expected-error{{no matching conversion for functional-style cast from 'const ImplicitNonConstCopy4' to 'ImplicitNonConstCopy4'}}
}
diff --git a/test/CXX/special/class.ctor/p4-0x.cpp b/test/CXX/special/class.ctor/p4-0x.cpp
new file mode 100644
index 0000000..e3508e2
--- /dev/null
+++ b/test/CXX/special/class.ctor/p4-0x.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// A constructor shall not be declared with a ref-qualifier.
+struct X {
+ X() &; // expected-error{{ref-qualifier '&' is not allowed on a constructor}}
+ X(int) &&; // expected-error{{ref-qualifier '&&' is not allowed on a constructor}}
+};
diff --git a/test/CXX/special/class.dtor/p2-0x.cpp b/test/CXX/special/class.dtor/p2-0x.cpp
new file mode 100644
index 0000000..53a2e03
--- /dev/null
+++ b/test/CXX/special/class.dtor/p2-0x.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// A destructor shall not be declared with a ref-qualifier.
+struct X {
+ ~X() &; // expected-error{{ref-qualifier '&' is not allowed on a destructor}}
+};
+
+struct Y {
+ ~Y() &&; // expected-error{{ref-qualifier '&&' is not allowed on a destructor}}
+};
diff --git a/test/CXX/special/class.inhctor/elsewhere.cpp b/test/CXX/special/class.inhctor/elsewhere.cpp
new file mode 100644
index 0000000..82944d6
--- /dev/null
+++ b/test/CXX/special/class.inhctor/elsewhere.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Tests related to constructor inheriting, but not specified in [class.inhctor]
+
+// [namespace.udecl]p8:
+// A using-declaration for a class member shall be a member-declaration.
+
+struct B1 {
+ B1(int);
+};
+
+using B1::B1; // expected-error {{using declaration can not refer to class member}}
+
+// C++0x [namespace.udecl]p10:
+// A using-declaration is a declaration and can therefore be used repeatedly
+// where (and only where) multiple declarations are allowed.
+
+struct I1 : B1 {
+ using B1::B1; // expected-note {{previous using declaration}}
+ using B1::B1; // expected-error {{redeclaration of using decl}}
+};
+
+// C++0x [namespace.udecl]p3:
+// In a using declaration used as a member-declaration, the nested-name-
+// specifier shall name a base class of the class being defined.
+// If such a using-declaration names a constructor, the nested-name-specifier
+// shall name a direct base class of the class being defined.
+
+struct D1 : I1 {
+ using B1::B1; // expected-error {{'B1' is not a direct base of 'D1', can not inherit constructors}}
+};
diff --git a/test/CXX/special/class.inhctor/p3.cpp b/test/CXX/special/class.inhctor/p3.cpp
new file mode 100644
index 0000000..021f701
--- /dev/null
+++ b/test/CXX/special/class.inhctor/p3.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+struct B1 {
+ B1(int);
+ B1(int, int);
+};
+struct D1 : B1 {
+ using B1::B1;
+};
+D1 d1a(1), d1b(1, 1);
+
+D1 fd1() { return 1; }
+
+struct B2 {
+ explicit B2(int, int = 0, int = 0);
+};
+struct D2 : B2 { // expected-note {{candidate constructor}}
+ using B2::B2;
+};
+D2 d2a(1), d2b(1, 1), d2c(1, 1, 1);
+
+D2 fd2() { return 1; } // expected-error {{no viable conversion}}
+
+struct B3 {
+ B3(void*); // expected-note {{inherited from here}}
+};
+struct D3 : B3 { // expected-note {{candidate constructor}}
+ using B3::B3; // expected-note {{candidate constructor (inherited)}}
+};
+D3 fd3() { return 1; } // expected-error {{no viable conversion}}
diff --git a/test/CXX/special/class.inhctor/p7.cpp b/test/CXX/special/class.inhctor/p7.cpp
new file mode 100644
index 0000000..3ad761f
--- /dev/null
+++ b/test/CXX/special/class.inhctor/p7.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Straight from the standard
+struct B1 {
+ B1(int); // expected-note {{previous constructor}}
+};
+struct B2 {
+ B2(int); // expected-note {{conflicting constructor}}
+};
+struct D1 : B1, B2 {
+ using B1::B1; // expected-note {{inherited here}}
+ using B2::B2; // expected-error {{already inherited constructor with the same signature}}
+};
+struct D2 : B1, B2 {
+ using B1::B1;
+ using B2::B2;
+ D2(int);
+};
diff --git a/test/CXX/stmt.stmt/stmt.label/p1.cpp b/test/CXX/stmt.stmt/stmt.label/p1.cpp
new file mode 100644
index 0000000..90367f8
--- /dev/null
+++ b/test/CXX/stmt.stmt/stmt.label/p1.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f()
+{
+ int x = 0;
+ goto label1;
+
+label1: // expected-note{{previous definition is here}}
+ x = 1;
+ goto label2; // expected-error{{use of undeclared label 'label2'}}
+
+label1: // expected-error{{redefinition of label 'label1'}}
+ x = 2;
+}
+
+void h()
+{
+ int x = 0;
+ switch (x)
+ {
+ case 1:;
+ default:; // expected-error{{multiple default labels in one switch}}
+ default:; // expected-note{{previous case defined here}}
+ }
+}
diff --git a/test/CXX/stmt.stmt/stmt.select/p3.cpp b/test/CXX/stmt.stmt/stmt.select/p3.cpp
index 31de685..35e5c91 100644
--- a/test/CXX/stmt.stmt/stmt.select/p3.cpp
+++ b/test/CXX/stmt.stmt/stmt.select/p3.cpp
@@ -16,4 +16,4 @@ void h() {
int x; // expected-error{{redefinition of 'x'}}
else
int x; // expected-error{{redefinition of 'x'}}
-} \ No newline at end of file
+}
diff --git a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
index b0f1c46..9b9b532 100644
--- a/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
+++ b/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
@@ -53,7 +53,7 @@ namespace pointer_to_object_parameters {
A2<X_ptr> *a12; // expected-error{{must have its address taken}}
A2<array_of_Xs> *a13;
A2<&an_X> *a13_2;
- A2<(&an_X)> *a13_3; // expected-error{{non-type template argument cannot be surrounded by parentheses}}
+ A2<(&an_X)> *a13_3; // expected-warning{{address non-type template argument cannot be surrounded by parentheses}}
// PR6244
struct X1 {} X1v;
@@ -88,19 +88,19 @@ namespace reference_parameters {
extern const volatile int cvi;
void test() {
S0<i> s0;
- S0<ci> s0c; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const' ignores qualifiers}}
- S0<vi> s0v; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int volatile' ignores qualifiers}}
- S0<cvi> s0cv; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'int const volatile' ignores qualifiers}}
+ S0<ci> s0c; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'const int' ignores qualifiers}}
+ S0<vi> s0v; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'volatile int' ignores qualifiers}}
+ S0<cvi> s0cv; // expected-error{{reference binding of non-type template parameter of type 'int &' to template argument of type 'const volatile int' ignores qualifiers}}
S1<i> s1;
S1<ci> s1c;
- S1<vi> s1v; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int volatile' ignores qualifiers}}
- S1<cvi> s1cv; // expected-error{{reference binding of non-type template parameter of type 'int const &' to template argument of type 'int const volatile' ignores qualifiers}}
+ S1<vi> s1v; // expected-error{{reference binding of non-type template parameter of type 'const int &' to template argument of type 'volatile int' ignores qualifiers}}
+ S1<cvi> s1cv; // expected-error{{reference binding of non-type template parameter of type 'const int &' to template argument of type 'const volatile int' ignores qualifiers}}
S2<i> s2;
- S2<ci> s2c; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const' ignores qualifiers}}
+ S2<ci> s2c; // expected-error{{reference binding of non-type template parameter of type 'volatile int &' to template argument of type 'const int' ignores qualifiers}}
S2<vi> s2v;
- S2<cvi> s2cv; // expected-error{{reference binding of non-type template parameter of type 'int volatile &' to template argument of type 'int const volatile' ignores qualifiers}}
+ S2<cvi> s2cv; // expected-error{{reference binding of non-type template parameter of type 'volatile int &' to template argument of type 'const volatile int' ignores qualifiers}}
S3<i> s3;
S3<ci> s3c;
diff --git a/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp b/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
new file mode 100644
index 0000000..794a050
--- /dev/null
+++ b/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template <class T> struct eval; // expected-note 3{{template is declared here}}
+
+template <template <class, class...> class TT, class T1, class... Rest>
+struct eval<TT<T1, Rest...>> { };
+
+template <class T1> struct A;
+template <class T1, class T2> struct B;
+template <int N> struct C;
+template <class T1, int N> struct D;
+template <class T1, class T2, int N = 17> struct E;
+
+eval<A<int>> eA;
+eval<B<int, float>> eB;
+eval<C<17>> eC; // expected-error{{implicit instantiation of undefined template 'eval<C<17> >'}}
+eval<D<int, 17>> eD; // expected-error{{implicit instantiation of undefined template 'eval<D<int, 17> >'}}
+eval<E<int, float>> eE; // expected-error{{implicit instantiation of undefined template 'eval<E<int, float, 17> >}}
+
+template<template <int ...N> class TT> struct X0 { }; // expected-note{{previous non-type template parameter with type 'int' is here}}
+template<int I, int J, int ...Rest> struct X0a;
+template<int ...Rest> struct X0b;
+template<int I, long J> struct X0c; // expected-note{{template non-type parameter has a different type 'long' in template argument}}
+
+X0<X0a> inst_x0a;
+X0<X0b> inst_x0b;
+X0<X0c> inst_x0c; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+
+template<typename T,
+ template <T ...N> class TT> // expected-note{{previous non-type template parameter with type 'short' is here}}
+struct X1 { };
+template<int I, int J, int ...Rest> struct X1a;
+template<long I, long ...Rest> struct X1b;
+template<short I, short J> struct X1c;
+template<short I, long J> struct X1d; // expected-note{{template non-type parameter has a different type 'long' in template argument}}
+
+X1<int, X1a> inst_x1a;
+X1<long, X1b> inst_x1b;
+X1<short, X1c> inst_x1c;
+X1<short, X1d> inst_x1d; // expected-error{{template template argument has different template parameters than its corresponding template template paramete}}
diff --git a/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp b/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp
new file mode 100644
index 0000000..0fd9a7e
--- /dev/null
+++ b/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<class T> struct A {
+ static T t; // expected-error{{static data member instantiated with function type 'int ()'}}
+};
+typedef int function();
+A<function> a; // expected-note{{instantiation of}}
+
+template<typename T> struct B {
+ B() { T t; } // expected-error{{variable instantiated with function type 'int ()'}}
+};
+B<function> b; // expected-note{{instantiation of}}
+
+template <typename T> int f0(void *, const T&); // expected-note{{candidate template ignored: substitution failure}}
+enum {e}; // expected-note{{unnamed type used in template argument was declared here}}
+
+void test_f0(int n) {
+ int i = f0(0, e); // expected-warning{{template argument uses unnamed type}}
+ int vla[n];
+ f0(0, vla); // expected-error{{no matching function for call to 'f0'}}
+}
+
+namespace N0 {
+ template <typename R, typename A1> void f0(R (*)(A1));
+ template <typename T> int f1(T);
+ template <typename T, typename U> int f1(T, U);
+ enum {e1}; // expected-note 2{{unnamed type used in template argument was declared here}}
+ enum {e2}; // expected-note 2{{unnamed type used in template argument was declared here}}
+ enum {e3}; // expected-note{{unnamed type used in template argument was declared here}}
+
+ template<typename T> struct X;
+ template<typename T> struct X<T*> { };
+
+ void f() {
+ f0( // expected-warning{{template argument uses unnamed type}}
+ &f1<__typeof__(e1)>); // expected-warning{{template argument uses unnamed type}}
+ int (*fp1)(int, __typeof__(e2)) = f1; // expected-warning{{template argument uses unnamed type}}
+ f1(e2); // expected-warning{{template argument uses unnamed type}}
+ f1(e2);
+
+ X<__typeof__(e3)*> x; // expected-warning{{template argument uses unnamed type}}
+ }
+}
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp
index a93249e..d0fc797 100644
--- a/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp
+++ b/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp
@@ -53,3 +53,24 @@ struct X0<float>::Inner0<Z*> {
int array3[X0<float>::Inner0<int>::value == 0? 1 : -1];
int array4[X0<float>::Inner0<int*>::value == 3? 1 : -1];
int array5[X0<float>::Inner0<const int*>::value == 2? 1 : -1];
+
+namespace rdar8651930 {
+ template<typename OuterT>
+ struct Outer {
+ template<typename T, typename U>
+ struct Inner;
+
+ template<typename T>
+ struct Inner<T, T> {
+ static const bool value = true;
+ };
+
+ template<typename T, typename U>
+ struct Inner {
+ static const bool value = false;
+ };
+ };
+
+ int array0[Outer<int>::Inner<int, int>::value? 1 : -1];
+ int array1[Outer<int>::Inner<int, float>::value? -1 : 1];
+}
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
new file mode 100644
index 0000000..14152cf
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<int ...Values> struct X1;
+
+template<int ...Values>
+struct X1<0, Values+1 ...>; // expected-error{{non-type template argument depends on a template parameter of the partial specialization}}
+
+
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p9-0x.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p9-0x.cpp
new file mode 100644
index 0000000..d8e07b8
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class.spec/p9-0x.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// -- The argument list of the specialization shall not be identical
+// to the implicit argument list of the primary template.
+
+template<typename T, typename ...Types>
+struct X1;
+
+template<typename T, typename ...Types>
+struct X1<T, Types...> // expected-error{{class template partial specialization does not specialize any template argument; to define the primary template, remove the template argument list}}
+{ };
+
+
diff --git a/test/CXX/temp/temp.decls/temp.class.spec/p9.cpp b/test/CXX/temp/temp.decls/temp.class.spec/p9.cpp
new file mode 100644
index 0000000..2a3e914
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.class.spec/p9.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR8905
+template<char C1, char C2>
+struct X {
+ static const bool value = 0;
+};
+
+template<int C1>
+struct X<C1, C1> {
+ static const bool value = 1;
+};
+
+int check0[X<1, 2>::value == 0? 1 : -1];
+int check1[X<1, 1>::value == 1? 1 : -1];
+
+template<int, int, int> struct int_values {
+ static const unsigned value = 0;
+};
+
+template<unsigned char C1, unsigned char C3>
+struct int_values<C1, 12, C3> {
+ static const unsigned value = 1;
+};
+
+int check2[int_values<256, 12, 3>::value == 0? 1 : -1];
diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
new file mode 100644
index 0000000..11ec289
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+// Core DR 532.
+namespace PR8130 {
+ struct A { };
+
+ template<class T> struct B {
+ template<class R> int &operator*(R&);
+ };
+
+ template<class T, class R> float &operator*(T&, R&);
+ void test() {
+ A a;
+ B<A> b;
+ int &ir = b * a;
+ }
+}
diff --git a/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
new file mode 100644
index 0000000..2ffdd95
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace DeduceVsMember {
+ template<typename T>
+ struct X {
+ template<typename U>
+ int &operator==(const U& other) const;
+ };
+
+ template<typename T, typename U>
+ float &operator==(const T&, const X<U>&);
+
+ void test(X<int> xi, X<float> xf) {
+ float& ir = (xi == xf);
+ }
+}
diff --git a/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
index 073b2a1..578de29 100644
--- a/test/CXX/temp/temp.decls/temp.friend/p1.cpp
+++ b/test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -293,3 +293,42 @@ namespace test13 {
template class Foo<0>;
}
+
+namespace test14 {
+ template <class T> class B;
+ template <class T> class A {
+ friend void B<T>::foo();
+ static void foo(); // expected-note {{declared private here}}
+ };
+
+ template <class T> class B {
+ void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test14::A<long>'}}
+ };
+
+ template class B<int>; // expected-note {{in instantiation}}
+}
+
+namespace test15 {
+ template <class T> class B;
+ template <class T> class A {
+ friend void B<T>::foo();
+
+ // This shouldn't be misrecognized as a templated-scoped reference.
+ template <class U> friend void B<T>::bar(U);
+
+ static void foo(); // expected-note {{declared private here}}
+ };
+
+ template <class T> class B {
+ void foo() { return A<long>::foo(); } // expected-error {{'foo' is a private member of 'test15::A<long>'}}
+ };
+
+ template <> class B<float> {
+ void foo() { return A<float>::foo(); }
+ template <class U> void bar(U u) {
+ (void) A<float>::foo();
+ }
+ };
+
+ template class B<int>; // expected-note {{in instantiation}}
+}
diff --git a/test/CXX/temp/temp.decls/temp.friend/p5.cpp b/test/CXX/temp/temp.decls/temp.friend/p5.cpp
index f23611b..63fd3df 100644
--- a/test/CXX/temp/temp.decls/temp.friend/p5.cpp
+++ b/test/CXX/temp/temp.decls/temp.friend/p5.cpp
@@ -1,13 +1,103 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-template <class T> class A {
- class Member {
+namespace test0 {
+ template <class T> class A {
+ class Member {};
};
-};
-class B {
- template <class T> friend class A<T>::Member;
-};
+ class B {
+ template <class T> friend class A<T>::Member;
+ };
+
+ A<int> a;
+ B b;
+}
+
+// rdar://problem/8204127
+namespace test1 {
+ template <class T> struct A;
+
+ class C {
+ static void foo();
+ template <class T> friend void A<T>::f();
+ };
+
+ template <class T> struct A {
+ void f() { C::foo(); }
+ };
+
+ template <class T> struct A<T*> {
+ void f() { C::foo(); }
+ };
+
+ template <> struct A<char> {
+ void f() { C::foo(); }
+ };
+}
+
+// FIXME: these should fail!
+namespace test2 {
+ template <class T> struct A;
+
+ class C {
+ static void foo();
+ template <class T> friend void A<T>::g();
+ };
+
+ template <class T> struct A {
+ void f() { C::foo(); }
+ };
+
+ template <class T> struct A<T*> {
+ void f() { C::foo(); }
+ };
+
+ template <> struct A<char> {
+ void f() { C::foo(); }
+ };
+}
+
+// Tests 3, 4 and 5 were all noted in <rdar://problem/8540527>.
+namespace test3 {
+ template <class T> struct A {
+ struct Inner {
+ static int foo();
+ };
+ };
+
+ template <class U> class C {
+ int i;
+ template <class T> friend struct A<T>::Inner;
+ };
+
+ template <class T> int A<T>::Inner::foo() {
+ C<int> c;
+ c.i = 0;
+ return 0;
+ }
+
+ int test = A<int>::Inner::foo();
+}
+
+namespace test4 {
+ template <class T> struct X {
+ template <class U> void operator+=(U);
+
+ template <class V>
+ template <class U>
+ friend void X<V>::operator+=(U);
+ };
+
+ void test() {
+ X<int>() += 1.0;
+ }
+}
+
+namespace test5 {
+ template<template <class> class T> struct A {
+ template<template <class> class T> friend void A<T>::foo();
+ };
-A<int> a;
-B b;
+ template <class> struct B {};
+ template class A<B>;
+}
diff --git a/test/CXX/temp/temp.decls/temp.friend/p8.cpp b/test/CXX/temp/temp.decls/temp.friend/p8.cpp
new file mode 100644
index 0000000..d0221a3
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.friend/p8.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<class T> class A { };
+
+class X {
+ template<class T> friend class A<T*>; // expected-error{{partial specialization cannot be declared as a friend}}
+};
diff --git a/test/CXX/temp/temp.decls/temp.mem/p3.cpp b/test/CXX/temp/temp.decls/temp.mem/p3.cpp
new file mode 100644
index 0000000..0eb747b
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.mem/p3.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <class T> struct AA {
+ template <class C> virtual void g(C); // expected-error{{'virtual' can not be specified on member function templates}}
+ virtual void f();
+};
diff --git a/test/CXX/temp/temp.decls/temp.mem/p5.cpp b/test/CXX/temp/temp.decls/temp.mem/p5.cpp
index b0078d4..a188f05 100644
--- a/test/CXX/temp/temp.decls/temp.mem/p5.cpp
+++ b/test/CXX/temp/temp.decls/temp.mem/p5.cpp
@@ -63,12 +63,12 @@ struct X0 {
template<typename T> operator const T*() const {
T x = T();
- return x; // expected-error{{cannot initialize return object of type 'char const *' with an lvalue of type 'char'}}
+ return x; // expected-error{{cannot initialize return object of type 'const char *' with an lvalue of type 'char'}}
}
};
-template X0::operator const char*() const; // expected-note{{'X0::operator char const *<char>' requested here}}
-template X0::operator const int*(); // expected-note{{'X0::operator int const *<int const>' requested here}}
+template X0::operator const char*() const; // expected-note{{'X0::operator const char *<char>' requested here}}
+template X0::operator const int*(); // expected-note{{'X0::operator const int *<const int>' requested here}}
template X0::operator float*() const; // expected-error{{explicit instantiation of undefined function template}}
void test_X0(X0 x0, const X0 &x0c) {
diff --git a/test/CXX/temp/temp.decls/temp.variadic/deduction.cpp b/test/CXX/temp/temp.decls/temp.variadic/deduction.cpp
new file mode 100644
index 0000000..383e268
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/deduction.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+namespace DeductionForInstantiation {
+ template<unsigned I, typename ...Types>
+ struct X { };
+
+ template<typename ...Types>
+ void f0(X<sizeof...(Types), Types&...>) { }
+
+ // No explicitly-specified arguments
+ template void f0(X<0>);
+ template void f0(X<1, int&>);
+ template void f0(X<2, int&, short&>);
+
+ // One explicitly-specified argument
+ template void f0<float>(X<1, float&>);
+ template void f0<double>(X<1, double&>);
+
+ // Two explicitly-specialized arguments
+ template void f0<char, unsigned char>(X<2, char&, unsigned char&>);
+ template void f0<signed char, char>(X<2, signed char&, char&>);
+
+ // FIXME: Extension of explicitly-specified arguments
+ // template void f0<short, int>(X<3, short&, int&, long&>);
+}
+
+namespace DeductionWithConversion {
+ template<char...> struct char_values {
+ static const unsigned value = 0;
+ };
+
+ template<int C1, char C3>
+ struct char_values<C1, 12, C3> {
+ static const unsigned value = 1;
+ };
+
+ int check0[char_values<1, 12, 3>::value == 1? 1 : -1];
+
+ template<int...> struct int_values {
+ static const unsigned value = 0;
+ };
+
+ template<unsigned char C1, unsigned char C3>
+ struct int_values<C1, 12, C3> {
+ static const unsigned value = 1;
+ };
+
+ int check1[int_values<256, 12, 3>::value == 0? 1 : -1];
+ int check2[int_values<3, 12, 3>::value == 1? 1 : -1];
+}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/example-bind.cpp b/test/CXX/temp/temp.decls/temp.variadic/example-bind.cpp
new file mode 100644
index 0000000..83db171
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/example-bind.cpp
@@ -0,0 +1,352 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Example bind implementation from the variadic templates proposal,
+// ISO C++ committee document number N2080.
+
+// Helper type traits
+template<typename T>
+struct add_reference {
+ typedef T &type;
+};
+
+template<typename T>
+struct add_reference<T&> {
+ typedef T &type;
+};
+
+template<typename T>
+struct add_const_reference {
+ typedef T const &type;
+};
+
+template<typename T>
+struct add_const_reference<T&> {
+ typedef T &type;
+};
+
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+template<typename T>
+class reference_wrapper {
+ T *ptr;
+
+public:
+ reference_wrapper(T& t) : ptr(&t) { }
+ operator T&() const { return *ptr; }
+};
+
+template<typename T> reference_wrapper<T> ref(T& t) {
+ return reference_wrapper<T>(t);
+}
+template<typename T> reference_wrapper<const T> cref(const T& t) {
+ return reference_wrapper<const T>(t);
+}
+
+template<typename... Values> class tuple;
+
+// Basis case: zero-length tuple
+template<> class tuple<> { };
+
+template<typename Head, typename... Tail>
+class tuple<Head, Tail...> : private tuple<Tail...> {
+ typedef tuple<Tail...> inherited;
+
+public:
+ tuple() { }
+ // implicit copy-constructor is okay
+
+ // Construct tuple from separate arguments.
+ tuple(typename add_const_reference<Head>::type v,
+ typename add_const_reference<Tail>::type... vtail)
+ : m_head(v), inherited(vtail...) { }
+
+ // Construct tuple from another tuple.
+ template<typename... VValues> tuple(const tuple<VValues...>& other)
+ : m_head(other.head()), inherited(other.tail()) { }
+
+ template<typename... VValues> tuple&
+ operator=(const tuple<VValues...>& other) {
+ m_head = other.head();
+ tail() = other.tail();
+ return *this;
+ }
+
+ typename add_reference<Head>::type head() { return m_head; }
+ typename add_reference<const Head>::type head() const { return m_head; }
+ inherited& tail() { return *this; }
+ const inherited& tail() const { return *this; }
+
+protected:
+ Head m_head;
+};
+
+// Creation functions
+template<typename T>
+struct make_tuple_result {
+ typedef T type;
+};
+
+template<typename T>
+struct make_tuple_result<reference_wrapper<T> > {
+ typedef T& type;
+};
+
+template<typename... Values>
+tuple<typename make_tuple_result<Values>::type...>
+make_tuple(const Values&... values) {
+ return tuple<typename make_tuple_result<Values>::type...>(values...);
+}
+
+template<typename... Values>
+tuple<Values&...> tie(Values&... values) {
+ return tuple<Values&...>(values...);
+}
+
+// Helper classes
+template<typename Tuple> struct tuple_size;
+
+template<typename... Values> struct tuple_size<tuple<Values...> > {
+ static const int value = sizeof...(Values);
+};
+
+template<int I, typename Tuple> struct tuple_element;
+
+template<int I, typename Head, typename... Tail>
+struct tuple_element<I, tuple<Head, Tail...> > {
+ typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
+};
+
+template<typename Head, typename... Tail>
+struct tuple_element<0, tuple<Head, Tail...> > {
+ typedef Head type;
+};
+
+// Element access
+template<int I, typename Tuple> class get_impl;
+template<int I, typename Head, typename... Values>
+class get_impl<I, tuple<Head, Values...> > {
+ typedef typename tuple_element<I-1, tuple<Values...> >::type Element;
+ typedef typename add_reference<Element>::type RJ;
+ typedef typename add_const_reference<Element>::type PJ;
+ typedef get_impl<I-1, tuple<Values...> > Next;
+public:
+ static RJ get(tuple<Head, Values...>& t) { return Next::get(t.tail()); }
+ static PJ get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); }
+};
+
+template<typename Head, typename... Values>
+class get_impl<0, tuple<Head, Values...> > {
+ typedef typename add_reference<Head>::type RJ;
+ typedef typename add_const_reference<Head>::type PJ;
+public:
+ static RJ get(tuple<Head, Values...>& t) { return t.head(); }
+ static PJ get(const tuple<Head, Values...>& t) { return t.head(); }
+};
+
+template<int I, typename... Values> typename add_reference<
+typename tuple_element<I, tuple<Values...> >::type >::type
+get(tuple<Values...>& t) {
+ return get_impl<I, tuple<Values...> >::get(t);
+}
+
+template<int I, typename... Values> typename add_const_reference<
+typename tuple_element<I, tuple<Values...> >::type >::type
+get(const tuple<Values...>& t) {
+ return get_impl<I, tuple<Values...> >::get(t);
+}
+
+// Relational operators
+inline bool operator==(const tuple<>&, const tuple<>&) { return true; }
+
+template<typename T, typename... TTail, typename U, typename... UTail>
+bool operator==(const tuple<T, TTail...>& t, const tuple<U, UTail...>& u) {
+ return t.head() == u.head() && t.tail() == u.tail();
+}
+
+template<typename... TValues, typename... UValues>
+bool operator!=(const tuple<TValues...>& t, const tuple<UValues...>& u) {
+ return !(t == u);
+}
+
+inline bool operator<(const tuple<>&, const tuple<>&) { return false; }
+
+template<typename T, typename... TTail, typename U, typename... UTail>
+bool operator<(const tuple<T, TTail...>& t, const tuple<U, UTail...>& u) {
+ return (t.head() < u.head() || (!(t.head() < u.head()) && t.tail() < u.tail()));
+}
+
+template<typename... TValues, typename... UValues>
+bool operator>(const tuple<TValues...>& t, const tuple<UValues...>& u) {
+ return u < t;
+}
+
+template<typename... TValues, typename... UValues>
+bool operator<=(const tuple<TValues...>& t, const tuple<UValues...>& u) {
+ return !(u < t);
+}
+
+template<typename... TValues, typename... UValues>
+bool operator>=(const tuple<TValues...>& t, const tuple<UValues...>& u) {
+ return !(t < u);
+}
+
+// make_indices helper
+template<int...> struct int_tuple {};
+// make_indexes impl is a helper for make_indexes
+template<int I, typename IntTuple, typename... Types> struct make_indexes_impl;
+
+template<int I, int... Indexes, typename T, typename... Types>
+struct make_indexes_impl<I, int_tuple<Indexes...>, T, Types...> {
+ typedef typename make_indexes_impl<I+1, int_tuple<Indexes..., I>, Types...>::type type;
+};
+
+template<int I, int... Indexes>
+struct make_indexes_impl<I, int_tuple<Indexes...> > {
+ typedef int_tuple<Indexes...> type;
+};
+
+template<typename... Types>
+struct make_indexes : make_indexes_impl<0, int_tuple<>, Types...> {
+};
+
+// Bind
+template<typename T> struct is_bind_expression {
+ static const bool value = false;
+};
+
+template<typename T> struct is_placeholder {
+ static const int value = 0;
+};
+
+
+template<typename F, typename... BoundArgs> class bound_functor {
+ typedef typename make_indexes<BoundArgs...>::type indexes;
+public:
+ typedef typename F::result_type result_type;
+ explicit bound_functor(const F& f, const BoundArgs&... bound_args)
+ : f(f), bound_args(bound_args...) { } template<typename... Args>
+ typename F::result_type operator()(Args&... args);
+private: F f;
+ tuple<BoundArgs...> bound_args;
+};
+
+template<typename F, typename... BoundArgs>
+inline bound_functor<F, BoundArgs...> bind(const F& f, const BoundArgs&... bound_args) {
+ return bound_functor<F, BoundArgs...>(f, bound_args...);
+}
+
+template<typename F, typename ...BoundArgs>
+struct is_bind_expression<bound_functor<F, BoundArgs...> > {
+ static const bool value = true;
+};
+
+// enable_if helper
+template<bool Cond, typename T = void>
+struct enable_if;
+
+template<typename T>
+struct enable_if<true, T> {
+ typedef T type;
+};
+
+template<typename T>
+struct enable_if<false, T> { };
+
+// safe_tuple_element helper
+template<int I, typename Tuple, typename = void>
+struct safe_tuple_element { };
+
+template<int I, typename... Values>
+struct safe_tuple_element<I, tuple<Values...>,
+ typename enable_if<(I >= 0 && I < tuple_size<tuple<Values...> >::value)>::type> {
+ typedef typename tuple_element<I, tuple<Values...> >::type type;
+};
+
+// mu
+template<typename Bound, typename... Args>
+inline typename safe_tuple_element<is_placeholder<Bound>::value -1,
+ tuple<Args...> >::type
+mu(Bound& bound_arg, const tuple<Args&...>& args) {
+ return get<is_placeholder<Bound>::value-1>(args);
+}
+
+template<typename T, typename... Args>
+inline T& mu(reference_wrapper<T>& bound_arg, const tuple<Args&...>&) {
+ return bound_arg.get();
+}
+
+template<typename F, int... Indexes, typename... Args>
+inline typename F::result_type
+unwrap_and_forward(F& f, int_tuple<Indexes...>, const tuple<Args&...>& args) {
+ return f(get<Indexes>(args)...);
+}
+
+template<typename Bound, typename... Args>
+inline typename enable_if<is_bind_expression<Bound>::value,
+ typename Bound::result_type>::type
+mu(Bound& bound_arg, const tuple<Args&...>& args) {
+ typedef typename make_indexes<Args...>::type Indexes;
+ return unwrap_and_forward(bound_arg, Indexes(), args);
+}
+
+template<typename T>
+struct is_reference_wrapper {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_reference_wrapper<reference_wrapper<T>> {
+ static const bool value = true;
+};
+
+template<typename Bound, typename... Args>
+inline typename enable_if<(!is_bind_expression<Bound>::value
+ && !is_placeholder<Bound>::value
+ && !is_reference_wrapper<Bound>::value),
+ Bound&>::type
+mu(Bound& bound_arg, const tuple<Args&...>&) {
+ return bound_arg;
+}
+
+template<typename F, typename... BoundArgs, int... Indexes, typename... Args>
+typename F::result_type apply_functor(F& f, tuple<BoundArgs...>& bound_args,
+ int_tuple<Indexes...>,
+ const tuple<Args&...>& args) {
+ return f(mu(get<Indexes>(bound_args), args)...);
+}
+
+template<typename F, typename... BoundArgs>
+template<typename... Args>
+typename F::result_type bound_functor<F, BoundArgs...>::operator()(Args&... args) {
+ return apply_functor(f, bound_args, indexes(), tie(args...));
+}
+
+template<int N> struct placeholder { };
+template<int N>
+struct is_placeholder<placeholder<N>> {
+ static const int value = N;
+};
+
+template<typename T>
+struct plus {
+ typedef T result_type;
+
+ T operator()(T x, T y) { return x + y; }
+};
+
+placeholder<1> _1;
+
+// Test bind
+void test_bind() {
+ int x = 17;
+ int y = 25;
+ bind(plus<int>(), x, _1)(y);
+}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp b/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp
new file mode 100644
index 0000000..b3d010c
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Example function implementation from the variadic templates proposal,
+// ISO C++ committee document number N2080.
+
+template<typename Signature> class function;
+
+template<typename R, typename... Args> class invoker_base {
+public:
+ virtual ~invoker_base() { }
+ virtual R invoke(Args...) = 0;
+ virtual invoker_base* clone() = 0;
+};
+
+template<typename F, typename R, typename... Args>
+class functor_invoker : public invoker_base<R, Args...> {
+public:
+ explicit functor_invoker(const F& f) : f(f) { }
+ R invoke(Args... args) { return f(args...); }
+ functor_invoker* clone() { return new functor_invoker(f); }
+
+private:
+ F f;
+};
+
+template<typename R, typename... Args>
+class function<R (Args...)> {
+public:
+ typedef R result_type;
+ function() : invoker (0) { }
+ function(const function& other) : invoker(0) {
+ if (other.invoker)
+ invoker = other.invoker->clone();
+ }
+
+ template<typename F> function(const F& f) : invoker(0) {
+ invoker = new functor_invoker<F, R, Args...>(f);
+ }
+
+ ~function() {
+ if (invoker)
+ delete invoker;
+ }
+
+ function& operator=(const function& other) {
+ function(other).swap(*this);
+ return *this;
+ }
+
+ template<typename F>
+ function& operator=(const F& f) {
+ function(f).swap(*this);
+ return *this;
+ }
+
+ void swap(function& other) {
+ invoker_base<R, Args...>* tmp = invoker;
+ invoker = other.invoker;
+ other.invoker = tmp;
+ }
+
+ result_type operator()(Args... args) const {
+ return invoker->invoke(args...);
+ }
+
+private:
+ invoker_base<R, Args...>* invoker;
+};
+
+template<typename T>
+struct add {
+ T operator()(T x, T y) { return x + y; }
+};
+
+int add_ints(int x, int y) { return x + y; }
+
+void test_function() {
+ function<int(int, int)> f2a;
+ function<int(int, int)> f2b = add<int>();
+ function<int(int, int)> f2c = add<float>();
+ function<int(int, int)> f2d(f2b);
+ function<int(int, int)> f2e = &add_ints;
+ f2c = f2d;
+ f2d = &add_ints;
+ f2c(1.0, 3);
+}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp b/test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp
new file mode 100644
index 0000000..3b4bd77
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp
@@ -0,0 +1,260 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Example tuple implementation from the variadic templates proposal,
+// ISO C++ committee document number N2080.
+
+// Helper type traits
+template<typename T>
+struct add_reference {
+ typedef T &type;
+};
+
+template<typename T>
+struct add_reference<T&> {
+ typedef T &type;
+};
+
+template<typename T>
+struct add_const_reference {
+ typedef T const &type;
+};
+
+template<typename T>
+struct add_const_reference<T&> {
+ typedef T &type;
+};
+
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+template<typename T>
+class reference_wrapper {
+ T *ptr;
+
+public:
+ reference_wrapper(T& t) : ptr(&t) { }
+ operator T&() const { return *ptr; }
+};
+
+template<typename T> reference_wrapper<T> ref(T& t) {
+ return reference_wrapper<T>(t);
+}
+template<typename T> reference_wrapper<const T> cref(const T& t) {
+ return reference_wrapper<const T>(t);
+}
+
+template<typename... Values> class tuple;
+
+// Basis case: zero-length tuple
+template<> class tuple<> { };
+
+template<typename Head, typename... Tail>
+class tuple<Head, Tail...> : private tuple<Tail...> {
+ typedef tuple<Tail...> inherited;
+
+public:
+ tuple() { }
+ // implicit copy-constructor is okay
+
+ // Construct tuple from separate arguments.
+ tuple(typename add_const_reference<Head>::type v,
+ typename add_const_reference<Tail>::type... vtail)
+ : m_head(v), inherited(vtail...) { }
+
+ // Construct tuple from another tuple.
+ template<typename... VValues> tuple(const tuple<VValues...>& other)
+ : m_head(other.head()), inherited(other.tail()) { }
+
+ template<typename... VValues> tuple&
+ operator=(const tuple<VValues...>& other) {
+ m_head = other.head();
+ tail() = other.tail();
+ return *this;
+ }
+
+ typename add_reference<Head>::type head() { return m_head; }
+ typename add_reference<const Head>::type head() const { return m_head; }
+ inherited& tail() { return *this; }
+ const inherited& tail() const { return *this; }
+
+protected:
+ Head m_head;
+};
+
+void test_tuple() {
+ tuple<> t0a;
+ tuple<> t0b(t0a);
+ t0a = t0b;
+
+ tuple<int> t1a;
+ tuple<int> t1b(17);
+ tuple<int> t1c(t1b);
+ t1a = t1b;
+
+ tuple<float> t1d(3.14159);
+ tuple<float> t1e(t1d);
+ t1d = t1e;
+
+ int i;
+ float f;
+ double d;
+ tuple<int*, float*, double*> t3a(&i, &f, &d);
+}
+
+// Creation functions
+template<typename T>
+struct make_tuple_result {
+ typedef T type;
+};
+
+template<typename T>
+struct make_tuple_result<reference_wrapper<T> > {
+ typedef T& type;
+};
+
+template<typename... Values>
+tuple<typename make_tuple_result<Values>::type...>
+make_tuple(const Values&... values) {
+ return tuple<typename make_tuple_result<Values>::type...>(values...);
+}
+
+template<typename... Values>
+tuple<Values&...> tie(Values&... values) {
+ return tuple<Values&...>(values...);
+}
+
+template<typename T> const T *addr(const T& ref) { return &ref; }
+void test_creation_functions() {
+ int i;
+ float f;
+ double d;
+ const tuple<int, float&, const double&> *t3p = addr(make_tuple(i, ref(f), cref(d)));
+ const tuple<int&, float&, double&> *t3q = addr(tie(i, f, d));
+}
+
+// Helper classes
+template<typename Tuple> struct tuple_size;
+
+template<typename... Values> struct tuple_size<tuple<Values...> > {
+ static const int value = sizeof...(Values);
+};
+
+int check_tuple_size_0[tuple_size<tuple<> >::value == 0? 1 : -1];
+int check_tuple_size_1[tuple_size<tuple<int>>::value == 1? 1 : -1];
+int check_tuple_size_2[tuple_size<tuple<float, double>>::value == 2? 1 : -1];
+int check_tuple_size_3[tuple_size<tuple<char, unsigned char, signed char>>::value == 3? 1 : -1];
+
+template<int I, typename Tuple> struct tuple_element;
+
+template<int I, typename Head, typename... Tail>
+struct tuple_element<I, tuple<Head, Tail...> > {
+ typedef typename tuple_element<I-1, tuple<Tail...> >::type type;
+};
+
+template<typename Head, typename... Tail>
+struct tuple_element<0, tuple<Head, Tail...> > {
+ typedef Head type;
+};
+
+int check_tuple_element_0[is_same<tuple_element<0, tuple<int&, float, double>>::type,
+ int&>::value? 1 : -1];
+
+int check_tuple_element_1[is_same<tuple_element<1, tuple<int&, float, double>>::type,
+ float>::value? 1 : -1];
+
+int check_tuple_element_2[is_same<tuple_element<2, tuple<int&, float, double>>::type,
+ double>::value? 1 : -1];
+
+// Element access
+template<int I, typename Tuple> class get_impl;
+template<int I, typename Head, typename... Values>
+class get_impl<I, tuple<Head, Values...> > {
+ typedef typename tuple_element<I-1, tuple<Values...> >::type Element;
+ typedef typename add_reference<Element>::type RJ;
+ typedef typename add_const_reference<Element>::type PJ;
+ typedef get_impl<I-1, tuple<Values...> > Next;
+public:
+ static RJ get(tuple<Head, Values...>& t) { return Next::get(t.tail()); }
+ static PJ get(const tuple<Head, Values...>& t) { return Next::get(t.tail()); }
+};
+
+template<typename Head, typename... Values>
+class get_impl<0, tuple<Head, Values...> > {
+ typedef typename add_reference<Head>::type RJ;
+ typedef typename add_const_reference<Head>::type PJ;
+public:
+ static RJ get(tuple<Head, Values...>& t) { return t.head(); }
+ static PJ get(const tuple<Head, Values...>& t) { return t.head(); }
+};
+
+template<int I, typename... Values> typename add_reference<
+typename tuple_element<I, tuple<Values...> >::type >::type
+get(tuple<Values...>& t) {
+ return get_impl<I, tuple<Values...> >::get(t);
+}
+
+template<int I, typename... Values> typename add_const_reference<
+typename tuple_element<I, tuple<Values...> >::type >::type
+get(const tuple<Values...>& t) {
+ return get_impl<I, tuple<Values...> >::get(t);
+}
+
+void test_element_access(tuple<int*, float*, double*&> t3) {
+ int i;
+ float f;
+ double d;
+ get<0>(t3) = &i;
+ get<1>(t3) = &f;
+ get<2>(t3) = &d;
+}
+
+// Relational operators
+inline bool operator==(const tuple<>&, const tuple<>&) { return true; }
+
+template<typename T, typename... TTail, typename U, typename... UTail>
+bool operator==(const tuple<T, TTail...>& t, const tuple<U, UTail...>& u) {
+ return t.head() == u.head() && t.tail() == u.tail();
+}
+
+template<typename... TValues, typename... UValues>
+bool operator!=(const tuple<TValues...>& t, const tuple<UValues...>& u) {
+ return !(t == u);
+}
+
+inline bool operator<(const tuple<>&, const tuple<>&) { return false; }
+
+template<typename T, typename... TTail, typename U, typename... UTail>
+bool operator<(const tuple<T, TTail...>& t, const tuple<U, UTail...>& u) {
+ return (t.head() < u.head() || (!(t.head() < u.head()) && t.tail() < u.tail()));
+}
+
+template<typename... TValues, typename... UValues>
+bool operator>(const tuple<TValues...>& t, const tuple<UValues...>& u) {
+ return u < t;
+}
+
+template<typename... TValues, typename... UValues>
+bool operator<=(const tuple<TValues...>& t, const tuple<UValues...>& u) {
+ return !(u < t);
+}
+
+template<typename... TValues, typename... UValues>
+bool operator>=(const tuple<TValues...>& t, const tuple<UValues...>& u) {
+ return !(t < u);
+}
+
+void test_relational_operators(tuple<int*, float*, double*> t3) {
+ (void)(t3 == t3);
+ (void)(t3 != t3);
+ (void)(t3 < t3);
+ (void)(t3 <= t3);
+ (void)(t3 >= t3);
+ (void)(t3 > t3);
+};
diff --git a/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp b/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp
new file mode 100644
index 0000000..62cf429
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -std=c++0x -fblocks -fsyntax-only -verify %s
+
+// Tests the use of blocks with variadic templates.
+template<typename ...Args>
+int f0(Args ...args) {
+ return ^ {
+ return sizeof...(Args);
+ }() + ^ {
+ return sizeof...(args);
+ }();
+}
+
+template<typename ...Args>
+int f1(Args ...args) {
+ return ^ {
+ return f0(args...);
+ }();
+}
+
+template int f0(int, float, double);
+template int f1(const char*, int, float, double);
+
+template<typename ...Args>
+int f2(Args ...args) {
+ return ^(Args ...block_args) {
+ return f1(block_args...);
+ }(args + 0 ...);
+}
+
+template int f2(const char*, int, float, double);
+
+template<typename ...Args>
+int f3(Args ...args) {
+ return ^(Args *...block_args) {
+ return f1(block_args...);
+ }(&args...);
+}
+
+template int f3(const char*, int, float, double);
diff --git a/test/CXX/temp/temp.decls/temp.variadic/injected-class-name.cpp b/test/CXX/temp/temp.decls/temp.variadic/injected-class-name.cpp
new file mode 100644
index 0000000..a76ef80
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/injected-class-name.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Check for declaration matching with out-of-line declarations and
+// variadic templates, which involves proper computation of the
+// injected-class-name.
+template<typename T, typename ...Types>
+struct X0 {
+ typedef T type;
+
+ void f0(T);
+ type f1(T);
+};
+
+template<typename T, typename ...Types>
+void X0<T, Types...>::f0(T) { }
+
+template<typename T, typename ...Types>
+typename X0<T, Types...>::type X0<T, Types...>::f1(T) { }
+
+template<typename T, typename ...Types>
+struct X0<T, T, Types...> {
+ typedef T* result;
+ result f3();
+
+ template<typename... InnerTypes>
+ struct Inner;
+};
+
+template<typename T, typename ...Types>
+typename X0<T, T, Types...>::result X0<T, T, Types...>::f3() { return 0; }
+
+template<typename T, typename ...Types>
+template<typename ...InnerTypes>
+struct X0<T, T, Types...>::Inner {
+ template<typename ...ReallyInner> void f4();
+};
+
+template<typename T, typename ...Types>
+template<typename ...InnerTypes>
+template<typename ...ReallyInner>
+void X0<T, T, Types...>::Inner<InnerTypes...>::f4() { }
+
+namespace rdar8848837 {
+ // Out-of-line definitions that cause rebuilding in the current
+ // instantiation.
+ template<typename F> struct X;
+
+ template<typename R, typename ...ArgTypes>
+ struct X<R(ArgTypes...)> {
+ X<R(ArgTypes...)> f();
+ };
+
+ template<typename R, typename ...ArgTypes>
+ X<R(ArgTypes...)> X<R(ArgTypes...)>::f() { return *this; }
+
+
+ X<int(float, double)> xif;
+
+ template<unsigned> struct unsigned_c { };
+ template<typename ...ArgTypes> int g(ArgTypes...);
+
+ template<typename F> struct X1;
+
+ template<typename R, typename ...ArgTypes>
+ struct X1<R(ArgTypes...)> {
+ unsigned_c<sizeof(1 + g(ArgTypes()...))> f();
+ };
+
+ template<typename R, typename ...ArgTypes>
+ unsigned_c<sizeof(1 + g(ArgTypes()...))> X1<R(ArgTypes...)>::f() {
+ return unsigned_c<sizeof(int)>();
+ }
+
+ X1<int(float, double)> xif2;
+}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp b/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp
new file mode 100644
index 0000000..d80182c
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp
@@ -0,0 +1,274 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// This is a collection of various template metafunctions involving
+// variadic templates, which are meant to exercise common use cases.
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+template<typename...> struct tuple { };
+template<int ...> struct int_tuple { };
+template<typename T, typename U> struct pair { };
+
+namespace Count {
+ template<typename Head, typename ...Tail>
+ struct count {
+ static const unsigned value = 1 + count<Tail...>::value;
+ };
+
+ template<typename T>
+ struct count<T> {
+ static const unsigned value = 1;
+ };
+
+ int check1[count<int>::value == 1? 1 : -1];
+ int check2[count<float, double>::value == 2? 1 : -1];
+ int check3[count<char, signed char, unsigned char>::value == 3? 1 : -1];
+}
+
+namespace CountWithPackExpansion {
+ template<typename ...> struct count;
+
+ template<typename Head, typename ...Tail>
+ struct count<Head, Tail...> {
+ static const unsigned value = 1 + count<Tail...>::value;
+ };
+
+ template<>
+ struct count<> {
+ static const unsigned value = 0;
+ };
+
+ int check0[count<>::value == 0? 1 : -1];
+ int check1[count<int>::value == 1? 1 : -1];
+ int check2[count<float, double>::value == 2? 1 : -1];
+ int check3[count<char, signed char, unsigned char>::value == 3? 1 : -1];
+}
+
+namespace Replace {
+ // Simple metafunction that replaces the template arguments of
+ // template template parameters with 'int'.
+ template<typename T>
+ struct EverythingToInt;
+
+ template<template<typename ...> class TT, typename T1, typename T2>
+ struct EverythingToInt<TT<T1, T2> > {
+ typedef TT<int, int> type;
+ };
+
+ int check0[is_same<EverythingToInt<tuple<double, float>>::type,
+ tuple<int, int>>::value? 1 : -1];
+}
+
+namespace Math {
+ template<int ...Values>
+ struct double_values {
+ typedef int_tuple<Values*2 ...> type;
+ };
+
+ int check0[is_same<double_values<1, 2, -3>::type,
+ int_tuple<2, 4, -6>>::value? 1 : -1];
+
+ template<int ...Values>
+ struct square {
+ typedef int_tuple<(Values*Values)...> type;
+ };
+
+ int check1[is_same<square<1, 2, -3>::type,
+ int_tuple<1, 4, 9>>::value? 1 : -1];
+
+ template<typename IntTuple> struct square_tuple;
+
+ template<int ...Values>
+ struct square_tuple<int_tuple<Values...>> {
+ typedef int_tuple<(Values*Values)...> type;
+ };
+
+ int check2[is_same<square_tuple<int_tuple<1, 2, -3> >::type,
+ int_tuple<1, 4, 9>>::value? 1 : -1];
+
+ template<int ...Values> struct sum;
+
+ template<int First, int ...Rest>
+ struct sum<First, Rest...> {
+ static const int value = First + sum<Rest...>::value;
+ };
+
+ template<>
+ struct sum<> {
+ static const int value = 0;
+ };
+
+ int check3[sum<1, 2, 3, 4, 5>::value == 15? 1 : -1];
+
+ template<int ... Values>
+ struct lazy_sum {
+ int operator()() {
+ return sum<Values...>::value;
+ }
+ };
+
+ void f() {
+ lazy_sum<1, 2, 3, 4, 5>()();
+ }
+}
+
+namespace ListMath {
+ template<typename T, T ... V> struct add;
+
+ template<typename T, T i, T ... V>
+ struct add<T, i, V...> {
+ static const T value = i + add<T, V...>::value;
+ };
+
+ template<typename T>
+ struct add<T> {
+ static const T value = T();
+ };
+
+ template<typename T, T ... V>
+ struct List {
+ struct sum {
+ static const T value = add<T, V...>::value;
+ };
+ };
+
+ template<int ... V>
+ struct ListI : public List<int, V...> {
+ };
+
+ int check0[ListI<1, 2, 3>::sum::value == 6? 1 : -1];
+}
+
+namespace Indices {
+ template<unsigned I, unsigned N, typename IntTuple>
+ struct build_indices_impl;
+
+ template<unsigned I, unsigned N, int ...Indices>
+ struct build_indices_impl<I, N, int_tuple<Indices...> >
+ : build_indices_impl<I+1, N, int_tuple<Indices..., I> > {
+ };
+
+ template<unsigned N, int ...Indices>
+ struct build_indices_impl<N, N, int_tuple<Indices...> > {
+ typedef int_tuple<Indices...> type;
+ };
+
+ template<unsigned N>
+ struct build_indices : build_indices_impl<0, N, int_tuple<> > { };
+
+ int check0[is_same<build_indices<5>::type,
+ int_tuple<0, 1, 2, 3, 4>>::value? 1 : -1];
+}
+
+namespace TemplateTemplateApply {
+ template<typename T, template<class> class ...Meta>
+ struct apply_each {
+ typedef tuple<typename Meta<T>::type...> type;
+ };
+
+ template<typename T>
+ struct add_reference {
+ typedef T& type;
+ };
+
+ template<typename T>
+ struct add_pointer {
+ typedef T* type;
+ };
+
+ template<typename T>
+ struct add_const {
+ typedef const T type;
+ };
+
+ int check0[is_same<apply_each<int,
+ add_reference, add_pointer, add_const>::type,
+ tuple<int&, int*, int const>>::value? 1 : -1];
+
+ template<typename T, template<class> class ...Meta>
+ struct apply_each_indirect {
+ typedef typename apply_each<T, Meta...>::type type;
+ };
+
+ int check1[is_same<apply_each_indirect<int, add_reference, add_pointer,
+ add_const>::type,
+ tuple<int&, int*, int const>>::value? 1 : -1];
+
+ template<typename T, typename ...Meta>
+ struct apply_each_nested {
+ typedef typename apply_each<T, Meta::template apply...>::type type;
+ };
+
+ struct add_reference_meta {
+ template<typename T>
+ struct apply {
+ typedef T& type;
+ };
+ };
+
+ struct add_pointer_meta {
+ template<typename T>
+ struct apply {
+ typedef T* type;
+ };
+ };
+
+ struct add_const_meta {
+ template<typename T>
+ struct apply {
+ typedef const T type;
+ };
+ };
+
+ int check2[is_same<apply_each_nested<int, add_reference_meta,
+ add_pointer_meta, add_const_meta>::type,
+ tuple<int&, int*, int const>>::value? 1 : -1];
+
+}
+
+namespace FunctionTypes {
+ template<typename FunctionType>
+ struct Arity;
+
+ template<typename R, typename ...Types>
+ struct Arity<R(Types...)> {
+ static const unsigned value = sizeof...(Types);
+ };
+
+ template<typename R, typename ...Types>
+ struct Arity<R(Types......)> {
+ static const unsigned value = sizeof...(Types);
+ };
+
+ template<typename R, typename T1, typename T2, typename T3, typename T4>
+ struct Arity<R(T1, T2, T3, T4)>; // expected-note{{template is declared here}}
+
+ int check0[Arity<int()>::value == 0? 1 : -1];
+ int check1[Arity<int(float, double)>::value == 2? 1 : -1];
+ int check2[Arity<int(float...)>::value == 1? 1 : -1];
+ int check3[Arity<int(float, double, long double...)>::value == 3? 1 : -1];
+ Arity<int(float, double, long double, char)> check4; // expected-error{{implicit instantiation of undefined template 'FunctionTypes::Arity<int (float, double, long double, char)>'}}
+}
+
+namespace SuperReplace {
+ template<typename T>
+ struct replace_with_int {
+ typedef int type;
+ };
+
+ template<template<typename ...> class TT, typename ...Types>
+ struct replace_with_int<TT<Types...>> {
+ typedef TT<typename replace_with_int<Types>::type...> type;
+ };
+
+ int check0[is_same<replace_with_int<pair<tuple<float, double, short>,
+ pair<char, unsigned char>>>::type,
+ pair<tuple<int, int, int>, pair<int, int>>>::value? 1 : -1];
+}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
new file mode 100644
index 0000000..2df6d33
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
@@ -0,0 +1,218 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<typename T, T ...Values> struct value_tuple {};
+template<typename...> struct tuple { };
+template<typename T, typename U> struct pair { };
+
+template<typename T, T Value> struct value_c;
+
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+template<typename T>
+struct X0 {
+ template<T ...Values>
+ void f(value_tuple<T, Values...> * = 0);
+};
+
+void test_X0() {
+ X0<int>().f<1, 2, 3, 4, 5>();
+}
+
+namespace PacksAtDifferentLevels {
+
+ template<typename ...Types>
+ struct X {
+ template<typename> struct Inner {
+ static const unsigned value = 1;
+ };
+
+ template<typename ...YTypes>
+ struct Inner<tuple<pair<Types, YTypes>...> > {
+ static const unsigned value = sizeof...(Types) - sizeof...(YTypes);
+ };
+ };
+
+ int check0[X<short, int, long>::Inner<tuple<pair<short, unsigned short>,
+ pair<int, unsigned int>,
+ pair<long, unsigned long>>
+ >::value == 0? 1 : -1];
+
+ int check1[X<short, int>::Inner<tuple<pair<short, unsigned short>,
+ pair<int, unsigned int>,
+ pair<long, unsigned long>>
+ >::value == 1? 1 : -1];
+
+ template<unsigned ...Values> struct unsigned_tuple { };
+ template<typename ...Types>
+ struct X1 {
+ template<typename, typename> struct Inner {
+ static const unsigned value = 0;
+ };
+
+ template<typename ...YTypes>
+ struct Inner<tuple<pair<Types, YTypes>...>,
+ unsigned_tuple<sizeof(Types) + sizeof(YTypes)...>> {
+ static const unsigned value = 1;
+ };
+ };
+
+ int check2[X1<short, int, long>::Inner<tuple<pair<short, unsigned short>,
+ pair<int, unsigned int>,
+ pair<long, unsigned long>>,
+ unsigned_tuple<sizeof(short) + sizeof(unsigned short),
+ sizeof(int) + sizeof(unsigned int),
+ sizeof(long) + sizeof(unsigned long)>
+ >::value == 1? 1 : -1];
+ int check3[X1<short, int>::Inner<tuple<pair<short, unsigned short>,
+ pair<int, unsigned int>,
+ pair<long, unsigned long>>,
+ unsigned_tuple<sizeof(short) + sizeof(unsigned short),
+ sizeof(int) + sizeof(unsigned int),
+ sizeof(long) + sizeof(unsigned long)>
+ >::value == 0? 1 : -1];
+
+ template<typename ...Types>
+ struct X2 {
+ template<typename> struct Inner {
+ static const unsigned value = 1;
+ };
+
+ template<typename R, typename ...YTypes>
+ struct Inner<R(pair<Types, YTypes>...)> {
+ static const unsigned value = sizeof...(Types) - sizeof...(YTypes);
+ };
+ };
+
+ int check4[X2<short, int, long>::Inner<int(pair<short, unsigned short>,
+ pair<int, unsigned int>,
+ pair<long, unsigned long>)
+ >::value == 0? 1 : -1];
+
+ int check5[X2<short, int>::Inner<int(pair<short, unsigned short>,
+ pair<int, unsigned int>,
+ pair<long, unsigned long>)
+ >::value == 1? 1 : -1];
+
+ template<typename T, typename U>
+ struct some_function_object {
+ template<typename>
+ struct result_of;
+ };
+
+ template<template<class> class...> struct metafun_tuple { };
+
+ template<typename ...Types1>
+ struct X3 {
+ template<typename, typename> struct Inner {
+ static const unsigned value = 0;
+ };
+
+ template<typename ...Types2>
+ struct Inner<tuple<pair<Types1, Types2>...>,
+ metafun_tuple<some_function_object<Types1, Types2>::template result_of...> > {
+ static const unsigned value = 1;
+ };
+ };
+
+ int check6[X3<short, int, long>::Inner<tuple<pair<short, unsigned short>,
+ pair<int, unsigned int>,
+ pair<long, unsigned long>>,
+ metafun_tuple<
+ some_function_object<short, unsigned short>::result_of,
+ some_function_object<int, unsigned int>::result_of,
+ some_function_object<long, unsigned long>::result_of>
+ >::value == 1? 1 : -1];
+ int check7[X3<short, int>::Inner<tuple<pair<short, unsigned short>,
+ pair<int, unsigned int>,
+ pair<long, unsigned long>>,
+ metafun_tuple<
+ some_function_object<short, unsigned short>::result_of,
+ some_function_object<int, unsigned int>::result_of,
+ some_function_object<long, unsigned long>::result_of>
+ >::value == 0? 1 : -1];
+
+ template<unsigned I, unsigned J> struct unsigned_pair { };
+
+ template<unsigned ...Values1>
+ struct X4 {
+ template<typename> struct Inner {
+ static const unsigned value = 0;
+ };
+
+ template<unsigned ...Values2>
+ struct Inner<tuple<unsigned_pair<Values1, Values2>...>> {
+ static const unsigned value = 1;
+ };
+ };
+
+ int check8[X4<1, 3, 5>::Inner<tuple<unsigned_pair<1, 2>,
+ unsigned_pair<3, 4>,
+ unsigned_pair<5, 6>>
+ >::value == 1? 1 : -1];
+ int check9[X4<1, 3>::Inner<tuple<unsigned_pair<1, 2>,
+ unsigned_pair<3, 4>,
+ unsigned_pair<5, 6>>
+ >::value == 0? 1 : -1];
+
+ template<class> struct add_reference;
+ template<class> struct add_pointer;
+ template<class> struct add_const;
+
+ template<template<class> class ...Templates>
+ struct X5 {
+ template<typename> struct Inner {
+ static const unsigned value = 0;
+ };
+
+ template<typename ...Types>
+ struct Inner<tuple<Templates<Types>...>> {
+ static const unsigned value = 1;
+ };
+ };
+
+ int check10[X5<add_reference, add_pointer, add_const>
+ ::Inner<tuple<add_reference<int>,
+ add_pointer<float>,
+ add_const<double>>>::value == 1? 1 : -1];
+ int check11[X5<add_reference, add_pointer>
+ ::Inner<tuple<add_reference<int>,
+ add_pointer<float>,
+ add_const<double>>>::value == 0? 1 : -1];
+
+}
+
+namespace ExpandingNonTypeTemplateParameters {
+ template<typename ...Types>
+ struct tuple_of_values {
+ template<Types ...Values> // expected-error{{a non-type template parameter cannot have type 'float'}} \
+ // expected-note{{template parameter is declared here}}
+ struct apply { // expected-note 2{{template is declared here}}
+ typedef tuple<value_c<Types, Values>...> type;
+ };
+ };
+
+ int i;
+ float f;
+ int check_tuple_of_values_1[
+ is_same<tuple_of_values<int&, float&, char, int>::apply<i, f, 'a', 17>
+ ::type,
+ tuple<value_c<int&, i>, value_c<float&, f>, value_c<char, 'a'>,
+ value_c<int, 17>>
+ >::value? 1 : -1];
+
+ tuple_of_values<int, float> tv1; // expected-note{{in instantiation of template class 'ExpandingNonTypeTemplateParameters::tuple_of_values<int, float>' requested here}}
+
+ tuple_of_values<int&, float&>::apply<i, i>::type tv2; // expected-error{{non-type template parameter of reference type 'float &' cannot bind to template argument of type 'int'}}
+
+ tuple_of_values<int&, float&>::apply<i>::type tv3; // expected-error{{too few template arguments for class template 'apply'}}
+
+ tuple_of_values<int&, float&>::apply<i, f, i>::type tv4; // expected-error{{too many template arguments for class template 'apply'}}
+}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p1.cpp b/test/CXX/temp/temp.decls/temp.variadic/p1.cpp
new file mode 100644
index 0000000..02f4c59
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/p1.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<class ...Types> struct Tuple;
+
+Tuple<> *t0;
+Tuple<int> *t1;
+Tuple<int, char> *t2a;
+Tuple<int, float> *t2b = t2a; // expected-error{{cannot initialize a variable of type 'Tuple<int, float> *' with an lvalue of type 'Tuple<int, char> *'}}
+Tuple<int, float, double> *t3;
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p2.cpp b/test/CXX/temp/temp.decls/temp.variadic/p2.cpp
new file mode 100644
index 0000000..100ae2c
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/p2.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<class ... Types> void f(Types ... args);
+
+void test() {
+ f();
+ f(1);
+ f(2, 1.0);
+}
+
+// Test simple recursive variadic function template
+template<typename Head, typename ...Tail>
+void recurse_until_fail(const Head &, const Tail &...tail) { // expected-note{{candidate function template not viable: requires at least 1 argument, but 0 were provided}}
+ recurse_until_fail(tail...); // expected-error{{no matching function for call to 'recurse_until_fail'}} \
+ // expected-note{{in instantiation of function template specialization 'recurse_until_fail<char [7], >' requested here}} \
+ // expected-note{{in instantiation of function template specialization 'recurse_until_fail<double, char [7]>' requested here}}
+}
+
+void test_recurse_until_fail() {
+ recurse_until_fail(1, 3.14159, "string"); // expected-note{{in instantiation of function template specialization 'recurse_until_fail<int, double, char [7]>' requested here}}
+
+}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p4.cpp b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
new file mode 100644
index 0000000..e2fa122
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
@@ -0,0 +1,135 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -fexceptions -verify %s
+
+template<typename... Types> struct tuple;
+template<int I> struct int_c;
+
+template<typename T>
+struct identity {
+ typedef T type;
+};
+
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+// FIXME: Several more bullets to go
+
+// In an initializer-list (8.5); the pattern is an initializer-clause.
+// Note: this also covers expression-lists, since expression-list is
+// just defined as initializer-list.
+void five_args(int, int, int, int, int); // expected-note{{candidate function not viable: requires 5 arguments, but 6 were provided}}
+
+template<int ...Values>
+void initializer_list_expansion() {
+ int values[5] = { Values... }; // expected-error{{excess elements in array initializer}}
+ five_args(Values...); // expected-error{{no matching function for call to 'five_args'}}
+}
+
+template void initializer_list_expansion<1, 2, 3, 4, 5>();
+template void initializer_list_expansion<1, 2, 3, 4, 5, 6>(); // expected-note{{in instantiation of function template specialization 'initializer_list_expansion<1, 2, 3, 4, 5, 6>' requested here}}
+
+namespace PR8977 {
+ struct A { };
+ template<typename T, typename... Args> void f(Args... args) {
+ T t(args...);
+ };
+
+ template void f<A>();
+}
+
+// In a base-specifier-list (Clause 10); the pattern is a base-specifier.
+template<typename ...Mixins>
+struct HasMixins : public Mixins... {
+ HasMixins();
+ HasMixins(const HasMixins&);
+ HasMixins(int i);
+};
+
+struct A { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int' to 'const A' for 1st argument}} \
+// expected-note{{candidate constructor (the implicit default constructor) not viable: requires 0 arguments, but 1 was provided}}
+struct B { };
+struct C { };
+struct D { };
+
+A *checkA = new HasMixins<A, B, C, D>;
+B *checkB = new HasMixins<A, B, C, D>;
+D *checkD = new HasMixins<A, B, C, D>;
+C *checkC = new HasMixins<A, B, D>; // expected-error{{cannot initialize a variable of type 'C *' with an rvalue of type 'HasMixins<A, B, D> *'}}
+HasMixins<> *checkNone = new HasMixins<>;
+
+template<typename Mixins>
+struct BrokenMixins : public Mixins... { }; // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
+
+// In a mem-initializer-list (12.6.2); the pattern is a mem-initializer.
+template<typename ...Mixins>
+HasMixins<Mixins...>::HasMixins(): Mixins()... { }
+
+template<typename ...Mixins>
+HasMixins<Mixins...>::HasMixins(const HasMixins &other): Mixins(other)... { }
+
+template<typename ...Mixins>
+HasMixins<Mixins...>::HasMixins(int i): Mixins(i)... { } // expected-error{{no matching constructor for initialization of 'A'}}
+
+void test_has_mixins() {
+ HasMixins<A, B> ab;
+ HasMixins<A, B> ab2 = ab;
+ HasMixins<A, B> ab3(17); // expected-note{{in instantiation of member function 'HasMixins<A, B>::HasMixins' requested here}}
+}
+
+template<typename T>
+struct X {
+ T member;
+
+ X() : member()... { } // expected-error{{pack expansion for initialization of member 'member'}}
+};
+
+// In a template-argument-list (14.3); the pattern is a template-argument.
+template<typename ...Types>
+struct tuple_of_refs {
+ typedef tuple<Types& ...> types;
+};
+
+tuple<int&, float&> *t_int_ref_float_ref;
+tuple_of_refs<int&, float&>::types *t_int_ref_float_ref_2 = t_int_ref_float_ref;
+
+template<typename ...Types>
+struct extract_nested_types {
+ typedef tuple<typename Types::type...> types;
+};
+
+tuple<int, float> *t_int_float;
+extract_nested_types<identity<int>, identity<float> >::types *t_int_float_2
+ = t_int_float;
+
+template<int ...N>
+struct tuple_of_ints {
+ typedef tuple<int_c<N>...> type;
+};
+
+int check_temp_arg_1[is_same<tuple_of_ints<1, 2, 3, 4, 5>::type,
+ tuple<int_c<1>, int_c<2>, int_c<3>, int_c<4>,
+ int_c<5>>>::value? 1 : -1];
+
+// In a dynamic-exception-specification (15.4); the pattern is a type-id.
+template<typename ...Types>
+struct f_with_except {
+ virtual void f() throw(Types...); // expected-note{{overridden virtual function is here}}
+};
+
+struct check_f_with_except_1 : f_with_except<int, float> {
+ virtual void f() throw(int, float);
+};
+
+struct check_f_with_except_2 : f_with_except<int, float> {
+ virtual void f() throw(int);
+};
+
+struct check_f_with_except_3 : f_with_except<int, float> {
+ virtual void f() throw(int, float, double); // expected-error{{exception specification of overriding function is more lax than base version}}
+};
diff --git a/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
new file mode 100644
index 0000000..1acc21e
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
@@ -0,0 +1,393 @@
+// RUN: %clang_cc1 -fexceptions -std=c++0x -fblocks -fms-extensions -fsyntax-only -verify %s
+
+template<typename T, typename U> struct pair;
+template<typename ...> struct tuple;
+
+// A parameter pack whose name appears within the pattern of a pack
+// expansion is expanded by that pack expansion. An appearance of the
+// name of a parameter pack is only expanded by the innermost
+// enclosing pack expansion. The pattern of a pack expansion shall
+// name one or more parameter packs that are not expanded by a nested
+// pack expansion.
+template<typename... Types>
+struct Expansion {
+ typedef pair<Types..., int> expand_with_pacs; // okay
+ typedef pair<Types, int...> expand_no_packs; // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
+ typedef pair<pair<Types..., int>..., int> expand_with_expanded_nested; // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
+};
+
+// All of the parameter packs expanded by a pack expansion shall have
+// the same number of arguments specified.
+template<typename ...Types>
+struct ExpansionLengthMismatch {
+ template<typename ...OtherTypes>
+ struct Inner {
+ typedef tuple<pair<Types, OtherTypes>...> type; // expected-error{{pack expansion contains parameter packs 'Types' and 'OtherTypes' that have different lengths (3 vs. 2)}}
+ };
+};
+
+ExpansionLengthMismatch<int, long>::Inner<unsigned int, unsigned long>::type
+ *il_pairs;
+tuple<pair<int, unsigned int>, pair<long, unsigned long> >*il_pairs_2 = il_pairs;
+
+ExpansionLengthMismatch<short, int, long>::Inner<unsigned int, unsigned long>::type // expected-note{{in instantiation of template class 'ExpansionLengthMismatch<short, int, long>::Inner<unsigned int, unsigned long>' requested here}}
+ *il_pairs_bad;
+
+
+// An appearance of a name of a parameter pack that is not expanded is
+// ill-formed.
+
+// Test for unexpanded parameter packs in each of the type nodes.
+template<typename T, int N, typename ... Types>
+struct TestPPName
+ : public Types, public T // expected-error{{base type contains unexpanded parameter pack 'Types'}}
+{
+ // BuiltinType is uninteresting
+ // FIXME: ComplexType is uninteresting?
+ // PointerType
+ typedef Types *types_pointer; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // BlockPointerType
+ typedef Types (^block_pointer_1)(int); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ typedef int (^block_pointer_2)(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // LValueReferenceType
+ typedef Types &lvalue_ref; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // RValueReferenceType
+ typedef Types &&rvalue_ref; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // MemberPointerType
+ typedef Types TestPPName::* member_pointer_1; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ typedef int Types::*member_pointer_2; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // ConstantArrayType
+ typedef Types constant_array[17]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // IncompleteArrayType
+ typedef Types incomplete_array[]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // VariableArrayType
+ void f(int i) {
+ Types variable_array[i]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ }
+
+ // DependentSizedArrayType
+ typedef Types dependent_sized_array[N]; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // DependentSizedExtVectorType
+ typedef Types dependent_sized_ext_vector __attribute__((ext_vector_type(N))); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // VectorType is uninteresting
+
+ // ExtVectorType
+ typedef Types ext_vector __attribute__((ext_vector_type(4))); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // FunctionProtoType
+ typedef Types (function_type_1)(int); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ typedef int (function_type_2)(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // FunctionNoProtoType is uninteresting
+ // UnresolvedUsingType is uninteresting
+ // ParenType is uninteresting
+ // TypedefType is uninteresting
+
+ // TypeOfExprType
+ typedef __typeof__((static_cast<Types>(0))) typeof_expr; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // TypeOfType
+ typedef __typeof__(Types) typeof_type; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // DecltypeType
+ typedef decltype((static_cast<Types>(0))) typeof_expr; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // RecordType is uninteresting
+ // EnumType is uninteresting
+ // ElaboratedType is uninteresting
+
+ // TemplateTypeParmType
+ typedef Types template_type_parm; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // SubstTemplateTypeParmType is uninteresting
+
+ // TemplateSpecializationType
+ typedef pair<Types, int> template_specialization; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // InjectedClassName is uninteresting.
+
+ // DependentNameType
+ typedef typename Types::type dependent_name; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // DependentTemplateSpecializationType
+ typedef typename Types::template apply<int> dependent_name_1; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ typedef typename T::template apply<Types> dependent_name_2; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+
+ // ObjCObjectType is uninteresting
+ // ObjCInterfaceType is uninteresting
+ // ObjCObjectPointerType is uninteresting
+};
+
+// FIXME: Test for unexpanded parameter packs in each of the expression nodes.
+template<int ...Values>
+void test_unexpanded_in_exprs() {
+ // PredefinedExpr is uninteresting
+ // DeclRefExpr
+ Values; // expected-error{{expression contains unexpanded parameter pack 'Values'}}
+ // IntegerLiteral is uninteresting
+ // FloatingLiteral is uninteresting
+ // ImaginaryLiteral is uninteresting
+ // StringLiteral is uninteresting
+ // CharacterLiteral is uninteresting
+ (Values); // expected-error{{expression contains unexpanded parameter pack 'Values'}}
+ // UnaryOperator
+ -Values; // expected-error{{expression contains unexpanded parameter pack 'Values'}}
+ // OffsetOfExpr
+ struct OffsetMe {
+ int array[17];
+ };
+ __builtin_offsetof(OffsetMe, array[Values]); // expected-error{{expression contains unexpanded parameter pack 'Values'}}
+ // FIXME: continue this...
+}
+
+template<typename ... Types>
+void TestPPNameFunc(int i) {
+ f(static_cast<Types>(i)); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+}
+
+template<typename T, template<class> class ...Meta>
+struct TestUnexpandedTTP {
+ typedef tuple<typename Meta<T>::type> type; // expected-error{{declaration type contains unexpanded parameter pack 'Meta'}}
+};
+
+// Test for unexpanded parameter packs in declarations.
+// FIXME: Attributes?
+template<typename T, typename... Types>
+struct TestUnexpandedDecls : T{
+ void member_function(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ void member_function () throw(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ operator Types() const; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ Types data_member; // expected-error{{data member type contains unexpanded parameter pack 'Types'}}
+ static Types static_data_member; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ unsigned bit_field : static_cast<Types>(0); // expected-error{{bit-field size contains unexpanded parameter pack 'Types'}}
+ static_assert(static_cast<Types>(0), "Boom"); // expected-error{{static assertion contains unexpanded parameter pack 'Types'}}
+
+ enum E0 : Types { // expected-error{{fixed underlying type contains unexpanded parameter pack 'Types'}}
+ EnumValue = static_cast<Types>(0) // expected-error{{enumerator value contains unexpanded parameter pack 'Types'}}
+ };
+
+ using typename Types::type; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}
+ using Types::value; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}
+ using T::operator Types; // expected-error{{using declaration contains unexpanded parameter pack 'Types'}}
+
+ friend class Types::foo; // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}}
+ friend void friend_func(Types); // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}}
+ friend void Types::other_friend_func(int); // expected-error{{friend declaration contains unexpanded parameter pack 'Types'}}
+
+ void test_initializers() {
+ T copy_init = static_cast<Types>(0); // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
+ T direct_init(0, static_cast<Types>(0)); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+ T list_init = { static_cast<Types>(0) }; // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
+ }
+
+ void default_function_args(T = static_cast<Types>(0)); // expected-error{{default argument contains unexpanded parameter pack 'Types'}}
+
+ template<typename = Types*> // expected-error{{default argument contains unexpanded parameter pack 'Types'}}
+ struct default_template_args_1;
+ template<int = static_cast<Types>(0)> // expected-error{{default argument contains unexpanded parameter pack 'Types'}}
+ struct default_template_args_2;
+ template<template<typename> class = Types::template apply> // expected-error{{default argument contains unexpanded parameter pack 'Types'}}
+ struct default_template_args_3;
+
+ template<Types value> // expected-error{{non-type template parameter type contains unexpanded parameter pack 'Types'}}
+ struct non_type_template_param_type;
+
+ void decls_in_stmts() {
+ Types t; // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ for (Types *t = 0; ; ) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ for (; Types *t = 0; ) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ switch(Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ while(Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ if (Types *t = 0) { } // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ try {
+ } catch (Types*) { // expected-error{{exception type contains unexpanded parameter pack 'Types'}}
+ }
+ }
+};
+
+// FIXME: Test for unexpanded parameter packs in each of the statements.
+struct X {
+ void f(int, int);
+ template<typename ...Types>
+ void f(Types...);
+};
+
+namespace std {
+ class type_info;
+}
+
+typedef struct _GUID {
+ unsigned long Data1;
+ unsigned short Data2;
+ unsigned short Data3;
+ unsigned char Data4[ 8 ];
+} GUID;
+
+template<typename T, typename ...Types>
+void test_unexpanded_exprs(Types ...values) {
+ // CXXOperatorCallExpr
+ (void)(values + 0); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+ (void)(0 + values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ // CXXMemberCallExpr
+ values.f(); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+ X x;
+ x.f(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+ x.Types::f(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+ x.f<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+
+ // CXXStaticCastExpr
+ (void)static_cast<Types&>(values); // expected-error{{expression contains unexpanded parameter packs 'Types' and 'values'}}
+
+ // CXXDynamicCastExpr
+ (void)dynamic_cast<Types&>(values); // expected-error{{expression contains unexpanded parameter packs 'Types' and 'values'}}
+
+ // CXXReinterpretCastExpr
+ (void)reinterpret_cast<Types&>(values); // expected-error{{expression contains unexpanded parameter packs 'Types' and 'values'}}
+
+ // CXXConstCastExpr
+ (void)const_cast<Types&>(values); // expected-error{{expression contains unexpanded parameter packs 'Types' and 'values'}}
+
+ // CXXTypeidExpr
+ (void)typeid(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+ (void)typeid(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ // CXXUuidofExpr
+ (void)__uuidof(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+ (void)__uuidof(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ // CXXThisExpr is uninteresting
+
+ // CXXThrowExpr
+ throw Types(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+ throw values; // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ // CXXDefaultArgExpr is uninteresting
+
+ // CXXBindTemporaryExpr is uninteresting
+
+ // CXXConstructExpr is uninteresting
+
+ // CXXFunctionalCastExpr
+ (void)Types(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+
+ // CXXTemporaryObjectExpr
+ (void)X(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ // CXXScalarValueInitExpr is uninteresting
+
+ // CXXNewExpr
+ (void)new Types; // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+ (void)new X(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+ (void)new (values) X(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+ (void)new X [values]; // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ // CXXDeleteExpr
+ delete values; // expected-error{{expression contains unexpanded parameter pack 'values'}}
+ delete [] values; // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ // CXXPseudoDestructorExpr
+ T t;
+ values.~T(); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+ t.~Types(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+ t.Types::~T(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+
+ // UnaryTypeTraitExpr
+ __is_pod(Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+
+ // BinaryTypeTraitExpr
+ __is_base_of(Types, T); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+ __is_base_of(T, Types); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+
+ // UnresolvedLookupExpr
+ test_unexpanded_exprs(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+ test_unexpanded_exprs<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+
+ // DependentScopeDeclRefExpr
+ Types::test_unexpanded_exprs(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+ T::template test_unexpanded_exprs<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+
+ // CXXUnresolvedConstructExpr
+ Types(5); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+
+ // CXXDependentScopeMemberExpr
+ values.foo(); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+ t.foo(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ // FIXME: There's an evil ambiguity here, because we don't know if
+ // Types refers to the template type parameter pack in scope or a
+ // non-pack member.
+ // t.Types::foo();
+
+ t.template foo<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+
+ // UnresolvedMemberExpr
+ x.f<Types>(); // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+ x.f(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ // CXXNoexceptExpr
+ noexcept(values); // expected-error{{expression contains unexpanded parameter pack 'values'}}
+
+ // PackExpansionExpr is uninteresting
+ // SizeOfPackExpr is uninteresting
+
+ // FIXME: Objective-C expressions will need to go elsewhere
+}
+
+// Test unexpanded parameter packs in partial specializations.
+template<typename ...Types>
+struct TestUnexpandedDecls<int, Types>; // expected-error{{partial specialization contains unexpanded parameter pack 'Types'}}
+
+// Test for diagnostics in the presence of multiple unexpanded
+// parameter packs.
+template<typename T, typename U> struct pair;
+
+template<typename ...OuterTypes>
+struct MemberTemplatePPNames {
+ template<typename ...InnerTypes>
+ struct Inner {
+ typedef pair<OuterTypes, InnerTypes>* types; // expected-error{{declaration type contains unexpanded parameter packs 'OuterTypes' and 'InnerTypes'}}
+
+ template<typename ...VeryInnerTypes>
+ struct VeryInner {
+ typedef pair<pair<VeryInnerTypes, OuterTypes>, pair<InnerTypes, OuterTypes> > types; // expected-error{{declaration type contains unexpanded parameter packs 'VeryInnerTypes', 'OuterTypes', ...}}
+ };
+ };
+};
+
+// Example from working paper
+namespace WorkingPaperExample {
+ template<typename...> struct Tuple {};
+ template<typename T1, typename T2> struct Pair {};
+
+ template<class ... Args1> struct zip {
+ template<class ... Args2> struct with {
+ typedef Tuple<Pair<Args1, Args2> ... > type; // expected-error{{pack expansion contains parameter packs 'Args1' and 'Args2' that have different lengths (1 vs. 2)}}
+ };
+ };
+
+ typedef zip<short, int>::with<unsigned short, unsigned>::type T1; // T1 is Tuple<Pair<short, unsigned short>, Pair<int, unsigned>>
+ typedef Tuple<Pair<short, unsigned short>, Pair<int, unsigned>> T1;
+
+ typedef zip<short>::with<unsigned short, unsigned>::type T2; // expected-note{{in instantiation of template class}}
+
+ template<class ... Args> void f(Args...);
+ template<class ... Args> void h(Args...);
+
+ template<class ... Args>
+ void g(Args ... args) {
+ f(const_cast<const Args*>(&args)...); // OK: "Args" and "args" are expanded within f
+ f(5 ...); // expected-error{{pack expansion does not contain any unexpanded parameter packs}}
+ f(args); // expected-error{{expression contains unexpanded parameter pack 'args'}}
+ f(h(args ...) + args ...);
+ }
+}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp b/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp
index 7352be2d..989ff9f 100644
--- a/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp
+++ b/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp
@@ -11,11 +11,33 @@ template<typename T> struct X1t; // expected-error{{template type parameter conf
template<typename T> struct X2t; // expected-note{{previous template type parameter declared here}}
template<typename ...T> struct X2t; // expected-error{{template type parameter pack conflicts with previous template type parameter}}
-template<template<typename ...T> class> struct X0tt;
-template<template<typename ...T> class> struct X0tt;
+template<template<typename ...T> class> struct X0t_intt;
+template<template<typename ...T> class> struct X0t_intt;
-template<template<typename ...T> class> struct X1tt; // expected-note{{previous template type parameter pack declared here}}
-template<template<typename T> class> struct X1tt; // expected-error{{template type parameter conflicts with previous template type parameter pack}}
+template<template<typename ...T> class> struct X1t_intt; // expected-note{{previous template type parameter pack declared here}}
+template<template<typename T> class> struct X1t_intt; // expected-error{{template type parameter conflicts with previous template type parameter pack}}
-template<template<typename T> class> struct X2tt; // expected-note{{previous template type parameter declared here}}
-template<template<typename ...T> class> struct X2tt; // expected-error{{template type parameter pack conflicts with previous template type parameter}}
+template<template<typename T> class> struct X2t_intt; // expected-note{{previous template type parameter declared here}}
+template<template<typename ...T> class> struct X2t_intt; // expected-error{{template type parameter pack conflicts with previous template type parameter}}
+
+template<int ...Values> struct X1nt; // expected-note{{previous non-type template parameter pack declared here}}
+template<int Values> struct X1nt; // expected-error{{non-type template parameter conflicts with previous non-type template parameter pack}}
+
+template<template<class T> class> class X1tt; // expected-note{{previous template template parameter declared here}}
+template<template<class T> class...> class X1tt; // expected-error{{template template parameter pack conflicts with previous template template parameter}}
+
+// Check for matching with out-of-line definitions
+namespace rdar8859985 {
+ template<typename ...> struct tuple { };
+ template<int ...> struct int_tuple { };
+
+ template<typename T>
+ struct X {
+ template<typename ...Args1, int ...Indices1>
+ X(tuple<Args1...>, int_tuple<Indices1...>);
+ };
+
+ template<typename T>
+ template<typename ...Args1, int ...Indices1>
+ X<T>::X(tuple<Args1...>, int_tuple<Indices1...>) {}
+}
diff --git a/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp b/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp
new file mode 100644
index 0000000..3723178
--- /dev/null
+++ b/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Various tests related to partial ordering of variadic templates.
+template<typename ...Types> struct tuple;
+
+template<typename Tuple>
+struct X1 {
+ static const unsigned value = 0;
+};
+
+template<typename Head, typename ...Tail>
+struct X1<tuple<Head, Tail...> > {
+ static const unsigned value = 1;
+};
+
+template<typename Head, typename ...Tail>
+struct X1<tuple<Head, Tail&...> > {
+ static const unsigned value = 2;
+};
+
+template<typename Head, typename ...Tail>
+struct X1<tuple<Head&, Tail&...> > {
+ static const unsigned value = 3;
+};
+
+int check0[X1<tuple<>>::value == 0? 1 : -1];
+int check1[X1<tuple<int>>::value == 2? 1 : -1];
+int check2[X1<tuple<int, int>>::value == 1? 1 : -1];
+int check3[X1<tuple<int, int&>>::value == 2? 1 : -1];
+int check4[X1<tuple<int&, int&>>::value == 3? 1 : -1];
+
+// Partial ordering of function templates.
+template<typename T1, typename T2, typename ...Rest>
+int &f0(T1, T2, Rest...);
+
+template<typename T1, typename T2>
+float &f0(T1, T2);
+
+void test_f0() {
+ int &ir1 = f0(1, 2.0, 'a');
+ float &fr1 = f0(1, 2.0);
+}
+
+template<typename T1, typename T2, typename ...Rest>
+int &f1(T1, T2, Rest...);
+
+template<typename T1, typename T2>
+float &f1(T1, T2, ...);
+
+void test_f1() {
+ int &ir1 = f1(1, 2.0, 'a');
+}
+
+template<typename T1, typename T2, typename ...Rest>
+int &f2(T1, T2, Rest...);
+
+float &f2(...);
+
+void test_f2() {
+ int &ir1 = f2(1, 2.0, 'a');
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp
new file mode 100644
index 0000000..46d70b6
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+namespace ParameterPacksWithFunctions {
+ template<typename ...> struct count;
+
+ template<typename Head, typename ...Tail>
+ struct count<Head, Tail...> {
+ static const unsigned value = 1 + count<Tail...>::value;
+ };
+
+ template<>
+ struct count<> {
+ static const unsigned value = 0;
+ };
+
+ template<unsigned> struct unsigned_c { };
+
+ template<typename ... Types>
+ unsigned_c<count<Types...>::value> f();
+
+ void test_f() {
+ unsigned_c<0> uc0a = f(); // okay, deduced to an empty pack
+ unsigned_c<0> uc0b = f<>();
+ unsigned_c<1> uc1 = f<int>();
+ unsigned_c<2> uc2 = f<float, double>();
+ }
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
index eb5465c..9ec8f0c 100644
--- a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
@@ -33,4 +33,4 @@ template <typename T> void g(T);
template <typename T> void g(T, T);
int typeof2[is_same<__typeof__(g<float>), void (int)>::value? 1 : -1]; // \
- // expected-error{{cannot determine the type of an overloaded function}}
+ // expected-error{{cannot resolve overloaded function from context}}
diff --git a/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp
new file mode 100644
index 0000000..b38cc27
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Metafunction to extract the Nth type from a set of types.
+template<unsigned N, typename ...Types> struct get_nth_type;
+
+template<unsigned N, typename Head, typename ...Tail>
+struct get_nth_type<N, Head, Tail...> : get_nth_type<N-1, Tail...> { };
+
+template<typename Head, typename ...Tail>
+struct get_nth_type<0, Head, Tail...> {
+ typedef Head type;
+};
+
+// Placeholder type when get_nth_type fails.
+struct no_type {};
+
+template<unsigned N>
+struct get_nth_type<N> {
+ typedef no_type type;
+};
+
+template<typename ...Args>
+typename get_nth_type<0, Args...>::type first_arg(Args...);
+
+template<typename ...Args>
+typename get_nth_type<1, Args...>::type second_arg(Args...);
+
+// Test explicit specification of function template arguments.
+void test_explicit_spec_simple() {
+ int *ip1 = first_arg<int *>(0);
+ int *ip2 = first_arg<int *, float*>(0, 0);
+ float *fp1 = first_arg<float *, double*, int*>(0, 0, 0);
+}
+
+// Template argument deduction can extend the sequence of template
+// arguments corresponding to a template parameter pack, even when the
+// sequence contains explicitly specified template arguments.
+void test_explicit_spec_extension(double *dp) {
+ int *ip1 = first_arg<int *>(0, 0);
+ int *ip2 = first_arg<int *, float*>(0, 0, 0, 0);
+ float *fp1 = first_arg<float *, double*, int*>(0, 0, 0);
+ int *i1 = second_arg<float *>(0, (int*)0, 0);
+ double *dp1 = first_arg<>(dp);
+}
+
+template<typename ...Types>
+struct tuple { };
+
+template<typename ...Types>
+void accept_tuple(tuple<Types...>);
+
+void test_explicit_spec_extension_targs(tuple<int, float, double> t3) {
+ accept_tuple(t3);
+ accept_tuple<int, float, double>(t3);
+ accept_tuple<int>(t3);
+ accept_tuple<int, float>(t3);
+}
+
+template<typename R, typename ...ParmTypes>
+void accept_function_ptr(R(*)(ParmTypes...));
+
+void test_explicit_spec_extension_funcparms(int (*f3)(int, float, double)) {
+ accept_function_ptr(f3);
+ accept_function_ptr<int>(f3);
+ accept_function_ptr<int, int>(f3);
+ accept_function_ptr<int, int, float>(f3);
+ accept_function_ptr<int, int, float, double>(f3);
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp
new file mode 100644
index 0000000..8933b63
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Metafunction to extract the Nth type from a set of types.
+template<unsigned N, typename ...Types> struct get_nth_type;
+
+template<unsigned N, typename Head, typename ...Tail>
+struct get_nth_type<N, Head, Tail...> : get_nth_type<N-1, Tail...> { };
+
+template<typename Head, typename ...Tail>
+struct get_nth_type<0, Head, Tail...> {
+ typedef Head type;
+};
+
+// Placeholder type when get_nth_type fails.
+struct no_type {};
+
+template<unsigned N>
+struct get_nth_type<N> {
+ typedef no_type type;
+};
+
+template<typename T, typename U> struct pair { };
+template<typename T, typename U> pair<T, U> make_pair(T, U);
+
+// For a function parameter pack that occurs at the end of the
+// parameter-declaration-list, the type A of each remaining argument
+// of the call is compared with the type P of the declarator-id of the
+// function parameter pack.
+template<typename ...Args>
+typename get_nth_type<0, Args...>::type first_arg(Args...);
+
+template<typename ...Args>
+typename get_nth_type<1, Args...>::type second_arg(Args...);
+
+void test_simple_deduction(int *ip, float *fp, double *dp) {
+ int *ip1 = first_arg(ip);
+ int *ip2 = first_arg(ip, fp);
+ int *ip3 = first_arg(ip, fp, dp);
+ no_type nt1 = first_arg();
+}
+
+template<typename ...Args>
+typename get_nth_type<0, Args...>::type first_arg_ref(Args&...);
+
+template<typename ...Args>
+typename get_nth_type<1, Args...>::type second_arg_ref(Args&...);
+
+void test_simple_ref_deduction(int *ip, float *fp, double *dp) {
+ int *ip1 = first_arg_ref(ip);
+ int *ip2 = first_arg_ref(ip, fp);
+ int *ip3 = first_arg_ref(ip, fp, dp);
+ no_type nt1 = first_arg_ref();
+}
+
+
+template<typename ...Args1, typename ...Args2>
+typename get_nth_type<0, Args1...>::type first_arg_pair(pair<Args1, Args2>...); // expected-note{{candidate template ignored: failed template argument deduction}}
+
+template<typename ...Args1, typename ...Args2>
+typename get_nth_type<1, Args1...>::type second_arg_pair(pair<Args1, Args2>...);
+
+void test_pair_deduction(int *ip, float *fp, double *dp) {
+ int *ip1 = first_arg_pair(make_pair(ip, 17));
+ int *ip2 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17));
+ int *ip3 = first_arg_pair(make_pair(ip, 17), make_pair(fp, 17),
+ make_pair(dp, 17));
+ float *fp1 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17));
+ float *fp2 = second_arg_pair(make_pair(ip, 17), make_pair(fp, 17),
+ make_pair(dp, 17));
+ no_type nt1 = first_arg_pair();
+ no_type nt2 = second_arg_pair();
+ no_type nt3 = second_arg_pair(make_pair(ip, 17));
+
+
+ first_arg_pair(make_pair(ip, 17), 16); // expected-error{{no matching function for call to 'first_arg_pair'}}
+}
+
+// For a function parameter pack that does not occur at the end of the
+// parameter-declaration-list, the type of the parameter pack is a
+// non-deduced context.
+template<typename ...Types> struct tuple { };
+
+template<typename ...Types>
+void pack_not_at_end(tuple<Types...>, Types... values, int);
+
+void test_pack_not_at_end(tuple<int*, double*> t2) {
+ pack_not_at_end(t2, 0, 0, 0);
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
new file mode 100644
index 0000000..f18a74a
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+
+// If P is an rvalue reference to a cv-unqualified template parameter
+// and the argument is an lvalue, the type "lvalue reference to A" is
+// used in place of A for type deduction.
+template<typename T> struct X { };
+
+template<typename T> X<T> f0(T&&);
+
+struct Y { };
+
+template<typename T> T prvalue();
+template<typename T> T&& xvalue();
+template<typename T> T& lvalue();
+
+void test_f0() {
+ X<int> xi0 = f0(prvalue<int>());
+ X<int> xi1 = f0(xvalue<int>());
+ X<int&> xi2 = f0(lvalue<int>());
+ X<Y> xy0 = f0(prvalue<Y>());
+ X<Y> xy1 = f0(xvalue<Y>());
+ X<Y&> xy2 = f0(lvalue<Y>());
+}
+
+template<typename T> X<T> f1(const T&&); // expected-note{{candidate function [with T = int] not viable: no known conversion from 'int' to 'const int &&' for 1st argument}} \
+// expected-note{{candidate function [with T = Y] not viable: no known conversion from 'Y' to 'const Y &&' for 1st argument}}
+
+void test_f1() {
+ X<int> xi0 = f1(prvalue<int>());
+ X<int> xi1 = f1(xvalue<int>());
+ f1(lvalue<int>()); // expected-error{{no matching function for call to 'f1'}}
+ X<Y> xy0 = f1(prvalue<Y>());
+ X<Y> xy1 = f1(xvalue<Y>());
+ f1(lvalue<Y>()); // expected-error{{no matching function for call to 'f1'}}
+}
+
+namespace std_example {
+ template <class T> int f(T&&);
+ template <class T> int g(const T&&); // expected-note{{candidate function [with T = int] not viable: no known conversion from 'int' to 'const int &&' for 1st argument}}
+
+ int i;
+ int n1 = f(i);
+ int n2 = f(0);
+ int n3 = g(i); // expected-error{{no matching function for call to 'g'}}
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp
index 19962c5..3c22cf3 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp
@@ -101,3 +101,25 @@ void test_f4(D d, E e, F f, G g) {
C<int, 1> *ci3c = f4c(&g);
int *ip1 = f4c(&f);
}
+
+// PR8462
+namespace N {
+ struct T0;
+ struct T1;
+
+ template<typename X, typename Y> struct B {};
+
+ struct J : B<T0,T0> {};
+ struct K : B<T1,T1> {};
+
+ struct D : J, K {};
+
+ template<typename X, typename Y> void F(B<Y,X>);
+
+ void test()
+ {
+ D d;
+ N::F<T0>(d); // Fails
+ N::F<T1>(d); // OK
+ }
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp
index 99ade4b..01155e1 100644
--- a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp
@@ -13,10 +13,35 @@ struct identity {
};
template <class T>
- T* f2(int, typename identity<T>::type = 0); // expected-note{{candidate}}
+ T* f2(int, typename identity<T>::type = 0);
template <class T, class U>
- T& f2(U, typename identity<T>::type = 0); // expected-note{{candidate}}
+ T& f2(U, typename identity<T>::type = 0);
void g2() {
- f2<int>(1); // expected-error{{ambiguous}}
+ int* ip = f2<int>(1);
+}
+
+template<class T, class U> struct A { };
+
+template<class T, class U> inline int *f3( U, A<U,T>* p = 0 ); // #1 expected-note{{candidate function [with T = int, U = int]}}
+template< class U> inline float *f3( U, A<U,U>* p = 0 ); // #2 expected-note{{candidate function [with U = int]}}
+
+void g3() {
+ float *fp = f3<int>( 42, (A<int,int>*)0 ); // Ok, picks #2.
+ f3<int>( 42 ); // expected-error{{call to 'f3' is ambiguous}}
+
+}
+
+namespace PR9006 {
+ struct X {
+ template <class Get>
+ int &f(char const* name, Get fget, char const* docstr = 0);
+
+ template <class Get, class Set>
+ float &f(char const* name, Get fget, Set fset, char const* docstr = 0);
+ };
+
+ void test(X x) {
+ int &ir = x.f("blah", 0, "blah");
+ }
}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp
new file mode 100644
index 0000000..1168100
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Note: Partial ordering of function templates containing template
+// parameter packs is independent of the number of deduced arguments
+// for those template parameter packs.
+template<class ...> struct Tuple { };
+template<class ... Types> int &g(Tuple<Types ...>); // #1
+template<class T1, class ... Types> float &g(Tuple<T1, Types ...>); // #2
+template<class T1, class ... Types> double &g(Tuple<T1, Types& ...>); // #3
+
+void test_g() {
+ int &ir1 = g(Tuple<>());
+ float &fr1 = g(Tuple<int, float>());
+ double &dr1 = g(Tuple<int, float&>());
+ double &dr2 = g(Tuple<int>());
+}
+
+template<class ... Types> int &h(int (*)(Types ...)); // #1
+template<class T1, class ... Types> float &h(int (*)(T1, Types ...)); // #2
+template<class T1, class ... Types> double &h(int (*)(T1, Types& ...)); // #3
+
+void test_h() {
+ int &ir1 = h((int(*)())0);
+ float &fr1 = h((int(*)(int, float))0);
+ double &dr1 = h((int(*)(int, float&))0);
+ double &dr2 = h((int(*)(int))0);
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp
new file mode 100644
index 0000000..46ea4db
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<typename T> int &f0(T&);
+template<typename T> float &f0(T&&);
+
+// Core issue 1164
+void test_f0(int i) {
+ int &ir0 = f0(i);
+ float &fr0 = f0(5);
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp
new file mode 100644
index 0000000..9d342c8
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+template<typename T> void f(T&&);
+template<> void f(int&) { }
+void (*fp)(int&) = &f;
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp
new file mode 100644
index 0000000..198f11f
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// If type deduction cannot be done for any P/A pair, or if for any
+// pair the deduction leads to more than one possible set of deduced
+// values, or if different pairs yield different deduced values, or if
+// any template argument remains neither deduced nor explicitly
+// specified, template argument deduction fails.
+
+template<typename ...> struct tuple;
+
+template<typename T, typename U>
+struct same_tuple {
+ static const bool value = false;
+};
+
+template<typename ...Types1>
+struct same_tuple<tuple<Types1...>, tuple<Types1...> > {
+ static const bool value = true;
+};
+
+int same_tuple_check1[same_tuple<tuple<int, float>, tuple<int, double>>::value? -1 : 1];
+int same_tuple_check2[same_tuple<tuple<float, double>, tuple<float, double>>::value? 1 : -1];
+
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp
new file mode 100644
index 0000000..247b981
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Note: Template argument deduction involving parameter packs
+// (14.5.3) can deduce zero or more arguments for each parameter pack.
+
+template<class> struct X {
+ static const unsigned value = 0;
+};
+
+template<class R, class ... ArgTypes> struct X<R(int, ArgTypes ...)> {
+ static const unsigned value = 1;
+};
+
+template<class ... Types> struct Y {
+ static const unsigned value = 0;
+};
+
+template<class T, class ... Types> struct Y<T, Types& ...> {
+ static const unsigned value = 1;
+};
+
+template<class ... Types> int f(void (*)(Types ...));
+void g(int, float);
+
+int check0[X<int>::value == 0? 1 : -1]; // uses primary template
+int check1[X<int(int, float, double)>::value == 1? 1 : -1]; // uses partial specialization
+int check2[X<int(float, int)>::value == 0? 1 : -1]; // uses primary template
+int check3[Y<>::value == 0? 1 : -1]; // uses primary template
+int check4[Y<int&, float&, double&>::value == 1? 1 : -1]; // uses partial specialization
+int check5[Y<int, float, double>::value == 0? 1 : -1]; // uses primary template
+int fv = f(g); // okay
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp
new file mode 100644
index 0000000..4326a69
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// If the original function parameter associated with A is a function
+// parameter pack and the function parameter associated with P is not
+// a function parameter pack, then template argument deduction fails.
+template<class ... Args> int& f(Args ... args);
+template<class T1, class ... Args> float& f(T1 a1, Args ... args);
+template<class T1, class T2> double& f(T1 a1, T2 a2);
+
+void test_f() {
+ int &ir1 = f();
+ float &fr1 = f(1, 2, 3);
+ double &dr1 = f(1, 2);
+}
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp
new file mode 100644
index 0000000..cf68a01
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// FIXME: More bullets to go!
+
+template<typename T, typename U>
+struct has_nondeduced_pack_test {
+ static const bool value = false;
+};
+
+template<typename R, typename FirstType, typename ...Types>
+struct has_nondeduced_pack_test<R(FirstType, Types..., int),
+ R(FirstType, Types...)> {
+ static const bool value = true;
+};
+
+// - A function parameter pack that does not occur at the end of the
+// parameter-declaration-clause.
+int check_nondeduced_pack_test0[
+ has_nondeduced_pack_test<int(float, double, int),
+ int(float, double)>::value? 1 : -1];
+
+
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp
new file mode 100644
index 0000000..a9173fd
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// Deductions specific to C++0x.
+
+template<typename T>
+struct member_pointer_kind {
+ static const unsigned value = 0;
+};
+
+template<class C, typename R, typename ...Args>
+struct member_pointer_kind<R (C::*)(Args...)> {
+ static const unsigned value = 1;
+};
+
+template<class C, typename R, typename ...Args>
+struct member_pointer_kind<R (C::*)(Args...) &> {
+ static const unsigned value = 2;
+};
+
+template<class C, typename R, typename ...Args>
+struct member_pointer_kind<R (C::*)(Args...) &&> {
+ static const unsigned value = 3;
+};
+
+template<class C, typename R, typename ...Args>
+struct member_pointer_kind<R (C::*)(Args...) const> {
+ static const unsigned value = 4;
+};
+
+template<class C, typename R, typename ...Args>
+struct member_pointer_kind<R (C::*)(Args...) const &> {
+ static const unsigned value = 5;
+};
+
+template<class C, typename R, typename ...Args>
+struct member_pointer_kind<R (C::*)(Args...) const &&> {
+ static const unsigned value = 6;
+};
+
+struct X { };
+
+static_assert(member_pointer_kind<int (X::*)(int)>::value == 1, "");
+static_assert(member_pointer_kind<int (X::*)(int) &>::value == 2, "");
+static_assert(member_pointer_kind<int (X::*)(int) &&>::value == 3, "");
+static_assert(member_pointer_kind<int (X::*)(int) const>::value == 4, "");
+static_assert(member_pointer_kind<int (X::*)(int) const&>::value == 5, "");
+static_assert(member_pointer_kind<int (X::*)(int) const&&>::value == 6, "");
diff --git a/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
new file mode 100644
index 0000000..5087224
--- /dev/null
+++ b/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+template<typename ...Types> struct tuple;
+template<unsigned> struct unsigned_c;
+
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+namespace PackExpansionNotAtEnd {
+ template<typename T, typename U>
+ struct tuple_same_with_int {
+ static const bool value = false;
+ };
+
+ template<typename ...Types>
+ struct tuple_same_with_int<tuple<Types...>, tuple<Types..., int>> {
+ static const bool value = true;
+ };
+
+ int tuple_same_with_int_1[tuple_same_with_int<tuple<int, float, double>,
+ tuple<int, float, double, int>
+ >::value? 1 : -1];
+
+ template<typename ... Types> struct UselessPartialSpec;
+
+ template<typename ... Types, // expected-note{{non-deducible template parameter 'Types'}}
+ typename Tail> // expected-note{{non-deducible template parameter 'Tail'}}
+ struct UselessPartialSpec<Types..., Tail>; // expected-warning{{class template partial specialization contains template parameters that can not be deduced; this partial specialization will never be used}}
+}
+
+namespace DeduceNonTypeTemplateArgsInArray {
+ template<typename ...ArrayTypes>
+ struct split_arrays;
+
+ template<typename ...ElementTypes, unsigned ...Bounds>
+ struct split_arrays<ElementTypes[Bounds]...> {
+ typedef tuple<ElementTypes...> element_types;
+
+ // FIXME: Would like to have unsigned_tuple<Bounds...> here.
+ typedef tuple<unsigned_c<Bounds>...> bounds_types;
+ };
+
+ int check1[is_same<split_arrays<int[1], float[2], double[3]>::element_types,
+ tuple<int, float, double>>::value? 1 : -1];
+ int check2[is_same<split_arrays<int[1], float[2], double[3]>::bounds_types,
+ tuple<unsigned_c<1>, unsigned_c<2>, unsigned_c<3>>
+ >::value? 1 : -1];
+}
diff --git a/test/CXX/temp/temp.param/p1.cpp b/test/CXX/temp/temp.param/p1.cpp
index 676bffe..e9a9789 100644
--- a/test/CXX/temp/temp.param/p1.cpp
+++ b/test/CXX/temp/temp.param/p1.cpp
@@ -1,4 +1,12 @@
// Suppress 'no run line' failure.
-// RUN: echo ok
+// RUN: %clang_cc1 -fsyntax-only -verify %s
-// Paragraph 1 is descriptive, and therefore requires no tests.
+template<template<> class C> class D; // expected-error{{template template parameter must have its own template parameters}}
+
+
+struct A {};
+template<class M,
+ class T = A, // expected-note{{previous default template argument defined here}}
+ class C> // expected-error{{template parameter missing a default argument}}
+class X0 {}; // expected-note{{template is declared here}}
+X0<int> x0; // expected-error{{too few template arguments for class template 'X0'}}
diff --git a/test/CXX/temp/temp.param/p11-0x.cpp b/test/CXX/temp/temp.param/p11-0x.cpp
new file mode 100644
index 0000000..0bf4341
--- /dev/null
+++ b/test/CXX/temp/temp.param/p11-0x.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// If a template-parameter of a class template has a default
+// template-argument, each subsequent template-parameter shall either
+// have a default template-argument supplied or be a template
+// parameter pack.
+template<typename> struct vector;
+
+template<typename T = int, typename ...Types> struct X2t;
+template<int V = 0, int ...Values> struct X2nt;
+template<template<class> class M = vector, template<class> class... Metas>
+ struct X2tt;
+
+// If a template-parameter of a primary class template is a template
+// parameter pack, it shall be the last template-parameter .
+template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}}
+ int After>
+struct X0t;
+
+template<int ...Values, // expected-error{{template parameter pack must be the last template parameter}}
+ int After>
+struct X0nt;
+
+template<template<typename> class ...Templates, // expected-error{{template parameter pack must be the last template parameter}}
+ int After>
+struct X0tt;
+
+// [ Note: These are not requirements for function templates or class
+// template partial specializations because template arguments can be
+// deduced (14.8.2). -- end note]
+template<typename... Types> struct X1t;
+template<typename ...Types, typename T> struct X1t<T, Types...> { };
+
+template<int... Values> struct X1nt;
+template<int ...Values, int V> struct X1nt<V, Values...> { };
+
+template<template<int> class... Meta> struct X1tt;
+template<template<int> class... Meta, template<int> class M>
+ struct X1tt<M, Meta...> { };
+
+template<typename ...Types, typename T>
+void f1t(X1t<T, Types...>);
+
+template<int ...Values, int V>
+void f1nt(X1nt<V, Values...>);
+
+template<template<int> class... Meta, template<int> class M>
+void f1tt(X1tt<M, Meta...>);
+
+namespace DefaultTemplateArgsInFunction {
+ template<typename T = int, typename U> T &f0(U) { T *x = 0; return *x; }
+
+ void test_f0() {
+ int &ir0 = f0(3.14159);
+ int &ir1 = f0<int>(3.14159);
+ float &fr0 = f0<float>(3.14159);
+ }
+
+ template<> int &f0(int*);
+ template int &f0(double&);
+}
diff --git a/test/CXX/temp/temp.param/p15-cxx0x.cpp b/test/CXX/temp/temp.param/p15-cxx0x.cpp
index 0ce6699..f4be5b9 100644
--- a/test/CXX/temp/temp.param/p15-cxx0x.cpp
+++ b/test/CXX/temp/temp.param/p15-cxx0x.cpp
@@ -20,3 +20,5 @@ void f(const X<int> x) {
X<X<int>> *x1;
}
+template<typename T = void> struct X1 { };
+X1<X1<>> x1a;
diff --git a/test/CXX/temp/temp.param/p9-0x.cpp b/test/CXX/temp/temp.param/p9-0x.cpp
new file mode 100644
index 0000000..17eca7f
--- /dev/null
+++ b/test/CXX/temp/temp.param/p9-0x.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -std=c++0x -fsyntax-only -verify %s
+
+// A default template-argument may be specified for any kind of
+// template-parameter that is not a template parameter pack.
+template<typename ...Types = int> // expected-error{{template parameter pack cannot have a default argument}}
+struct X0;
+
+template<int ...Values = 0> // expected-error{{template parameter pack cannot have a default argument}}
+struct X1;
+
+template<typename T> struct vector;
+
+template<template<class> class ...Templates = vector> // expected-error{{template parameter pack cannot have a default argument}}
+struct X2;
+
+struct X3 {
+ template<typename T = int> // expected-error{{default template argument not permitted on a friend template}}
+ friend void f0(X3);
+
+ template<typename T = int>
+ friend void f1(X3) {
+ }
+};
+
+namespace PR8748 {
+ // Testcase 1
+ struct A0 { template<typename U> struct B; };
+ template<typename U = int> struct A0::B { };
+
+ // Testcase 2
+ template<typename T> struct A1 { template<typename U> struct B; };
+ template<typename T> template<typename U = int> struct A1<T>::B { }; // expected-error{{cannot add a default template argument to the definition of a member of a class template}}
+
+ // Testcase 3
+ template<typename T>
+ struct X2 {
+ void f0();
+ template<typename U> void f1();
+ };
+
+ template<typename T = int> void X2<T>::f0() { } // expected-error{{cannot add a default template argument to the definition of a member of a class template}}
+ template<typename T> template<typename U = int> void X2<T>::f1() { } // expected-error{{cannot add a default template argument to the definition of a member of a class template}}
+
+ namespace Inner {
+ template<typename T> struct X3;
+ template<typename T> void f2();
+ }
+
+ // Okay; not class members.
+ template<typename T = int> struct Inner::X3 { };
+ template<typename T = int> void Inner::f2() {}
+}
diff --git a/test/CXX/temp/temp.param/p9.cpp b/test/CXX/temp/temp.param/p9.cpp
index 625477c..62af522 100644
--- a/test/CXX/temp/temp.param/p9.cpp
+++ b/test/CXX/temp/temp.param/p9.cpp
@@ -2,9 +2,9 @@
// A default template-argument shall not be specified in a function
// template declaration or a function template definition
-template<typename T = int> // expected-error{{cannot have a default argument}}
+template<typename T = int> // expected-warning{{default template arguments for a function template are a C++0x extension}}
void foo0(T);
-template<typename T = int> // expected-error{{cannot have a default argument}}
+template<typename T = int> // expected-warning{{default template arguments for a function template are a C++0x extension}}
void foo1(T) { }
// [...] nor in the template-parameter-list of the definition of a
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
new file mode 100644
index 0000000..ed600e4
--- /dev/null
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
@@ -0,0 +1,239 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++0x %s
+
+// This test creates cases where implicit instantiations of various entities
+// would cause a diagnostic, but provides expliict specializations for those
+// entities that avoid the diagnostic. The specializations are alternately
+// declarations and definitions, and the intent of this test is to verify
+// that we allow specializations only in the appropriate namespaces (and
+// nowhere else).
+struct NonDefaultConstructible {
+ NonDefaultConstructible(int);
+};
+
+
+// C++ [temp.expl.spec]p1:
+// An explicit specialization of any of the following:
+
+// -- function template
+namespace N0 {
+ template<typename T> void f0(T) {
+ T t;
+ }
+
+ template<> void f0(NonDefaultConstructible) { }
+
+ void test_f0(NonDefaultConstructible NDC) {
+ f0(NDC);
+ }
+
+ template<> void f0(int);
+ template<> void f0(long);
+}
+
+template<> void N0::f0(int) { } // okay
+
+namespace N1 {
+ template<> void N0::f0(long) { } // expected-error{{not in a namespace enclosing}}
+}
+
+template<> void N0::f0(double) { }
+
+struct X1 {
+ template<typename T> void f(T);
+
+ template<> void f(int); // expected-error{{in class scope}}
+};
+
+// -- class template
+namespace N0 {
+
+template<typename T>
+struct X0 { // expected-note {{here}}
+ static T member;
+
+ void f1(T t) {
+ t = 17;
+ }
+
+ struct Inner : public T { }; // expected-note 2{{here}}
+
+ template<typename U>
+ struct InnerTemplate : public T { }; // expected-note 1{{explicitly specialized}} \
+ // expected-error{{base specifier}}
+
+ template<typename U>
+ void ft1(T t, U u);
+};
+
+}
+
+template<typename T>
+template<typename U>
+void N0::X0<T>::ft1(T t, U u) {
+ t = u;
+}
+
+template<typename T> T N0::X0<T>::member;
+
+template<> struct N0::X0<void> { };
+N0::X0<void> test_X0;
+
+namespace N1 {
+ template<> struct N0::X0<const void> { }; // expected-error{{class template specialization of 'X0' must originally be declared in namespace 'N0'}}
+}
+
+namespace N0 {
+ template<> struct X0<volatile void>;
+}
+
+template<> struct N0::X0<volatile void> {
+ void f1(void *);
+};
+
+// -- member function of a class template
+template<> void N0::X0<void*>::f1(void *) { }
+
+void test_spec(N0::X0<void*> xvp, void *vp) {
+ xvp.f1(vp);
+}
+
+namespace N0 {
+ template<> void X0<volatile void>::f1(void *) { } // expected-error{{no function template matches}}
+
+ template<> void X0<const volatile void*>::f1(const volatile void*);
+}
+
+void test_x0_cvvoid(N0::X0<const volatile void*> x0, const volatile void *cvp) {
+ x0.f1(cvp); // okay: we've explicitly specialized
+}
+
+// -- static data member of a class template
+namespace N0 {
+ // This actually tests p15; the following is a declaration, not a definition.
+ template<>
+ NonDefaultConstructible X0<NonDefaultConstructible>::member;
+
+ template<> long X0<long>::member = 17;
+
+ template<> float X0<float>::member;
+
+ template<> double X0<double>::member;
+}
+
+NonDefaultConstructible &get_static_member() {
+ return N0::X0<NonDefaultConstructible>::member;
+}
+
+template<> int N0::X0<int>::member;
+
+template<> float N0::X0<float>::member = 3.14f;
+
+namespace N1 {
+ template<> double N0::X0<double>::member = 3.14; // expected-error{{not in a namespace enclosing}}
+}
+
+// -- member class of a class template
+namespace N0 {
+
+ template<>
+ struct X0<void*>::Inner { };
+
+ template<>
+ struct X0<int>::Inner { };
+
+ template<>
+ struct X0<unsigned>::Inner;
+
+ template<>
+ struct X0<float>::Inner;
+
+ template<>
+ struct X0<double>::Inner; // expected-note{{forward declaration}}
+}
+
+template<>
+struct N0::X0<long>::Inner { };
+
+template<>
+struct N0::X0<float>::Inner { };
+
+namespace N1 {
+ template<>
+ struct N0::X0<unsigned>::Inner { }; // expected-error{{member class specialization}}
+
+ template<>
+ struct N0::X0<unsigned long>::Inner { }; // expected-error{{member class specialization}}
+};
+
+N0::X0<void*>::Inner inner0;
+N0::X0<int>::Inner inner1;
+N0::X0<long>::Inner inner2;
+N0::X0<float>::Inner inner3;
+N0::X0<double>::Inner inner4; // expected-error{{incomplete}}
+
+// -- member class template of a class template
+namespace N0 {
+ template<>
+ template<>
+ struct X0<void*>::InnerTemplate<int> { };
+
+ template<> template<>
+ struct X0<int>::InnerTemplate<int>; // expected-note{{forward declaration}}
+
+ template<> template<>
+ struct X0<int>::InnerTemplate<long>;
+
+ template<> template<>
+ struct X0<int>::InnerTemplate<double>;
+}
+
+template<> template<>
+struct N0::X0<int>::InnerTemplate<long> { }; // okay
+
+template<> template<>
+struct N0::X0<int>::InnerTemplate<float> { };
+
+namespace N1 {
+ template<> template<>
+ struct N0::X0<int>::InnerTemplate<double> { }; // expected-error{{enclosing}}
+}
+
+N0::X0<void*>::InnerTemplate<int> inner_template0;
+N0::X0<int>::InnerTemplate<int> inner_template1; // expected-error{{incomplete}}
+N0::X0<int>::InnerTemplate<long> inner_template2;
+N0::X0<int>::InnerTemplate<unsigned long> inner_template3; // expected-note{{instantiation}}
+
+// -- member function template of a class template
+namespace N0 {
+ template<>
+ template<>
+ void X0<void*>::ft1(void*, const void*) { }
+
+ template<> template<>
+ void X0<void*>::ft1(void *, int);
+
+ template<> template<>
+ void X0<void*>::ft1(void *, unsigned);
+
+ template<> template<>
+ void X0<void*>::ft1(void *, long);
+}
+
+template<> template<>
+void N0::X0<void*>::ft1(void *, unsigned) { } // okay
+
+template<> template<>
+void N0::X0<void*>::ft1(void *, float) { }
+
+namespace N1 {
+ template<> template<>
+ void N0::X0<void*>::ft1(void *, long) { } // expected-error{{enclosing}}
+}
+
+
+void test_func_template(N0::X0<void *> xvp, void *vp, const void *cvp,
+ int i, unsigned u) {
+ xvp.ft1(vp, cvp);
+ xvp.ft1(vp, i);
+ xvp.ft1(vp, u);
+}
diff --git a/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp b/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
index 654f5ab..1032a87 100644
--- a/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
+++ b/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
@@ -36,7 +36,7 @@ namespace N1 {
template<> void N0::f0(long) { } // expected-error{{not in a namespace enclosing}}
}
-template<> void N0::f0(double) { } // expected-error{{originally be declared}}
+template<> void N0::f0(double) { } // expected-warning{{originally be declared}}
struct X1 {
template<typename T> void f(T);
@@ -75,7 +75,7 @@ void N0::X0<T>::ft1(T t, U u) {
template<typename T> T N0::X0<T>::member;
-template<> struct N0::X0<void> { }; // expected-error{{originally}}
+template<> struct N0::X0<void> { }; // expected-warning{{originally}}
N0::X0<void> test_X0;
namespace N1 {
@@ -91,7 +91,7 @@ template<> struct N0::X0<volatile void> {
};
// -- member function of a class template
-template<> void N0::X0<void*>::f1(void *) { } // expected-error{{member function specialization}}
+template<> void N0::X0<void*>::f1(void *) { } // expected-warning{{member function specialization}}
void test_spec(N0::X0<void*> xvp, void *vp) {
xvp.f1(vp);
@@ -124,7 +124,7 @@ NonDefaultConstructible &get_static_member() {
return N0::X0<NonDefaultConstructible>::member;
}
-template<> int N0::X0<int>::member; // expected-error{{originally}}
+template<> int N0::X0<int>::member; // expected-warning{{originally}}
template<> float N0::X0<float>::member = 3.14f;
@@ -152,7 +152,7 @@ namespace N0 {
}
template<>
-struct N0::X0<long>::Inner { }; // expected-error{{originally}}
+struct N0::X0<long>::Inner { }; // expected-warning{{originally}}
template<>
struct N0::X0<float>::Inner { };
@@ -191,7 +191,7 @@ template<> template<>
struct N0::X0<int>::InnerTemplate<long> { }; // okay
template<> template<>
-struct N0::X0<int>::InnerTemplate<float> { }; // expected-error{{class template specialization}}
+struct N0::X0<int>::InnerTemplate<float> { }; // expected-warning{{class template specialization}}
namespace N1 {
template<> template<>
@@ -223,7 +223,7 @@ template<> template<>
void N0::X0<void*>::ft1(void *, unsigned) { } // okay
template<> template<>
-void N0::X0<void*>::ft1(void *, float) { } // expected-error{{function template specialization}}
+void N0::X0<void*>::ft1(void *, float) { } // expected-warning{{function template specialization}}
namespace N1 {
template<> template<>
diff --git a/test/CXX/temp/temp.spec/temp.explicit/p12.cpp b/test/CXX/temp/temp.spec/temp.explicit/p12.cpp
index 912b8e1..c756486 100644
--- a/test/CXX/temp/temp.spec/temp.explicit/p12.cpp
+++ b/test/CXX/temp/temp.spec/temp.explicit/p12.cpp
@@ -2,5 +2,5 @@
char* p = 0;
template<class T> T g(T x = &p) { return x; }
-template int g<int>(int); // OK even though &p isn’t an int.
+template int g<int>(int); // OK even though &p isn't an int.
OpenPOWER on IntegriCloud