summaryrefslogtreecommitdiff
path: root/clang/test/CXX/temp
diff options
context:
space:
mode:
authorCarlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au>2012-10-15 17:10:06 +1100
committerCarlo Zancanaro <carlo@pc-4w14-0.cs.usyd.edu.au>2012-10-15 17:10:06 +1100
commitbe1de4be954c80875ad4108e0a33e8e131b2f2c0 (patch)
tree1fbbecf276bf7c7bdcbb4dd446099d6d90eaa516 /clang/test/CXX/temp
parentc4626a62754862d20b41e8a46a3574264ea80e6d (diff)
parentf1bd2e48c5324d3f7cda4090c87f8a5b6f463ce2 (diff)
Merge branch 'master' of ssh://bitbucket.org/czan/honours
Diffstat (limited to 'clang/test/CXX/temp')
-rw-r--r--clang/test/CXX/temp/p3.cpp18
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp60
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp95
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp205
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp40
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.type/p2-cxx0x.cpp20
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp42
-rw-r--r--clang/test/CXX/temp/temp.decls/p3.cpp7
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.alias/p1.cpp8
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp45
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp13
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp76
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp8
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class.spec/p9-0x.cpp13
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class.spec/p9.cpp26
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp48
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1-neg.cpp25
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp25
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp27
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp152
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp28
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp100
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp17
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp17
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp28
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp26
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp17
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp16
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p4.cpp23
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p5.cpp12
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp27
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp13
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp16
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp358
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.friend/p3.cpp12
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.friend/p4.cpp28
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.friend/p5.cpp103
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.friend/p8.cpp6
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.mem/p1.cpp35
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.mem/p3.cpp6
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.mem/p5.cpp79
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/deduction.cpp50
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/example-bind.cpp352
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp86
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp260
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp46
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp127
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/injected-class-name.cpp75
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp274
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp251
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/p1.cpp9
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/p2.cpp22
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp193
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp403
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp43
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp61
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp12
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp27
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp36
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp65
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp68
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp41
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp26
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp42
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp30
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp88
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p2.cpp31
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp46
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp148
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp20
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp128
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp36
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp30
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp44
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp22
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp47
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp27
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp10
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp4
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp31
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp23
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp31
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp14
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp22
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp47
-rw-r--r--clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp55
-rw-r--r--clang/test/CXX/temp/temp.names/p2.cpp13
-rw-r--r--clang/test/CXX/temp/temp.names/p4.cpp15
-rw-r--r--clang/test/CXX/temp/temp.param/p1.cpp12
-rw-r--r--clang/test/CXX/temp/temp.param/p10-0x.cpp13
-rw-r--r--clang/test/CXX/temp/temp.param/p10.cpp12
-rw-r--r--clang/test/CXX/temp/temp.param/p11-0x.cpp81
-rw-r--r--clang/test/CXX/temp/temp.param/p11.cpp15
-rw-r--r--clang/test/CXX/temp/temp.param/p12.cpp39
-rw-r--r--clang/test/CXX/temp/temp.param/p13.cpp14
-rw-r--r--clang/test/CXX/temp/temp.param/p14.cpp5
-rw-r--r--clang/test/CXX/temp/temp.param/p15-cxx0x.cpp24
-rw-r--r--clang/test/CXX/temp/temp.param/p15.cpp12
-rw-r--r--clang/test/CXX/temp/temp.param/p2.cpp22
-rw-r--r--clang/test/CXX/temp/temp.param/p3.cpp40
-rw-r--r--clang/test/CXX/temp/temp.param/p4.cpp21
-rw-r--r--clang/test/CXX/temp/temp.param/p5.cpp13
-rw-r--r--clang/test/CXX/temp/temp.param/p7.cpp15
-rw-r--r--clang/test/CXX/temp/temp.param/p8.cpp6
-rw-r--r--clang/test/CXX/temp/temp.param/p9-0x.cpp61
-rw-r--r--clang/test/CXX/temp/temp.param/p9.cpp23
-rw-r--r--clang/test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp32
-rw-r--r--clang/test/CXX/temp/temp.res/temp.dep/p3.cpp43
-rw-r--r--clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2-0x.cpp27
-rw-r--r--clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp21
-rw-r--r--clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp30
-rw-r--r--clang/test/CXX/temp/temp.res/temp.local/p1.cpp32
-rw-r--r--clang/test/CXX/temp/temp.res/temp.local/p3.cpp32
-rw-r--r--clang/test/CXX/temp/temp.res/temp.local/p7.cpp10
-rw-r--r--clang/test/CXX/temp/temp.res/temp.local/p8.cpp53
-rw-r--r--clang/test/CXX/temp/temp.res/temp.local/p9.cpp15
-rw-r--r--clang/test/CXX/temp/temp.spec/p5.cpp47
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp334
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp99
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p10.cpp7
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p11.cpp8
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p13.cpp6
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp42
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp33
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp38
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp34
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp20
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp30
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp302
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp252
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp14
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp30
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp13
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp58
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp34
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp61
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp63
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p9.cpp14
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp24
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp29
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p1.cpp89
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p10.cpp33
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p11.cpp18
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p12.cpp6
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp43
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p3-0x.cpp65
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p3.cpp81
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp48
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p5.cpp17
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p6.cpp35
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p7.cpp36
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p8.cpp40
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp66
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.explicit/p9.cpp59
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.inst/p1.cpp104
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.inst/p11.cpp15
-rw-r--r--clang/test/CXX/temp/temp.type/p1-0x.cpp23
157 files changed, 8544 insertions, 0 deletions
diff --git a/clang/test/CXX/temp/p3.cpp b/clang/test/CXX/temp/p3.cpp
new file mode 100644
index 0000000..c146bc4
--- /dev/null
+++ b/clang/test/CXX/temp/p3.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -verify %s
+
+template<typename T> struct S {
+ static int a, b;
+};
+
+template<typename T> int S<T>::a, S<T>::b; // expected-error {{can only declare a single entity}}
+
+template<typename T> struct A { static A a; } A<T>::a; // expected-error {{expected ';' after struct}} \
+ expected-error {{use of undeclared identifier 'T'}} \
+ expected-warning{{extra qualification}}
+
+template<typename T> struct B { } f(); // expected-error {{expected ';' after struct}} \
+ expected-error {{requires a type specifier}}
+
+template<typename T> struct C { } // expected-error {{expected ';' after struct}}
+
+A<int> c;
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp
new file mode 100644
index 0000000..59ce8b6
--- /dev/null
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -std=c++11 %s -verify
+
+namespace std {
+ typedef decltype(nullptr) nullptr_t;
+}
+
+template<int *ip> struct IP { // expected-note 4 {{template parameter is declared here}}
+ IP<ip> *ip2;
+};
+
+constexpr std::nullptr_t get_nullptr() { return nullptr; }
+
+constexpr std::nullptr_t np = nullptr;
+
+std::nullptr_t nonconst_np; // expected-note{{declared here}}
+
+IP<0> ip0; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}}
+IP<(0)> ip1; // expected-error{{null non-type template argument must be cast to template parameter type 'int *'}}
+IP<nullptr> ip2;
+IP<get_nullptr()> ip3;
+IP<(int*)0> ip4;
+IP<np> ip5;
+IP<nonconst_np> ip5; // expected-error{{non-type template argument of type 'std::nullptr_t' (aka 'nullptr_t') is not a constant expression}} \
+// expected-note{{read of non-constexpr variable 'nonconst_np' is not allowed in a constant expression}}
+IP<(float*)0> ip6; // expected-error{{null non-type template argument of type 'float *' does not match template parameter of type 'int *'}}
+
+struct X { };
+template<int X::*pm> struct PM { // expected-note 2 {{template parameter is declared here}}
+ PM<pm> *pm2;
+};
+
+PM<0> pm0; // expected-error{{null non-type template argument must be cast to template parameter type 'int X::*'}}
+PM<(0)> pm1; // expected-error{{null non-type template argument must be cast to template parameter type 'int X::*'}}
+PM<nullptr> pm2;
+PM<get_nullptr()> pm3;
+PM<(int X::*)0> pm4;
+PM<np> pm5;
+
+template<int (X::*pmf)(int)> struct PMF { // expected-note 2 {{template parameter is declared here}}
+ PMF<pmf> *pmf2;
+};
+
+PMF<0> pmf0; // expected-error{{null non-type template argument must be cast to template parameter type 'int (X::*)(int)'}}
+PMF<(0)> pmf1; // expected-error{{null non-type template argument must be cast to template parameter type 'int (X::*)(int)'}}
+PMF<nullptr> pmf2;
+PMF<get_nullptr()> pmf3;
+PMF<(int (X::*)(int))0> pmf4;
+PMF<np> pmf5;
+
+
+template<std::nullptr_t np> struct NP { // expected-note 2{{template parameter is declared here}}
+ NP<np> *np2;
+};
+
+NP<nullptr> np1;
+NP<np> np2;
+NP<get_nullptr()> np3;
+NP<0> np4; // expected-error{{null non-type template argument must be cast to template parameter type 'std::nullptr_t' (aka 'nullptr_t')}}
+constexpr int i = 7;
+NP<i> np5; // expected-error{{non-type template argument of type 'const int' cannot be converted to a value of type 'std::nullptr_t'}}
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
new file mode 100644
index 0000000..c4db002
--- /dev/null
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple=x86_64-linux-gnu %s
+
+// C++11 [temp.arg.nontype]p1:
+//
+// A template-argument for a non-type, non-template template-parameter shall
+// be one of:
+// -- an integral constant expression; or
+// -- the name of a non-type template-parameter ; or
+namespace non_type_tmpl_param {
+ template <int N> struct X0 { X0(); };
+ template <int N> X0<N>::X0() { }
+ template <int* N> struct X1 { X1(); };
+ template <int* N> X1<N>::X1() { }
+ template <int& N> struct X3 { X3(); };
+ template <int& N> X3<N>::X3() { }
+ template <int (*F)(int)> struct X4 { X4(); };
+ template <int (*F)(int)> X4<F>::X4() { }
+ template <typename T, int (T::* M)(int)> struct X5 { X5(); };
+ template <typename T, int (T::* M)(int)> X5<T, M>::X5() { }
+}
+
+// -- a constant expression that designates the address of an object with
+// static storage duration and external or internal linkage or a function
+// with external or internal linkage, including function templates and
+// function template-ids, but excluting non-static class members, expressed
+// (ignoring parentheses) as & id-expression, except that the & may be
+// omitted if the name refers to a function or array and shall be omitted
+// if the corresopnding template-parameter is a reference; or
+namespace addr_of_obj_or_func {
+ template <int* p> struct X0 { }; // expected-note 4{{here}}
+ template <int (*fp)(int)> struct X1 { };
+ template <int &p> struct X2 { }; // expected-note 4{{here}}
+ template <const int &p> struct X2k { }; // expected-note {{here}}
+ template <int (&fp)(int)> struct X3 { }; // expected-note 4{{here}}
+
+ int i = 42;
+ int iarr[10];
+ int f(int i);
+ const int ki = 9; // expected-note 5{{here}}
+ __thread int ti = 100; // expected-note 2{{here}}
+ static int f_internal(int); // expected-note 4{{here}}
+ template <typename T> T f_tmpl(T t);
+
+ void test() {
+ X0<i> x0a; // expected-error {{must have its address taken}}
+ X0<&i> x0a_addr;
+ X0<iarr> x0b;
+ X0<&iarr> x0b_addr; // expected-error {{cannot be converted to a value of type 'int *'}}
+ X0<ki> x0c; // expected-error {{must have its address taken}} expected-warning {{internal linkage is a C++11 extension}}
+ X0<&ki> x0c_addr; // expected-error {{cannot be converted to a value of type 'int *'}} expected-warning {{internal linkage is a C++11 extension}}
+ X0<&ti> x0d_addr; // expected-error {{refers to thread-local object}}
+ X1<f> x1a;
+ X1<&f> x1a_addr;
+ X1<f_tmpl> x1b;
+ X1<&f_tmpl> x1b_addr;
+ X1<f_tmpl<int> > x1c;
+ X1<&f_tmpl<int> > x1c_addr;
+ X1<f_internal> x1d; // expected-warning {{internal linkage is a C++11 extension}}
+ X1<&f_internal> x1d_addr; // expected-warning {{internal linkage is a C++11 extension}}
+ X2<i> x2a;
+ X2<&i> x2a_addr; // expected-error {{address taken}}
+ X2<iarr> x2b; // expected-error {{cannot bind to template argument of type 'int [10]'}}
+ X2<&iarr> x2b_addr; // expected-error {{address taken}}
+ X2<ki> x2c; // expected-error {{ignores qualifiers}} expected-warning {{internal linkage is a C++11 extension}}
+ X2k<ki> x2kc; // expected-warning {{internal linkage is a C++11 extension}}
+ X2k<&ki> x2kc_addr; // expected-error {{address taken}} expected-warning {{internal linkage is a C++11 extension}}
+ X2<ti> x2d_addr; // expected-error {{refers to thread-local object}}
+ X3<f> x3a;
+ X3<&f> x3a_addr; // expected-error {{address taken}}
+ X3<f_tmpl> x3b;
+ X3<&f_tmpl> x3b_addr; // expected-error {{address taken}}
+ X3<f_tmpl<int> > x3c;
+ X3<&f_tmpl<int> > x3c_addr; // expected-error {{address taken}}
+ X3<f_internal> x3d; // expected-warning {{internal linkage is a C++11 extension}}
+ X3<&f_internal> x3d_addr; // expected-error {{address taken}} expected-warning {{internal linkage is a C++11 extension}}
+
+ int n; // expected-note {{here}}
+ X0<&n> x0_no_linkage; // expected-error {{non-type template argument refers to object 'n' that does not have linkage}}
+ struct Local { static int f() {} }; // expected-note {{here}}
+ X1<&Local::f> x1_no_linkage; // expected-error {{non-type template argument refers to function 'f' that does not have linkage}}
+ }
+}
+
+// -- a constant expression that evaluates to a null pointer value (4.10); or
+// -- a constant expression that evaluates to a null member pointer value
+// (4.11); or
+// -- a pointer to member expressed as described in 5.3.1.
+
+namespace bad_args {
+ template <int* N> struct X0 { }; // expected-note 2{{template parameter is declared here}}
+ int i = 42;
+ X0<&i + 2> x0a; // expected-error{{non-type template argument does not refer to any declaration}}
+ int* iptr = &i;
+ X0<iptr> x0b; // expected-error{{non-type template argument for template parameter of pointer type 'int *' must have its address taken}}
+}
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
new file mode 100644
index 0000000..9b9b532
--- /dev/null
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
@@ -0,0 +1,205 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [temp.arg.nontype] p5:
+// The following conversions are performed on each expression used as
+// a non-type template-argument. If a non-type template-argument cannot be
+// converted to the type of the corresponding template-parameter then the
+// program is ill-formed.
+// -- for a non-type template-parameter of integral or enumeration type,
+// integral promotions (4.5) and integral conversions (4.7) are applied.
+namespace integral_parameters {
+ template<short s> struct X0 { };
+ X0<17> x0i;
+ X0<'a'> x0c;
+ template<char c> struct X1 { };
+ X1<100l> x1l;
+}
+
+// -- for a non-type template-parameter of type pointer to object,
+// qualification conversions (4.4) and the array-to-pointer conversion
+// (4.2) are applied; if the template-argument is of type
+// std::nullptr_t, the null pointer conversion (4.10) is applied.
+namespace pointer_to_object_parameters {
+ // PR6226
+ struct Str {
+ Str(const char *);
+ };
+
+ template<const char *s>
+ struct A {
+ Str get() { return s; }
+ };
+
+ char hello[6] = "Hello";
+ extern const char world[6];
+ const char world[6] = "world";
+ void test() {
+ (void)A<hello>().get();
+ (void)A<world>().get();
+ }
+
+ class X {
+ public:
+ X();
+ X(int, int);
+ operator int() const;
+ };
+
+ template<X const *Ptr> struct A2; // expected-note{{template parameter is declared here}}
+
+ X *X_ptr;
+ X an_X;
+ X array_of_Xs[10];
+ 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-warning{{address non-type template argument cannot be surrounded by parentheses}}
+
+ // PR6244
+ struct X1 {} X1v;
+ template <X1*> struct X2 { };
+ template <X1* Value> struct X3 : X2<Value> { };
+ struct X4 : X3<&X1v> { };
+
+ // PR6563
+ int *bar;
+ template <int *> struct zed {}; // expected-note 2{{template parameter is declared here}}
+ void g(zed<bar>*); // expected-error{{must have its address taken}}
+
+ int baz;
+ void g2(zed<baz>*); // expected-error{{must have its address taken}}
+
+ void g3(zed<&baz>*); // okay
+}
+
+// -- For a non-type template-parameter of type reference to object, no
+// conversions apply. The type referred to by the reference may be more
+// cv-qualified than the (otherwise identical) type of the
+// template-argument. The template-parameter is bound directly to the
+// template-argument, which shall be an lvalue.
+namespace reference_parameters {
+ template <int& N> struct S0 { }; // expected-note 3 {{template parameter is declared here}}
+ template <const int& N> struct S1 { }; // expected-note 2 {{template parameter is declared here}}
+ template <volatile int& N> struct S2 { }; // expected-note 2 {{template parameter is declared here}}
+ template <const volatile int& N> struct S3 { };
+ int i;
+ extern const int ci;
+ volatile int vi;
+ 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 '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 '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 '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 'volatile int &' to template argument of type 'const volatile int' ignores qualifiers}}
+
+ S3<i> s3;
+ S3<ci> s3c;
+ S3<vi> s3v;
+ S3<cvi> s3cv;
+ }
+
+ namespace PR6250 {
+ template <typename T, const T &ref> void inc() {
+ ref++; // expected-error{{read-only variable is not assignable}}
+ }
+
+ template<typename T, const T &ref> void bind() {
+ T &ref2 = ref; // expected-error{{drops qualifiers}}
+ }
+
+ int counter;
+ void test() {
+ inc<int, counter>(); // expected-note{{instantiation of}}
+ bind<int, counter>(); // expected-note{{instantiation of}}
+ }
+ }
+
+ namespace PR6749 {
+ template <int& i> struct foo {}; // expected-note{{template parameter is declared here}}
+ int x, &y = x;
+ foo<y> f; // expected-error{{is not an object}}
+ }
+}
+
+// -- For a non-type template-parameter of type pointer to function, the
+// function-to-pointer conversion (4.3) is applied; if the
+// template-argument is of type std::nullptr_t, the null pointer
+// conversion (4.10) is applied. If the template-argument represents
+// a set of overloaded functions (or a pointer to such), the matching
+// function is selected from the set (13.4).
+namespace pointer_to_function {
+ template<int (*)(int)> struct X0 { }; // expected-note 3{{template parameter is declared here}}
+ int f(int);
+ int f(float);
+ int g(float);
+ int (*funcptr)(int);
+ void x0a(X0<f>);
+ void x0b(X0<&f>);
+ void x0c(X0<g>); // expected-error{{non-type template argument of type 'int (float)' cannot be converted to a value of type 'int (*)(int)'}}
+ void x0d(X0<&g>); // expected-error{{non-type template argument of type 'int (*)(float)' cannot be converted to a value of type 'int (*)(int)'}}
+ void x0e(X0<funcptr>); // expected-error{{must have its address taken}}
+}
+
+// -- For a non-type template-parameter of type reference to function, no
+// conversions apply. If the template-argument represents a set of
+// overloaded functions, the matching function is selected from the set
+// (13.4).
+namespace reference_to_function {
+ template<int (&)(int)> struct X0 { }; // expected-note 4{{template parameter is declared here}}
+ int f(int);
+ int f(float);
+ int g(float);
+ int (*funcptr)(int);
+ void x0a(X0<f>);
+ void x0b(X0<&f>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}}
+ void x0c(X0<g>); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (float)'}}
+ void x0d(X0<&g>); // expected-error{{address taken in non-type template argument for template parameter of reference type 'int (&)(int)'}}
+ void x0e(X0<funcptr>); // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'int (*)(int)'}}
+}
+// -- For a non-type template-parameter of type pointer to member function,
+// if the template-argument is of type std::nullptr_t, the null member
+// pointer conversion (4.11) is applied; otherwise, no conversions
+// apply. If the template-argument represents a set of overloaded member
+// functions, the matching member function is selected from the set
+// (13.4).
+namespace pointer_to_member_function {
+ struct X { };
+ struct Y : X {
+ int f(int);
+ int g(int);
+ int g(float);
+ float h(float);
+ };
+
+ template<int (Y::*)(int)> struct X0 {}; // expected-note{{template parameter is declared here}}
+ X0<&Y::f> x0a;
+ X0<&Y::g> x0b;
+ X0<&Y::h> x0c; // expected-error{{non-type template argument of type 'float (pointer_to_member_function::Y::*)(float)' cannot be converted to a value of type 'int (pointer_to_member_function::Y::*)(int)'}}
+}
+
+// -- For a non-type template-parameter of type pointer to data member,
+// qualification conversions (4.4) are applied; if the template-argument
+// is of type std::nullptr_t, the null member pointer conversion (4.11)
+// is applied.
+namespace pointer_to_member_data {
+ struct X { int x; };
+ struct Y : X { int y; };
+
+ template<int Y::*> struct X0 {}; // expected-note{{template parameter is declared here}}
+ X0<&Y::y> x0a;
+ X0<&Y::x> x0b; // expected-error{{non-type template argument of type 'int pointer_to_member_data::X::*' cannot be converted to a value of type 'int pointer_to_member_data::Y::*'}}
+
+ // Test qualification conversions
+ template<const int Y::*> struct X1 {};
+ X1<&Y::y> x1a;
+}
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
new file mode 100644
index 0000000..1c13bff
--- /dev/null
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.arg/temp.arg.type/p2-cxx0x.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.type/p2-cxx0x.cpp
new file mode 100644
index 0000000..b03ed46
--- /dev/null
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.type/p2-cxx0x.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+// C++03 imposed restrictions in this paragraph that were lifted with 0x, so we
+// just test that the example given now parses cleanly.
+
+template <class T> class X { };
+template <class T> void f(T t) { }
+struct { } unnamed_obj;
+void f() {
+ struct A { };
+ enum { e1 };
+ typedef struct { } B;
+ B b;
+ X<A> x1;
+ X<A*> x2;
+ X<B> x3;
+ f(e1);
+ f(unnamed_obj);
+ f(b);
+}
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp
new file mode 100644
index 0000000..0fd9a7e
--- /dev/null
+++ b/clang/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/clang/test/CXX/temp/temp.decls/p3.cpp b/clang/test/CXX/temp/temp.decls/p3.cpp
new file mode 100644
index 0000000..41811ff
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/p3.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+template<typename T> using A = int;
+template<typename T> using A<T*> = char; // expected-error {{partial specialization of alias templates is not permitted}}
+template<> using A<char> = char; // expected-error {{explicit specialization of alias templates is not permitted}}
+template using A<char> = char; // expected-error {{explicit instantiation of alias templates is not permitted}}
+using A<char> = char; // expected-error {{name defined in alias declaration must be an identifier}}
diff --git a/clang/test/CXX/temp/temp.decls/temp.alias/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.alias/p1.cpp
new file mode 100644
index 0000000..966e3c1
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.alias/p1.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+template<typename T> using U = T;
+
+// The name of the alias template is a template-name.
+U<char> x;
+void f(U<int>);
+typedef U<U<U<U<int>>>> I;
diff --git a/clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp b/clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp
new file mode 100644
index 0000000..a5b39fe
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.alias/p2.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+template<typename T> using U = T;
+
+using I = U<U<U<U<int>>>>;
+using I = int;
+
+template<typename A, typename B> using Fst = A;
+template<typename A, typename B> using Snd = B;
+
+using I = Fst<Snd<char,int>,double>;
+
+namespace StdExample {
+ // Prerequisites for example.
+ template<class T, class A> struct vector { /* ... */ };
+
+
+ template<class T> struct Alloc {};
+ template<class T> using Vec = vector<T, Alloc<T>>;
+ Vec<int> v;
+
+ template<class T>
+ void process(Vec<T>& v) // expected-note {{previous definition is here}}
+ { /* ... */ }
+
+ template<class T>
+ void process(vector<T, Alloc<T>>& w) // expected-error {{redefinition of 'process'}}
+ { /* ... */ }
+
+ template<template<class> class TT>
+ void f(TT<int>); // expected-note {{candidate template ignored}}
+
+ template<template<class,class> class TT>
+ void g(TT<int, Alloc<int>>);
+
+ int h() {
+ f(v); // expected-error {{no matching function for call to 'f'}}
+ g(v); // OK: TT = vector
+ }
+
+
+ // v's type is same as vector<int, Alloc<int>>.
+ using VTest = vector<int, Alloc<int>>;
+ using VTest = decltype(v);
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp b/clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp
new file mode 100644
index 0000000..afd9b4b
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.alias/p3.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+// The example given in the standard (this is rejected for other reasons anyway).
+template<class T> struct A;
+template<class T> using B = typename A<T>::U; // expected-error {{no type named 'U' in 'A<T>'}}
+template<class T> struct A {
+ typedef B<T> U; // expected-note {{in instantiation of template type alias 'B' requested here}}
+};
+B<short> b;
+
+template<typename T> using U = int;
+// FIXME: This is illegal, but probably only because CWG1044 missed this paragraph.
+template<typename T> using U = U<T>;
diff --git a/clang/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp
new file mode 100644
index 0000000..d0fc797
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp
@@ -0,0 +1,76 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Test class template partial specializations of member templates.
+template<typename T>
+struct X0 {
+ template<typename U> struct Inner0 {
+ static const unsigned value = 0;
+ };
+
+ template<typename U> struct Inner0<U*> {
+ static const unsigned value = 1;
+ };
+};
+
+template<typename T> template<typename U>
+struct X0<T>::Inner0<const U*> {
+ static const unsigned value = 2;
+};
+
+int array0[X0<int>::Inner0<int>::value == 0? 1 : -1];
+int array1[X0<int>::Inner0<int*>::value == 1? 1 : -1];
+int array2[X0<int>::Inner0<const int*>::value == 2? 1 : -1];
+
+// Make sure we can provide out-of-line class template partial specializations
+// for member templates (and instantiate them).
+template<class T> struct A {
+ struct C {
+ template<class T2> struct B;
+ };
+};
+
+// partial specialization of A<T>::C::B<T2>
+template<class T> template<class T2> struct A<T>::C::B<T2*> { };
+
+A<short>::C::B<int*> absip;
+
+// Check for conflicts during template instantiation.
+template<typename T, typename U>
+struct Outer {
+ template<typename X, typename Y> struct Inner;
+ template<typename Y> struct Inner<T, Y> {}; // expected-note{{previous}}
+ template<typename Y> struct Inner<U, Y> {}; // expected-error{{cannot be redeclared}}
+};
+
+Outer<int, int> outer; // expected-note{{instantiation}}
+
+// Test specialization of class template partial specialization members.
+template<> template<typename Z>
+struct X0<float>::Inner0<Z*> {
+ static const unsigned value = 3;
+};
+
+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/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
new file mode 100644
index 0000000..aa1e2d4
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-0x.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.decls/temp.class.spec/p9-0x.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/p9-0x.cpp
new file mode 100644
index 0000000..b754368
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class.spec/p9-0x.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.decls/temp.class.spec/p9.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/p9.cpp
new file mode 100644
index 0000000..2a3e914
--- /dev/null
+++ b/clang/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/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp
new file mode 100644
index 0000000..97457ea
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.order/p2.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<int I, int J, class T> struct X {
+ static const int value = 0;
+};
+
+template<int I, int J> struct X<I, J, int> {
+ static const int value = 1;
+};
+
+template<int I> struct X<I, I, int> {
+ static const int value = 2;
+};
+
+int array0[X<0, 0, float>::value == 0? 1 : -1];
+int array1[X<0, 1, int>::value == 1? 1 : -1];
+int array2[X<0, 0, int>::value == 2? 1 : -1];
+
+namespace DependentSubstPartialOrdering {
+ template<typename T, typename U = void, typename V = void>
+ struct X {
+ static const unsigned value = 1;
+ };
+
+ template<typename T, typename U>
+ struct X<T, U, typename T::is_b> {
+ static const unsigned value = 2;
+ };
+
+ template<typename T>
+ struct X<T, typename T::is_a, typename T::is_b> {
+ static const unsigned value = 3;
+ };
+
+ struct X1 { };
+
+ struct X2 {
+ typedef void is_b;
+ };
+
+ struct X3 {
+ typedef void is_a;
+ typedef void is_b;
+ };
+
+ int check_X1[X<X1, void, void>::value == 1? 1 : -1];
+ int check_X2[X<X2, void, void>::value == 2? 1 : -1];
+ int check_X3[X<X3, void, void>::value == 3? 1 : -1];
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1-neg.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1-neg.cpp
new file mode 100644
index 0000000..59253db
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1-neg.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T, int N>
+struct A;
+
+template<typename T> // expected-note{{previous template declaration}}
+struct A<T*, 2> {
+ void f0();
+ void f1();
+ void f2();
+};
+
+template<>
+struct A<int, 1> {
+ void g0();
+};
+
+// FIXME: We should probably give more precise diagnostics here, but the
+// diagnostics we give aren't terrible.
+// FIXME: why not point to the first parameter that's "too many"?
+template<typename T, int N> // expected-error{{too many template parameters}}
+void A<T*, 2>::f0() { }
+
+template<typename T, int N>
+void A<T, N>::f1() { } // expected-error{{out-of-line definition}}
diff --git a/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp
new file mode 100644
index 0000000..87e21e4
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class.spec/temp.class.spec.mfunc/p1.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, int N>
+struct A;
+
+template<typename T>
+struct A<T*, 2> {
+ A(T);
+ ~A();
+
+ void f(T*);
+
+ operator T*();
+
+ static T value;
+};
+
+template<class X> void A<X*, 2>::f(X*) { }
+
+template<class X> X A<X*, 2>::value;
+
+template<class X> A<X*, 2>::A(X) { value = 0; }
+
+template<class X> A<X*, 2>::~A() { }
+
+template<class X> A<X*, 2>::operator X*() { return 0; }
diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp
new file mode 100644
index 0000000..b65e1d0
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.class/p1.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T, typename U>
+struct X0 {
+ struct Inner;
+};
+
+template<typename T, typename U>
+struct X0<T, U>::Inner {
+ T x;
+ U y;
+
+ void f() { x = y; } // expected-error{{incompatible}}
+};
+
+
+void test(int i, float f) {
+ X0<int, float>::Inner inner;
+ inner.x = 5;
+ inner.y = 3.4;
+ inner.f();
+
+ X0<int*, float *>::Inner inner2;
+ inner2.x = &i;
+ inner2.y = &f;
+ inner2.f(); // expected-note{{instantiation}}
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
new file mode 100644
index 0000000..f8cc009
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.enum/p1.cpp
@@ -0,0 +1,152 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+template<typename T> struct A {
+ enum E : T; // expected-note {{here}}
+ E v;
+ E f() { return A::e1; } // expected-error {{no member named 'e1' in 'A<T>'}}
+ E g() { return E::e1; }
+ E h();
+};
+
+A<int> a;
+A<int>::E a0 = A<int>().v;
+int n = A<int>::E::e1; // expected-error {{implicit instantiation of undefined member}}
+
+template<typename T> enum A<T>::E : T { e1, e2 };
+
+// FIXME: Now that A<T>::E is defined, we are supposed to inject its enumerators
+// into the already-instantiated class A<T>. This seems like a really bad idea,
+// though, so we don't implement that, but what we do implement is inconsistent.
+//
+// Either do as the standard says, or only include enumerators lexically defined
+// within the class in its scope.
+A<int>::E a1 = A<int>::e1; // expected-error {{no member named 'e1' in 'A<int>'}}
+
+A<char>::E a2 = A<char>::e2;
+
+template<typename T> typename A<T>::E A<T>::h() { return e2; }
+A<short>::E a3 = A<short>().h();
+
+
+template<typename T> struct B {
+ enum class E;
+ E v;
+ E f() { return E::e1; }
+ E g();
+};
+
+B<int> b;
+B<int>::E b0 = B<int>().v;
+
+template<typename T> enum class B<T>::E { e1, e2 };
+B<int>::E b1 = B<int>::E::e1;
+
+B<char>::E b2 = B<char>::E::e2;
+
+template<typename T> typename B<T>::E B<T>::g() { return e2; }
+B<short>::E b3 = B<short>().g();
+
+
+// Enumeration members of class templates can be explicitly specialized. For
+// unscoped enumerations, specializations must be defined before the primary
+// template is, since otherwise the primary template will be implicitly
+// instantiated when we parse the nested name specifier.
+template<> enum A<long long>::E : long long { e3, e4 }; // expected-error {{explicit specialization of 'E' after instantiation}} expected-note {{first required here}}
+
+template<> enum class B<long long>::E { e3, e4 };
+B<long long>::E b4 = B<long long>::E::e4;
+
+B<long>::E b5;
+template<> enum class B<long>::E { e5 };
+void fb5() { b5 = decltype(b5)::e5; }
+B<long>::E b6 = B<long>::E::e5;
+
+
+template<typename T> struct C {
+ enum class E : T;
+};
+
+template<> enum class C<long long>::E : long long { e3, e4 };
+C<long long>::E c0 = C<long long>::E::e3;
+
+C<long>::E c1;
+template<> enum class C<long>::E : long { e5 };
+void fc1() { c1 = decltype(c1)::e5; }
+C<long>::E c2 = C<long>::E::e5;
+
+template<> enum class C<int>::E : int { e6 };
+template<typename T> enum class C<T>::E : T { e0 };
+C<int>::E c3 = C<int>::E::e6;
+C<int>::E c4 = C<int>::E::e0; // expected-error {{no member named 'e0' in 'C<int>::E'}}
+
+
+// Enumeration members can't be partially-specialized.
+template<typename T> enum class B<T*>::E { e5, e6 }; // expected-error {{nested name specifier for a declaration cannot depend on a template parameter}}
+
+
+// Explicit specializations can be forward-declared.
+template<typename T>
+struct D {
+ enum class E { e1 };
+};
+template<> enum class D<int>::E;
+D<int>::E d1 = D<int>::E::e1; // expected-error {{incomplete type 'D<int>::E'}}
+template<> enum class D<int>::E { e2 };
+D<int>::E d2 = D<int>::E::e2;
+D<char>::E d3 = D<char>::E::e1; // expected-note {{first required here}}
+D<char>::E d4 = D<char>::E::e2; // expected-error {{no member named 'e2'}}
+template<> enum class D<char>::E { e3 }; // expected-error {{explicit specialization of 'E' after instantiation}}
+
+template<> enum class D<short>::E;
+struct F {
+ // Per C++11 [class.friend]p3, these friend declarations have no effect.
+ // Only classes and functions can be friends.
+ template<typename T> friend enum D<T>::E;
+ template<> friend enum D<short>::E;
+
+ template<> friend enum D<double>::E { e3 }; // expected-error {{cannot define a type in a friend declaration}}
+
+private:
+ static const int n = 1; // expected-note {{private here}}
+};
+template<> enum class D<short>::E {
+ e = F::n // expected-error {{private member}}
+};
+
+class Access {
+ friend class X;
+
+ template<typename T>
+ class Priv {
+ friend class X;
+
+ enum class E : T;
+ };
+
+ class S {
+ typedef int N; // expected-note {{here}}
+ static const int k = 3; // expected-note {{here}}
+
+ friend class Priv<char>;
+ };
+
+ static const int k = 5;
+};
+
+template<> enum class Access::Priv<Access::S::N>::E
+ : Access::S::N { // expected-error {{private member}}
+ a = Access::k, // ok
+ b = Access::S::k // expected-error {{private member}}
+};
+
+template<typename T> enum class Access::Priv<T>::E : T {
+ c = Access::k,
+ d = Access::S::k
+};
+
+class X {
+ Access::Priv<int>::E a = Access::Priv<int>::E::a;
+ Access::Priv<char>::E c = Access::Priv<char>::E::d;
+ // FIXME: We should see an access error for this enumerator.
+ Access::Priv<short>::E b = Access::Priv<short>::E::d;
+};
diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp
new file mode 100644
index 0000000..4c05c62
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1-retmem.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> struct X1 { };
+
+template<typename T>
+struct X0 {
+ typedef int size_type;
+ typedef T value_type;
+
+ size_type f0() const;
+ value_type *f1();
+ X1<value_type*> f2();
+};
+
+template<typename T>
+typename X0<T>::size_type X0<T>::f0() const {
+ return 0;
+}
+
+template<typename U>
+typename X0<U>::value_type *X0<U>::f1() {
+ return 0;
+};
+
+template<typename U>
+X1<typename X0<U>::value_type*> X0<U>::f2() {
+ return 0;
+};
diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp
new file mode 100644
index 0000000..1764563
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U> // expected-note{{previous template}}
+class X0 {
+public:
+ typedef int size_type;
+
+ X0(int);
+ ~X0();
+
+ void f0(const T&, const U&);
+
+ T& operator[](int i) const;
+
+ void f1(size_type) const;
+ void f2(size_type) const;
+ void f3(size_type) const;
+ void f4() ;
+
+ operator T*() const;
+
+ T value;
+};
+
+template<typename T, typename U>
+void X0<T, U>::f0(const T&, const U&) { // expected-note{{previous definition}}
+}
+
+template<class X, class Y>
+X& X0<X, Y>::operator[](int i) const {
+ (void)i;
+ return value;
+}
+
+template<class X, class Y>
+void X0<X, Y>::f1(int) const { }
+
+template<class X, class Y>
+void X0<X, Y>::f2(size_type) const { }
+
+template<class X, class Y, class Z> // expected-error{{too many template parameters}}
+void X0<X, Y>::f3(size_type) const {
+}
+
+template<class X, class Y>
+void X0<Y, X>::f4() { } // expected-error{{does not refer}}
+
+// FIXME: error message should probably say, "redefinition of 'X0<T, U>::f0'"
+// rather than just "redefinition of 'f0'"
+template<typename T, typename U>
+void X0<T, U>::f0(const T&, const U&) { // expected-error{{redefinition}}
+}
+
+// Test out-of-line constructors, destructors
+template<typename T, typename U>
+X0<T, U>::X0(int x) : value(x) { }
+
+template<typename T, typename U>
+X0<T, U>::~X0() { }
+
+// Test out-of-line conversion functions.
+template<typename T, typename U>
+X0<T, U>::operator T*() const {
+ return &value;
+}
+
+namespace N { template <class X> class A {void a();}; }
+namespace N { template <class X> void A<X>::a() {} }
+
+// PR5566
+template<typename T>
+struct X1 {
+ template<typename U>
+ struct B { void f(); };
+};
+
+template<typename T>
+template<typename U>
+void X1<T>::template B<U>::f() { }
+
+// PR5527
+template <template <class> class T>
+class X2 {
+ template <class F>
+ class Bar {
+ void Func();
+ };
+};
+
+template <template <class> class T>
+template <class F>
+void X2<T>::Bar<F>::Func() {}
+
+// PR5528
+template <template <class> class T>
+class X3 {
+ void F();
+};
+
+template <template <class> class T>
+void X3<T>::F() {}
diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp
new file mode 100644
index 0000000..f09faa9
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/p1inst.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// Test instantiation of member functions of class templates defined out-of-line
+template<typename T, typename U>
+struct X0 {
+ void f(T *t, const U &u);
+ void f(T *);
+};
+
+template<typename T, typename U>
+void X0<T, U>::f(T *t, const U &u) {
+ *t = u; // expected-error{{not assignable}}
+}
+
+void test_f(X0<float, int> xfi, X0<void, int> xvi, float *fp, void *vp, int i) {
+ xfi.f(fp, i);
+ xvi.f(vp, i); // expected-note{{instantiation}}
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp
new file mode 100644
index 0000000..70c9c70
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.mem.func/pr5056.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+extern "C" void * malloc(int);
+
+template <typename T> struct A {
+ void *malloc(int);
+};
+
+template <typename T>
+inline void *A<T>::malloc(int)
+{
+ return 0;
+}
+
+void f() {
+ malloc(10);
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp
new file mode 100644
index 0000000..9fc4a58
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1-inst.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Test instantiation of static data members declared out-of-line.
+
+template<typename T>
+struct X {
+ static T value;
+};
+
+template<typename T>
+ T X<T>::value = 17; // expected-error{{no viable conversion}}
+
+struct InitOkay {
+ InitOkay(int) { }
+};
+
+struct CannotInit { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
+
+int &returnInt() { return X<int>::value; }
+float &returnFloat() { return X<float>::value; }
+
+InitOkay &returnInitOkay() { return X<InitOkay>::value; }
+
+unsigned long sizeOkay() { return sizeof(X<CannotInit>::value); }
+
+CannotInit &returnError() {
+ return X<CannotInit>::value; // expected-note{{instantiation}}
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
new file mode 100644
index 0000000..2eae112
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.class/temp.static/p1.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 {
+ static T value;
+};
+
+template<typename T>
+T X0<T>::value = 0; // expected-error{{no viable conversion}}
+
+struct X1 {
+ X1(int);
+};
+
+struct X2 { }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
+
+int& get_int() { return X0<int>::value; }
+X1& get_X1() { return X0<X1>::value; }
+
+double*& get_double_ptr() { return X0<int*>::value; } // expected-error{{non-const lvalue reference to type 'double *' cannot bind to a value of unrelated type 'int *'}}
+
+X2& get_X2() {
+ return X0<X2>::value; // expected-note{{instantiation}}
+}
+
+template<typename T> T x; // expected-error{{variable 'x' declared as a template}}
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3-0x.cpp
new file mode 100644
index 0000000..63909fb
--- /dev/null
+++ b/clang/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++11 %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/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p3.cpp
new file mode 100644
index 0000000..2ffdd95
--- /dev/null
+++ b/clang/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/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p4.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p4.cpp
new file mode 100644
index 0000000..b2a6219
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p4.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T> struct A { A(); };
+template<class T> int &f(T);
+template<class T> float &f(T*);
+template<class T> double &f(const T*);
+
+template<class T> void g(T); // expected-note{{candidate}}
+template<class T> void g(T&); // expected-note{{candidate}}
+
+template<class T> int &h(const T&);
+template<class T> float &h(A<T>&);
+
+void m() {
+ const int *p;
+ double &dr1 = f(p);
+ float x;
+ g(x); // expected-error{{ambiguous}}
+ A<int> z;
+ float &fr1 = h(z);
+ const A<int> z2;
+ int &ir1 = h(z2);
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p5.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p5.cpp
new file mode 100644
index 0000000..4d34968
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.func.order/p5.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<class T> int &f(T);
+template<class T> float &f(T*, int=1);
+
+template<class T> int &g(T);
+template<class T> float &g(T*, ...);
+
+int main() {
+ int* ip;
+ float &fr1 = f(ip);
+ float &fr2 = g(ip);
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp
new file mode 100644
index 0000000..e9a3eaa
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4-neg.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> void f0(T) { } // expected-note{{previous}}
+template<class U> void f0(U) { } // expected-error{{redefinition}}
+
+template<int I> void f0() { } // expected-note{{previous}}
+template<int> void f0() { } // expected-error{{redefinition}}
+
+typedef int INT;
+
+template<template<class T, T Value1, INT> class X>
+ void f0() { } // expected-note{{previous}}
+template<template<typename T, T Value1, int> class>
+ void f0() { } // expected-error{{redefinition}}
+
+template<typename T>
+struct MetaFun;
+
+template<typename T>
+ typename MetaFun<T*>::type f0(const T&) { while (1) {} } // expected-note{{previous}}
+template<class U>
+ typename MetaFun<U*>::type f0(const U&) { while (1) {} } // expected-error{{redefinition}}
+
+// FIXME: We need canonicalization of expressions for this to work
+// template<int> struct A { };
+// template<int I> void f0(A<I>) { } // Xpected-note{{previous}}
+// template<int J> void f0(A<J>) { } // Xpected-error{{redefinition}}
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp
new file mode 100644
index 0000000..f42b94a
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p4.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// All of these function templates are distinct.
+template<typename T> void f0(T) { }
+template<typename T, typename U> void f0(T) { }
+template<typename T, typename U> void f0(U) { }
+void f0();
+template<typename T> void f0(T*);
+void f0(int);
+template<int I> void f0();
+template<typename T> void f0();
+
+
diff --git a/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp b/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp
new file mode 100644
index 0000000..a668ada
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.fct/temp.over.link/p6.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<int N, int M>
+struct A0 {
+ void g0();
+};
+
+template<int X, int Y> void f0(A0<X, Y>) { } // expected-note{{previous}}
+template<int N, int M> void f0(A0<M, N>) { }
+template<int V1, int V2> void f0(A0<V1, V2>) { } // expected-error{{redefinition}}
+
+template<int X, int Y> void f1(A0<0, (X + Y)>) { } // expected-note{{previous}}
+template<int X, int Y> void f1(A0<0, (X - Y)>) { }
+template<int A, int B> void f1(A0<0, (A + B)>) { } // expected-error{{redefinition}}
+
+template<int X, int Y> void A0<X, Y>::g0() { }
diff --git a/clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp
new file mode 100644
index 0000000..63f569b
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.friend/p1.cpp
@@ -0,0 +1,358 @@
+// RUN: %clang_cc1 -verify -emit-llvm-only %s
+
+namespace test0 {
+template <typename T> struct Num {
+ T value_;
+
+public:
+ Num(T value) : value_(value) {}
+ T get() const { return value_; }
+
+ template <typename U> struct Rep {
+ U count_;
+ Rep(U count) : count_(count) {}
+
+ friend Num operator*(const Num &a, const Rep &n) {
+ Num x = 0;
+ for (U count = n.count_; count; --count)
+ x += a;
+ return x;
+ }
+ };
+
+ friend Num operator+(const Num &a, const Num &b) {
+ return a.value_ + b.value_;
+ }
+
+ Num& operator+=(const Num& b) {
+ value_ += b.value_;
+ return *this;
+ }
+
+ class Representation {};
+ friend class Representation;
+};
+
+class A {
+ template <typename T> friend bool iszero(const A &a) throw();
+};
+
+template <class T> class B_iterator;
+template <class T> class B {
+ friend class B_iterator<T>;
+};
+
+int calc1() {
+ Num<int> left = -1;
+ Num<int> right = 1;
+ Num<int> result = left + right;
+ return result.get();
+}
+
+int calc2() {
+ Num<int> x = 3;
+ Num<int>::Rep<char> n = (char) 10;
+ Num<int> result = x * n;
+ return result.get();
+}
+}
+
+// Reduced from GNU <locale>
+namespace test1 {
+ class A {
+ bool b; // expected-note {{declared private here}}
+ template <typename T> friend bool has(const A&);
+ };
+ template <typename T> bool has(const A &x) {
+ return x.b;
+ }
+ template <typename T> bool hasnot(const A &x) {
+ return x.b; // expected-error {{'b' is a private member of 'test1::A'}}
+ }
+}
+
+namespace test2 {
+ class A {
+ bool b; // expected-note {{declared private here}}
+ template <typename T> friend class HasChecker;
+ };
+ template <typename T> class HasChecker {
+ bool check(A *a) {
+ return a->b;
+ }
+ };
+ template <typename T> class HasNotChecker {
+ bool check(A *a) {
+ return a->b; // expected-error {{'b' is a private member of 'test2::A'}}
+ }
+ };
+}
+
+namespace test3 {
+ class Bool;
+ template <class T> class User;
+ template <class T> T transform(class Bool, T);
+
+ class Bool {
+ friend class User<bool>;
+ friend bool transform<>(Bool, bool);
+
+ bool value; // expected-note 2 {{declared private here}}
+ };
+
+ template <class T> class User {
+ static T compute(Bool b) {
+ return b.value; // expected-error {{'value' is a private member of 'test3::Bool'}}
+ }
+ };
+
+ template <class T> T transform(Bool b, T value) {
+ if (b.value) // expected-error {{'value' is a private member of 'test3::Bool'}}
+ return value;
+ return value + 1;
+ }
+
+ template bool transform(Bool, bool);
+ template int transform(Bool, int); // expected-note {{requested here}}
+
+ template class User<bool>;
+ template class User<int>; // expected-note {{requested here}}
+}
+
+namespace test4 {
+ template <class T> class A {
+ template <class T0> friend class B;
+ bool foo(const A<T> *) const;
+ };
+
+ template <class T> class B {
+ bool bar(const A<T> *a, const A<T> *b) {
+ return a->foo(b);
+ }
+ };
+
+ template class B<int>;
+}
+
+namespace test5 {
+ template <class T, class U=int> class A {};
+ template <class T> class B {
+ template <class X, class Y> friend class A;
+ };
+ template class B<int>;
+ template class A<int>;
+}
+
+namespace Dependent {
+ template<typename T, typename Traits> class X;
+ template<typename T, typename Traits>
+ X<T, Traits> operator+(const X<T, Traits>&, const T*);
+
+ template<typename T, typename Traits> class X {
+ typedef typename Traits::value_type value_type;
+ friend X operator+<>(const X&, const value_type*);
+ };
+}
+
+namespace test7 {
+ template <class T> class A { // expected-note {{declared here}}
+ friend class B;
+ int x; // expected-note {{declared private here}}
+ };
+
+ class B {
+ int foo(A<int> &a) {
+ return a.x;
+ }
+ };
+
+ class C {
+ int foo(A<int> &a) {
+ return a.x; // expected-error {{'x' is a private member of 'test7::A<int>'}}
+ }
+ };
+
+ // This shouldn't crash.
+ template <class T> class D {
+ friend class A; // expected-error {{elaborated type refers to a template}}
+ };
+ template class D<int>;
+}
+
+namespace test8 {
+ template <class N> class A {
+ static int x;
+ template <class T> friend void foo();
+ };
+ template class A<int>;
+
+ template <class T> void foo() {
+ A<int>::x = 0;
+ }
+ template void foo<int>();
+}
+
+namespace test9 {
+ template <class T> class A {
+ class B; class C;
+
+ int foo(B *b) {
+ return b->x;
+ }
+
+ int foo(C *c) {
+ return c->x; // expected-error {{'x' is a private member}}
+ }
+
+ class B {
+ int x;
+ friend int A::foo(B*);
+ };
+
+ class C {
+ int x; // expected-note {{declared private here}}
+ };
+ };
+
+ template class A<int>; // expected-note {{in instantiation}}
+}
+
+namespace test10 {
+ template <class T> class A;
+ template <class T> A<T> bar(const T*, const A<T>&);
+ template <class T> class A {
+ private:
+ void foo(); // expected-note {{declared private here}}
+ friend A bar<>(const T*, const A<T>&);
+ };
+
+ template <class T> A<T> bar(const T *l, const A<T> &r) {
+ A<T> l1;
+ l1.foo();
+
+ A<char> l2;
+ l2.foo(); // expected-error {{'foo' is a private member of 'test10::A<char>'}}
+
+ return l1;
+ }
+
+ template A<int> bar<int>(const int *, const A<int> &); // expected-note {{in instantiation}}
+}
+
+// PR6752: this shouldn't crash.
+namespace test11 {
+ struct Foo {
+ template<class A>
+ struct IteratorImpl {
+ template<class T> friend class IteratorImpl;
+ };
+ };
+
+ template struct Foo::IteratorImpl<int>;
+ template struct Foo::IteratorImpl<long>;
+}
+
+// PR6827
+namespace test12 {
+ template <typename T> class Foo;
+ template <typename T> Foo<T> foo(T* t){ return Foo<T>(t, true); }
+
+ template <typename T> class Foo {
+ public:
+ Foo(T*);
+ friend Foo<T> foo<T>(T*);
+ private:
+ Foo(T*, bool); // expected-note {{declared private here}}
+ };
+
+ // Should work.
+ int globalInt;
+ Foo<int> f = foo(&globalInt);
+
+ // Shouldn't work.
+ long globalLong;
+ template <> Foo<long> foo(long *t) {
+ Foo<int> s(&globalInt, false); // expected-error {{calling a private constructor}}
+ return Foo<long>(t, true);
+ }
+}
+
+// PR6514
+namespace test13 {
+ template <int N, template <int> class Temp>
+ class Role : public Temp<N> {
+ friend class Temp<N>;
+ int x;
+ };
+
+ template <int N> class Foo {
+ void foo(Role<N, test13::Foo> &role) {
+ (void) role.x;
+ }
+ };
+
+ 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}}
+}
+
+namespace PR10913 {
+ template<class T> class X;
+
+ template<class T> void f(X<T> *x) {
+ x->member = 0;
+ }
+
+ template<class U, class T> void f2(X<T> *x) {
+ x->member = 0; // expected-error{{'member' is a protected member of 'PR10913::X<int>'}}
+ }
+
+ template<class T> class X {
+ friend void f<T>(X<T> *x);
+ friend void f2<T>(X<int> *x);
+
+ protected:
+ int member; // expected-note{{declared protected here}}
+ };
+
+ template void f(X<int> *);
+ template void f2<int>(X<int> *);
+ template void f2<float>(X<int> *); // expected-note{{in instantiation of function template specialization 'PR10913::f2<float, int>' requested here}}
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.friend/p3.cpp b/clang/test/CXX/temp/temp.decls/temp.friend/p3.cpp
new file mode 100644
index 0000000..0b2a25e
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.friend/p3.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <class T> class A {
+ typedef int Member;
+};
+
+class B {
+ template <class T> friend class A;
+ template <class T> friend class Undeclared;
+
+ template <class T> friend typename A<T>::Member; // expected-error {{friend type templates must use an elaborated type}}
+};
diff --git a/clang/test/CXX/temp/temp.decls/temp.friend/p4.cpp b/clang/test/CXX/temp/temp.decls/temp.friend/p4.cpp
new file mode 100644
index 0000000..e036cef
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.friend/p4.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X1 {
+ friend void f6(int) { } // expected-error{{redefinition of}} \
+ // expected-note{{previous definition}}
+};
+
+X1<int> x1a;
+X1<float> x1b; // expected-note {{in instantiation of}}
+
+template<typename T>
+struct X2 {
+ operator int();
+
+ friend void f(int x) { } // expected-error{{redefinition}} \
+ // expected-note{{previous definition}}
+};
+
+int array0[sizeof(X2<int>)];
+int array1[sizeof(X2<float>)]; // expected-note{{instantiation of}}
+
+void g() {
+ X2<int> xi;
+ f(xi);
+ X2<float> xf;
+ f(xf);
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.friend/p5.cpp b/clang/test/CXX/temp/temp.decls/temp.friend/p5.cpp
new file mode 100644
index 0000000..63fd3df
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.friend/p5.cpp
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace test0 {
+ template <class T> class A {
+ class 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();
+ };
+
+ template <class> struct B {};
+ template class A<B>;
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.friend/p8.cpp b/clang/test/CXX/temp/temp.decls/temp.friend/p8.cpp
new file mode 100644
index 0000000..d0221a3
--- /dev/null
+++ b/clang/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/clang/test/CXX/temp/temp.decls/temp.mem/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.mem/p1.cpp
new file mode 100644
index 0000000..f5f1205
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.mem/p1.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <class T> struct A {
+ static T cond;
+
+ template <class U> struct B {
+ static T twice(U value) {
+ return (cond ? value + value : value);
+ }
+ };
+};
+
+int foo() {
+ A<bool>::cond = true;
+ return A<bool>::B<int>::twice(4);
+}
+
+namespace PR6376 {
+ template<typename T>
+ struct X {
+ template<typename Y>
+ struct Y1 { }; //
+ };
+
+ template<>
+ struct X<float> {
+ template<typename Y>
+ struct Y1 { };
+ };
+
+ template<typename T, typename U>
+ struct Z : public X<T>::template Y1<U> { };
+
+ Z<float, int> z0;
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.mem/p3.cpp b/clang/test/CXX/temp/temp.decls/temp.mem/p3.cpp
new file mode 100644
index 0000000..0eb747b
--- /dev/null
+++ b/clang/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/clang/test/CXX/temp/temp.decls/temp.mem/p5.cpp b/clang/test/CXX/temp/temp.decls/temp.mem/p5.cpp
new file mode 100644
index 0000000..8bcd773
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.mem/p5.cpp
@@ -0,0 +1,79 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A {
+ template <class T> operator T*();
+};
+
+template <class T> A::operator T*() { return 0; }
+template <> A::operator char*(){ return 0; } // specialization
+template A::operator void*(); // explicit instantiation
+
+int main() {
+ A a;
+ int *ip;
+ ip = a.operator int*();
+}
+
+// PR5742
+namespace PR5742 {
+ template <class T> struct A { };
+ template <class T> struct B { };
+
+ struct S {
+ template <class T> operator T();
+ } s;
+
+ void f() {
+ s.operator A<A<int> >();
+ s.operator A<B<int> >();
+ s.operator A<B<A<int> > >();
+ }
+}
+
+// PR5762
+class Foo {
+ public:
+ template <typename T> operator T();
+
+ template <typename T>
+ T As() {
+ return this->operator T();
+ }
+
+ template <typename T>
+ T As2() {
+ return operator T();
+ }
+
+ int AsInt() {
+ return this->operator int();
+ }
+};
+
+template float Foo::As();
+template double Foo::As2();
+
+// Partial ordering with conversion function templates.
+struct X0 {
+ template<typename T> operator T*() {
+ T x = 1;
+ x = 17; // expected-error{{read-only variable is not assignable}}
+ }
+
+ template<typename T> operator T*() const; // expected-note{{explicit instantiation refers here}}
+
+ template<typename T> operator const T*() const {
+ T x = T();
+ return x; // expected-error{{cannot initialize return object of type 'const char *' with an lvalue of type 'char'}} \
+ // expected-error{{cannot initialize return object of type 'const int *' with an lvalue of type 'int'}}
+ }
+};
+
+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) {
+ x0.operator const int*(); // expected-note{{in instantiation of function template specialization}}
+ x0.operator float *();
+ x0c.operator const char*();
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/deduction.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/deduction.cpp
new file mode 100644
index 0000000..fec8060
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/deduction.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.decls/temp.variadic/example-bind.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/example-bind.cpp
new file mode 100644
index 0000000..db28eea
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/example-bind.cpp
@@ -0,0 +1,352 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp
new file mode 100644
index 0000000..e15203a
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/example-function.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp
new file mode 100644
index 0000000..9de5fa8
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/example-tuple.cpp
@@ -0,0 +1,260 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp
new file mode 100644
index 0000000..6d9d8c5
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/ext-blocks.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -std=c++11 -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);
+
+template<typename ...Args>
+int PR9953(Args ...args) {
+ return ^(Args *...block_args) {
+ return f1(block_args); // expected-error{{expression contains unexpanded parameter pack 'block_args'}}
+ }(&args...);
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
new file mode 100644
index 0000000..fb72754
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
@@ -0,0 +1,127 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+template<typename T, typename U> struct pair { };
+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;
+};
+
+namespace ExpandIntoFixed {
+ template<typename T,
+ typename U,
+ typename V = pair<T, U>,
+ typename W = V*>
+ class X0 { };
+
+ template<typename ...Ts>
+ class X1 {
+ public:
+ typedef X0<Ts...> type;
+ };
+
+ static_assert(is_same<X1<int, int>::type,
+ X0<int, int, pair<int, int>, pair<int, int>*>>::value,
+ "fails with two default arguments");
+
+ static_assert(is_same<X1<int, int, float>::type,
+ X0<int, int, float, float*>>::value,
+ "fails with one default argument");
+
+ static_assert(is_same<X1<int, int, float, double>::type,
+ X0<int, int, float, double>>::value,
+ "fails with no default arguments");
+}
+
+namespace ExpandIntoFixedShifted {
+ template<typename T,
+ typename U,
+ typename V = pair<T, U>,
+ typename W = V*>
+ class X0 { };
+
+ template<typename ...Ts>
+ class X1 {
+ public:
+ typedef X0<char, Ts...> type;
+ };
+
+ static_assert(is_same<X1<int>::type,
+ X0<char, int, pair<char, int>, pair<char, int>*>>::value,
+ "fails with two default arguments");
+
+ static_assert(is_same<X1<int, float>::type,
+ X0<char, int, float, float*>>::value,
+ "fails with one default argument");
+
+ static_assert(is_same<X1<int, float, double>::type,
+ X0<char, int, float, double>>::value,
+ "fails with no default arguments");
+}
+
+namespace Deduction {
+ template <typename X, typename Y = double> struct Foo {};
+ template <typename ...Args> tuple<Args...> &foo(Foo<Args...>);
+
+ void call_foo(Foo<int, float> foo_if, Foo<int> foo_i) {
+ tuple<int, float> &t1 = foo(foo_if);
+ tuple<int, double> &t2 = foo(foo_i);
+ }
+}
+
+namespace PR9021a {
+ template<typename, typename>
+ struct A { };
+
+ template<typename ...T>
+ struct B {
+ A<T...> a1;
+ };
+
+ void test() {
+ B<int, int> c;
+ }
+}
+
+namespace PR9021b {
+ template<class, class>
+ struct t2
+ {
+
+ };
+
+ template<template<class...> class M>
+ struct m
+ {
+ template<class... B>
+ using inner = M<B...>;
+ };
+
+ m<t2> sta2;
+}
+
+namespace PartialSpecialization {
+ template<typename T, typename U, typename V = U>
+ struct X0; // expected-note{{template is declared here}}
+
+ template<typename ...Ts>
+ struct X0<Ts...> {
+ };
+
+ X0<int> x0i; // expected-error{{too few template arguments for class template 'X0'}}
+ X0<int, float> x0if;
+ X0<int, float, double> x0ifd;
+}
+
+namespace FixedAliasTemplate {
+ template<typename,typename,typename> struct S {};
+ template<typename T, typename U> using U = S<T, int, U>;
+ template<typename...Ts> U<Ts...> &f(U<Ts...>, Ts...);
+ S<int, int, double> &s1 = f({}, 0, 0.0);
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/injected-class-name.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/injected-class-name.cpp
new file mode 100644
index 0000000..b5786ac
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/injected-class-name.cpp
@@ -0,0 +1,75 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp
new file mode 100644
index 0000000..73cbd07
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/metafunctions.cpp
@@ -0,0 +1,274 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
new file mode 100644
index 0000000..21aa24f
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
@@ -0,0 +1,251 @@
+// RUN: %clang_cc1 -std=c++11 -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'}}
+}
+
+namespace ExpandingFunctionParameters {
+ template<typename ...T>
+ struct X0 {
+ typedef int type;
+ };
+
+ template<typename ...T>
+ struct X1 {
+ template<typename ... U>
+ typename X0<T(T, U...)...>::type f(U...);
+ };
+
+ void test() {
+ X1<float> x1;
+ x1.f(17, 3.14159);
+ }
+}
+
+namespace PR10230 {
+ template<typename>
+ struct s
+ {
+ template<typename... Args>
+ auto f() -> int(&)[sizeof...(Args)];
+ };
+
+ void main()
+ {
+ int (&ir1)[1] = s<int>().f<int>();
+ int (&ir3)[3] = s<int>().f<int, float, double>();
+ }
+}
diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/p1.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/p1.cpp
new file mode 100644
index 0000000..daff9d1
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/p1.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.decls/temp.variadic/p2.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/p2.cpp
new file mode 100644
index 0000000..ce19582
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/p2.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
new file mode 100644
index 0000000..d8294a1
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/p4.cpp
@@ -0,0 +1,193 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fexceptions -fcxx-exceptions -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 a function parameter pack, the pattern is the parameter-declaration
+// without the ellipsis.
+namespace PR11850 {
+ template<typename ...T> struct S {
+ int f(T...a, int b) { return b; }
+ };
+ S<> s;
+ S<int*, char, const double&> t;
+ int k = s.f(0);
+ int l = t.f(&k, 'x', 5.9, 4);
+
+ template<typename ...As> struct A {
+ template<typename ...Bs> struct B {
+ template<typename ...Cs> struct C {
+ C(As..., Bs..., int &k, Cs...);
+ };
+ };
+ };
+ A<>::B<>::C<> c000(k);
+ A<int>::B<>::C<int> c101(1, k, 3);
+ A<>::B<int>::C<int> c011(1, k, 3);
+ A<int>::B<int>::C<> c110(1, 2, k);
+ A<int, int>::B<int, int>::C<int, int> c222(1, 2, 3, 4, k, 5, 6);
+ A<int, int, int>::B<>::C<> c300(1, 2, 3, k);
+
+ int &f();
+ char &f(void*);
+ template<typename ...A> struct U {
+ template<typename ...B> struct V {
+ auto g(A...a, B...b) -> decltype(f(a...));
+ };
+ };
+ U<>::V<int*> v0;
+ U<int*>::V<> v1;
+ int &v0f = v0.g(0);
+ char &v1f = v1.g(0);
+}
+namespace PR12096 {
+ void Foo(int) {}
+ void Foo(int, int) = delete;
+ template<typename ...Args> struct Var {
+ Var(const Args &...args, int *) { Foo(args...); }
+ };
+ Var<int> var(1, 0);
+}
+
+// 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) {
+ // An empty expression-list performs value initialization.
+ constexpr 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 move constructor) not viable: no known conversion from 'int' to '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'}}
+};
+
+// There was a bug in the delayed parsing code for the
+// following case.
+template<typename ...T>
+struct DelayedParseTest : T...
+{
+ int a;
+ DelayedParseTest(T... i) : T{i}..., a{10} {}
+};
+
+
+// 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/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
new file mode 100644
index 0000000..726e222
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/p5.cpp
@@ -0,0 +1,403 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -std=c++11 -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.
+template<typename T, typename... Types>
+// FIXME: this should test that the diagnostic reads "type contains..."
+struct alignas(Types) TestUnexpandedDecls : T{ // expected-error{{expression contains unexpanded parameter pack 'Types'}}
+ void member_function(Types); // expected-error{{declaration type contains unexpanded parameter pack 'Types'}}
+ void member_function () throw(Types); // expected-error{{exception 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{{initializer contains unexpanded parameter pack 'Types'}}
+ T list_init = { static_cast<Types>(0) }; // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
+ }
+
+ T in_class_member_init = static_cast<Types>(0); // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
+ TestUnexpandedDecls() :
+ Types(static_cast<Types>(0)), // expected-error{{initializer contains unexpanded parameter pack 'Types'}}
+ Types(static_cast<Types>(0))...,
+ in_class_member_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'}}
+ T a[] = { T(), T(), T() };
+ for (Types t : a) { } // 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
+
+ for (auto t : values) { } // expected-error{{expression contains unexpanded parameter pack 'values'}}
+}
+
+// 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/clang/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp
new file mode 100644
index 0000000..79340c3
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/parameter-matching.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+// Check for template type parameter pack (mis-)matches with template
+// type parameters.
+template<typename ...T> struct X0t;
+template<typename ...T> struct X0t;
+
+template<typename ...T> struct X1t; // expected-note{{previous template type parameter pack declared here}}
+template<typename T> struct X1t; // expected-error{{template type parameter conflicts with previous template type parameter pack}}
+
+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 X0t_intt;
+template<template<typename ...T> class> struct X0t_intt;
+
+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 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/clang/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp
new file mode 100644
index 0000000..71bd6aa
--- /dev/null
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/partial-ordering.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp
new file mode 100644
index 0000000..0aef6ad
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p1.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<typename T> struct A { };
+
+template<typename T> T make();
+template<typename T> T make2(const T&);
+
+void test_make() {
+ int& ir0 = make<int&>();
+ A<int> a0 = make< A<int> >();
+ A<int> a1 = make2< A<int> >(A<int>());
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp
new file mode 100644
index 0000000..4d29b74
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-0x.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
new file mode 100644
index 0000000..de3b44f
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3-nodeduct.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5811
+template <class F> void Call(F f) { f(1); }
+template <typename T> void f(T);
+void a() { Call(f<int>); }
+
+// Check the conversion of a template-id to a pointer
+template<typename T, T* Address> struct Constant { };
+Constant<void(int), &f<int> > constant0;
+
+template<typename T, T* Address> void constant_func();
+void test_constant_func() {
+ constant_func<void(int), &f<int> >();
+}
+
+
+// Check typeof() on a template-id referring to a single function
+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;
+};
+
+int typeof0[is_same<__typeof__(f<int>), void (int)>::value? 1 : -1];
+int typeof1[is_same<__typeof__(&f<int>), void (*)(int)>::value? 1 : -1];
+
+template <typename T> void g(T); // expected-note{{possible target for call}}
+template <typename T> void g(T, T); // expected-note{{possible target for call}}
+
+int typeof2[is_same<__typeof__(g<float>), void (int)>::value? 1 : -1]; // \
+ // expected-error{{reference to overloaded function could not be resolved; did you mean to call it?}}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp
new file mode 100644
index 0000000..5556f35
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p3.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class X, class Y, class Z> X f(Y,Z); // expected-note {{candidate template ignored: couldn't infer template argument 'X'}}
+
+void g() {
+ f<int,char*,double>("aa",3.0); // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+ f<int,char*>("aa",3.0); // Z is deduced to be double \
+ // expected-warning{{conversion from string literal to 'char *' is deprecated}}
+ f<int>("aa",3.0); // Y is deduced to be char*, and
+ // Z is deduced to be double
+ f("aa",3.0); // expected-error{{no matching}}
+}
+
+// PR5910
+namespace PR5910 {
+ template <typename T>
+ void Func() {}
+
+ template <typename R>
+ void Foo(R (*fp)());
+
+ void Test() {
+ Foo(Func<int>);
+ }
+}
+
+// PR5949
+namespace PR5949 {
+ struct Bar;
+
+ template <class Container>
+ void quuz(const Container &cont) {
+ }
+
+ template<typename T>
+ int Foo(Bar *b, void (*Baz)(const T &t), T * = 0) {
+ return 0;
+ }
+
+ template<typename T>
+ int Quux(Bar *b, T * = 0)
+ {
+ return Foo<T>(b, quuz);
+ }
+}
+
+// PR7641
+namespace PR7641 {
+ namespace N2
+ {
+ template<class>
+ int f0(int);
+ }
+ namespace N
+ {
+ using N2::f0;
+ }
+
+ template<class R,class B1>
+ int
+ f1(R(a)(B1));
+
+ void f2()
+ { f1(N::f0<int>); }
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp
new file mode 100644
index 0000000..81addfe
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.arg.explicit/p9-0x.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp
new file mode 100644
index 0000000..c14b063
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/cwg1170.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+#if !__has_feature(cxx_access_control_sfinae)
+# error No support for access control as part of SFINAE?
+#endif
+
+typedef char yes_type;
+typedef char (&no_type)[2];
+
+template<unsigned N> struct unsigned_c { };
+
+template<typename T>
+class has_copy_constructor {
+ static T t;
+
+ template<typename U> static yes_type check(unsigned_c<sizeof(U(t))> * = 0);
+ template<typename U> static no_type check(...);
+
+public:
+ static const bool value = (sizeof(check<T>(0)) == sizeof(yes_type));
+};
+
+struct HasCopy { };
+
+struct HasNonConstCopy {
+ HasNonConstCopy(HasNonConstCopy&);
+};
+
+struct HasDeletedCopy {
+ HasDeletedCopy(const HasDeletedCopy&) = delete;
+};
+
+struct HasPrivateCopy {
+private:
+ HasPrivateCopy(const HasPrivateCopy&);
+};
+
+int check0[has_copy_constructor<HasCopy>::value? 1 : -1];
+int check1[has_copy_constructor<HasNonConstCopy>::value? 1 : -1];
+int check2[has_copy_constructor<HasDeletedCopy>::value? -1 : 1];
+int check3[has_copy_constructor<HasPrivateCopy>::value? -1 : 1];
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp
new file mode 100644
index 0000000..c27261c
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/p9.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <int> int f(int); // expected-note 2{{candidate}}
+template <signed char> int f(int); // expected-note 2{{candidate}}
+int i1 = f<1>(0); // expected-error{{ambiguous}}
+int i2 = f<1000>(0); // expected-error{{ambiguous}}
+
+namespace PR6707 {
+ template<typename T, T Value>
+ struct X { };
+
+ template<typename T, T Value>
+ void f(X<T, Value>);
+
+ void g(X<int, 10> x) {
+ f(x);
+ }
+
+ static const unsigned char ten = 10;
+ template<typename T, T Value, typename U>
+ void f2(X<T, Value>, X<U, Value>);
+
+ void g2() {
+ f2(X<int, 10>(), X<char, ten>());
+ }
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp
new file mode 100644
index 0000000..6481485
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/sfinae-1.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -verify %s
+
+typedef char one_byte;
+struct two_bytes { char data[2]; };
+
+template<typename T> one_byte __is_class_check(int T::*);
+template<typename T> two_bytes __is_class_check(...);
+
+template<typename T> struct is_class {
+ static const bool value = sizeof(__is_class_check<T>(0)) == 1;
+};
+
+struct X { };
+
+int array0[is_class<X>::value? 1 : -1];
+int array1[is_class<int>::value? -1 : 1];
+int array2[is_class<char[3]>::value? -1 : 1];
+
+namespace instantiation_order1 {
+ template<typename T>
+ struct it_is_a_trap {
+ typedef typename T::trap type;
+ };
+
+ template<bool, typename T = void>
+ struct enable_if {
+ typedef T type;
+ };
+
+ template<typename T>
+ struct enable_if<false, T> { };
+
+ template<typename T>
+ typename enable_if<sizeof(T) == 17>::type
+ f(const T&, typename it_is_a_trap<T>::type* = 0);
+
+ void f(...);
+
+ void test_f() {
+ f('a');
+ }
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
new file mode 100644
index 0000000..90d2949
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/basic.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> struct A { };
+
+template<typename T> A<T> f0(T*);
+
+void test_f0(int *ip, float const *cfp) {
+ A<int> a0 = f0(ip);
+ A<const float> a1 = f0(cfp);
+}
+
+template<typename T> void f1(T*, int);
+
+void test_f1(int *ip, float fv) {
+ f1(ip, fv);
+}
+
+// TODO: this diagnostic can and should improve
+template<typename T> void f2(T*, T*); // expected-note {{candidate template ignored: failed template argument deduction}} \
+// expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'float')}}
+
+struct ConvToIntPtr {
+ operator int*() const;
+};
+
+void test_f2(int *ip, float *fp) {
+ f2(ip, ConvToIntPtr()); // expected-error{{no matching function}}
+ f2(ip, ip); // okay
+ f2(ip, fp); // expected-error{{no matching function}}
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp
new file mode 100644
index 0000000..8b192fa
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p1-0x.cpp
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p2.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p2.cpp
new file mode 100644
index 0000000..c165c45
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p2.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T> struct A { };
+
+// bullet 1
+template<typename T> A<T> f0(T* ptr);
+
+void test_f0_bullet1() {
+ int arr0[6];
+ A<int> a0 = f0(arr0);
+ const int arr1[] = { 1, 2, 3, 4, 5 };
+ A<const int> a1 = f0(arr1);
+}
+
+// bullet 2
+int g0(int, int);
+float g1(float);
+
+void test_f0_bullet2() {
+ A<int(int, int)> a0 = f0(g0);
+ A<float(float)> a1 = f0(g1);
+}
+
+// bullet 3
+struct X { };
+const X get_X();
+
+template<typename T> A<T> f1(T);
+
+void test_f1_bullet3() {
+ A<X> a0 = f1(get_X());
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
new file mode 100644
index 0000000..e470dd0
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp
new file mode 100644
index 0000000..295f080
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3.cpp
@@ -0,0 +1,148 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> struct A { };
+
+// Top-level cv-qualifiers of P's type are ignored for type deduction.
+template<typename T> A<T> f0(const T);
+
+void test_f0(int i, const int ci) {
+ A<int> a0 = f0(i);
+ A<int> a1 = f0(ci);
+}
+
+// If P is a reference type, the type referred to by P is used for type
+// deduction.
+template<typename T> A<T> f1(T&);
+
+void test_f1(int i, const int ci, volatile int vi) {
+ A<int> a0 = f1(i);
+ A<const int> a1 = f1(ci);
+ A<volatile int> a2 = f1(vi);
+}
+
+template<typename T, unsigned N> struct B { };
+template<typename T, unsigned N> B<T, N> g0(T (&array)[N]);
+template<typename T, unsigned N> B<T, N> g0b(const T (&array)[N]);
+
+void test_g0() {
+ int array0[5];
+ B<int, 5> b0 = g0(array0);
+ const int array1[] = { 1, 2, 3};
+ B<const int, 3> b1 = g0(array1);
+ B<int, 3> b2 = g0b(array1);
+}
+
+template<typename T> B<T, 0> g1(const A<T>&);
+
+void test_g1(A<float> af) {
+ B<float, 0> b0 = g1(af);
+ B<int, 0> b1 = g1(A<int>());
+}
+
+// - If the original P is a reference type, the deduced A (i.e., the type
+// referred to by the reference) can be more cv-qualified than the
+// transformed A.
+template<typename T> A<T> f2(const T&);
+
+void test_f2(int i, const int ci, volatile int vi) {
+ A<int> a0 = f2(i);
+ A<int> a1 = f2(ci);
+ A<volatile int> a2 = f2(vi);
+}
+
+// PR5913
+template <typename T, int N>
+void Foo(const T (&a)[N]) {
+ T x;
+ x = 0;
+}
+
+const int a[1] = { 0 };
+
+void Test() {
+ Foo(a);
+}
+
+// - The transformed A can be another pointer or pointer to member type that
+// can be converted to the deduced A via a qualification conversion (4.4).
+template<typename T> A<T> f3(T * * const * const);
+
+void test_f3(int ***ip, volatile int ***vip) {
+ A<int> a0 = f3(ip);
+ A<volatile int> a1 = f3(vip);
+}
+
+// Also accept conversions for pointer types which require removing
+// [[noreturn]].
+namespace noreturn_stripping {
+ template <class R>
+ void f(R (*function)());
+
+ void g() __attribute__ ((__noreturn__));
+ void h();
+ void test() {
+ f(g);
+ f(h);
+ }
+}
+
+// - If P is a class, and P has the form template-id, then A can be a
+// derived class of the deduced A. Likewise, if P is a pointer to a class
+// of the form template-id, A can be a pointer to a derived class pointed
+// to by the deduced A.
+template<typename T, int I> struct C { };
+
+struct D : public C<int, 1> { };
+struct E : public D { };
+struct F : A<float> { };
+struct G : A<float>, C<int, 1> { };
+
+template<typename T, int I>
+ C<T, I> *f4a(const C<T, I>&);
+template<typename T, int I>
+ C<T, I> *f4b(C<T, I>);
+template<typename T, int I>
+ C<T, I> *f4c(C<T, I>*);
+int *f4c(...);
+
+void test_f4(D d, E e, F f, G g) {
+ C<int, 1> *ci1a = f4a(d);
+ C<int, 1> *ci2a = f4a(e);
+ C<int, 1> *ci1b = f4b(d);
+ C<int, 1> *ci2b = f4b(e);
+ C<int, 1> *ci1c = f4c(&d);
+ C<int, 1> *ci2c = f4c(&e);
+ 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
+ }
+}
+
+namespace PR9233 {
+ template<typename T> void f(const T **q); // expected-note{{candidate template ignored: substitution failure [with T = int]}}
+
+ void g(int **p) {
+ f(p); // expected-error{{no matching function for call to 'f'}}
+ }
+
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp
new file mode 100644
index 0000000..83b5f23
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p4.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR8598 {
+ template<class T> struct identity { typedef T type; };
+
+ template<class T, class C>
+ void f(T C::*, typename identity<T>::type*){}
+
+ struct X { void f() {}; };
+
+ void g() { (f)(&X::f, 0); }
+}
+
+namespace PR12132 {
+ template<typename S> void fun(const int* const S::* member) {}
+ struct A { int* x; };
+ void foo() {
+ fun(&A::x);
+ }
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp
new file mode 100644
index 0000000..8b18189
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p6.cpp
@@ -0,0 +1,128 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace test0 {
+ template<class T> void apply(T x, void (*f)(T)) { f(x); } // expected-note 2 {{candidate template ignored: deduced conflicting types for parameter 'T'}}\
+ // expected-note {{no overload of 'temp2' matching 'void (*)(int)'}}
+
+ template<class A> void temp(A);
+ void test0() {
+ // okay: deduce T=int from first argument, A=int during overload
+ apply(0, &temp);
+ apply(0, &temp<>);
+
+ // okay: deduce T=int from first and second arguments
+ apply(0, &temp<int>);
+
+ // deduction failure: T=int from first, T=long from second
+ apply(0, &temp<long>); // expected-error {{no matching function for call to 'apply'}}
+ }
+
+ void over(int);
+ int over(long);
+
+ void test1() {
+ // okay: deductions match
+ apply(0, &over);
+
+ // deduction failure: deduced T=long from first argument, T=int from second
+ apply(0L, &over); // expected-error {{no matching function for call to 'apply'}}
+ }
+
+ void over(short);
+
+ void test2() {
+ // deduce T=int from first arg, second arg is undeduced context,
+ // pick correct overload of 'over' during overload resolution for 'apply'
+ apply(0, &over);
+ }
+
+ template<class A, class B> B temp2(A);
+ void test3() {
+ // deduce T=int from first arg, A=int B=void during overload resolution
+ apply(0, &temp2);
+ apply(0, &temp2<>);
+ apply(0, &temp2<int>);
+
+ // overload failure
+ apply(0, &temp2<long>); // expected-error {{no matching function for call to 'apply'}}
+ }
+}
+
+namespace test1 {
+ template<class T> void invoke(void (*f)(T)) { f(T()); } // expected-note 6 {{couldn't infer template argument}} \
+ // expected-note {{candidate template ignored: couldn't infer template argument 'T'}}
+
+ template<class T> void temp(T);
+ void test0() {
+ // deduction failure: overload has template => undeduced context
+ invoke(&temp); // expected-error {{no matching function for call to 'invoke'}}
+ invoke(&temp<>); // expected-error {{no matching function for call to 'invoke'}}
+
+ // okay: full template-id
+ invoke(&temp<int>);
+ }
+
+ void over(int);
+ int over(long);
+
+ void test1() {
+ // okay: only one overload matches
+ invoke(&over);
+ }
+
+ void over(short);
+
+ void test2() {
+ // deduction failure: overload has multiple matches => undeduced context
+ invoke(&over); // expected-error {{no matching function for call to 'invoke'}}
+ }
+
+ template<class A, class B> B temp2(A);
+ void test3() {
+ // deduction failure: overload has template => undeduced context
+ // (even though partial application temp2<int> could in theory
+ // let us infer T=int)
+ invoke(&temp2); // expected-error {{no matching function for call to 'invoke'}}
+ invoke(&temp2<>); // expected-error {{no matching function for call to 'invoke'}}
+ invoke(&temp2<int>); // expected-error {{no matching function for call to 'invoke'}}
+
+ // okay: full template-id
+ invoke(&temp2<int, void>);
+
+ // overload failure
+ invoke(&temp2<int, int>); // expected-error {{no matching function for call to 'invoke'}}
+ }
+}
+
+namespace rdar8360106 {
+ template<typename R, typename T> void f0(R (*)(T), T);
+ template<typename R, typename T> void f1(R (&)(T) , T); // expected-note{{candidate template ignored: couldn't infer template argument 'R'}}
+ template<typename R, typename T> void f2(R (* const&)(T), T); // expected-note{{candidate template ignored: couldn't infer template argument 'R'}}
+
+ int g(int);
+ int g(int, int);
+
+ void h() {
+ f0(g, 1);
+ f0(&g, 1);
+ f1(g, 1);
+ f1(&g, 1); // expected-error{{no matching function for call to 'f1'}}
+ f2(g, 1); // expected-error{{no matching function for call to 'f2'}}
+ f2(&g, 1);
+ }
+}
+
+namespace PR11713 {
+ template<typename T>
+ int f(int, int, int);
+
+ template<typename T>
+ float f(float, float);
+
+ template<typename R, typename B1, typename B2, typename A1, typename A2>
+ R& g(R (*)(B1, B2), A1, A2);
+
+ void h() {
+ float &fr = g(f<int>, 1, 2);
+ }
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp
new file mode 100644
index 0000000..5a9ea08
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p2.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: [temp.deduct.conv]p2 bullets 1 and 2 can't actually happen without
+// references?
+// struct ConvertibleToArray {
+// // template<typename T, unsigned N>
+// // operator T(()[]) const;
+
+// private:
+// typedef int array[17];
+
+// operator array() const;
+// };
+
+// void test_array(ConvertibleToArray cta) {
+// int *ip = cta;
+// ip = cta;
+// const float *cfp = cta;
+// }
+
+// bullet 2
+// struct ConvertibleToFunction {
+// template<typename T, typename A1, typename A2>
+// operator T(A1, A2) const () { };
+// };
+
+// bullet 3
+struct ConvertibleToCVQuals {
+ template<typename T>
+ operator T* const() const;
+};
+
+void test_cvqual_conv(ConvertibleToCVQuals ctcv) {
+ int *ip = ctcv;
+ const int *icp = ctcv;
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp
new file mode 100644
index 0000000..e23e98a
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p3.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct AnyPtr {
+ template<typename T>
+ operator T*() const;
+};
+
+// If A is a cv-qualified type, the top level cv-qualifiers of A's type
+// are ignored for type deduction.
+void test_cvquals(AnyPtr ap) {
+ int* const ip = ap;
+ const float * const volatile fp = ap;
+}
+
+// If A is a reference type, the type referred to by A is used for
+// type deduction.
+void test_ref_arg(AnyPtr ap) {
+ const int* const &ip = ap;
+ double * const &dp = ap;
+}
+
+struct AnyRef {
+ template<typename T>
+ operator T&() const;
+};
+
+void test_ref_param(AnyRef ar) {
+ int &ir = ar;
+ const float &fr = ar;
+ int i = ar;
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp
new file mode 100644
index 0000000..4dca820
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.conv/p4.cpp
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+struct AnyT {
+ template<typename T>
+ operator T();
+};
+
+void test_cvqual_ref(AnyT any) {
+ const int &cir = any;
+}
+
+struct AnyThreeLevelPtr {
+ template<typename T>
+ operator T***() const
+ {
+ T x = 0;
+ // FIXME: looks like we get this wrong, too!
+ // x = 0; // will fail if T is deduced to a const type
+ // (EDG and GCC get this wrong)
+ return 0;
+ }
+};
+
+struct X { };
+
+void test_deduce_with_qual(AnyThreeLevelPtr a3) {
+ int * const * const * const ip = a3;
+}
+
+struct AnyPtrMem {
+ template<typename Class, typename T>
+ operator T Class::*() const
+ {
+ T x = 0;
+ // FIXME: looks like we get this wrong, too!
+ // x = 0; // will fail if T is deduced to a const type.
+ // (EDG and GCC get this wrong)
+ return 0;
+ }
+};
+
+void test_deduce_ptrmem_with_qual(AnyPtrMem apm) {
+ const float X::* pm = apm;
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp
new file mode 100644
index 0000000..99a265a
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.funcaddr/p1.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<typename T>
+ T f0(T, int);
+
+void test_f0() {
+ int (*f0a)(int, int) = f0;
+ int (*f0b)(int, int) = &f0;
+ float (*f0c)(float, int) = &f0;
+}
+
+template<typename T> T f1(T, int);
+template<typename T> T f1(T);
+
+void test_f1() {
+ float (*f1a)(float, int) = f1;
+ float (*f1b)(float, int) = &f1;
+ float (*f1c)(float) = f1;
+ float (*f1d)(float) = (f1);
+ float (*f1e)(float) = &f1;
+ float (*f1f)(float) = (&f1);
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp
new file mode 100644
index 0000000..01155e1
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p11.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+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<typename T>
+struct identity {
+ typedef T type;
+};
+
+template <class T>
+ T* f2(int, typename identity<T>::type = 0);
+template <class T, class U>
+ T& f2(U, typename identity<T>::type = 0);
+
+void g2() {
+ 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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp
new file mode 100644
index 0000000..b965300
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p12.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp
new file mode 100644
index 0000000..f204caf
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.partial/p9-0x.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp
new file mode 100644
index 0000000..8183061
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p10-0x.cpp
@@ -0,0 +1,4 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+template<typename T> void f(T&&);
+template<> void f(int&) { }
+void (*fp)(int&) = &f;
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp
new file mode 100644
index 0000000..bf5f962
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p17.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<int i> class A { };
+template<short s> void f(A<s>); // expected-note{{candidate template ignored: substitution failure}}
+
+void k1() {
+ A<1> a;
+ f(a); // expected-error{{no matching function for call}}
+ f<1>(a);
+}
+template<const short cs> class B { };
+template<short s> void g(B<s>);
+void k2() {
+ B<1> b;
+ g(b); // OK: cv-qualifiers are ignored on template parameter types
+}
+
+template<short s> void h(int (&)[s]); // expected-note{{candidate function template not viable: requires 1 argument, but 2 were provided}}
+void k3() {
+ int array[5];
+ h(array);
+ h<5>(array);
+}
+
+template<short s> void h(int (&)[s], A<s>); // expected-note{{candidate template ignored: substitution failure}}
+void k4() {
+ A<5> a;
+ int array[5];
+ h(array, a); // expected-error{{no matching function for call}}
+ h<5>(array, a);
+}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp
new file mode 100644
index 0000000..5b031c2
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p2-0x.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp
new file mode 100644
index 0000000..4e98a6d
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p21.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp
new file mode 100644
index 0000000..fcc6cf7
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p22.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp
new file mode 100644
index 0000000..c819d97
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p5-0x.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp
new file mode 100644
index 0000000..a6b1172
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p8-0x.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
new file mode 100644
index 0000000..7774b5c
--- /dev/null
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -std=c++11 -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/clang/test/CXX/temp/temp.names/p2.cpp b/clang/test/CXX/temp/temp.names/p2.cpp
new file mode 100644
index 0000000..93e45dd
--- /dev/null
+++ b/clang/test/CXX/temp/temp.names/p2.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Ensure that when enforcing access control an unqualified template name with
+// explicit template arguments, we don't lose the context of the name lookup
+// because of the required early lookup to determine if it names a template.
+namespace PR7163 {
+ template <typename R, typename P> void h(R (*func)(P)) {}
+ class C {
+ template <typename T> static void g(T*) {};
+ public:
+ void f() { h(g<int>); }
+ };
+}
diff --git a/clang/test/CXX/temp/temp.names/p4.cpp b/clang/test/CXX/temp/temp.names/p4.cpp
new file mode 100644
index 0000000..103a1bd
--- /dev/null
+++ b/clang/test/CXX/temp/temp.names/p4.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct meta {
+ template<typename U>
+ struct apply {
+ typedef U* type;
+ };
+};
+
+template<typename T, typename U>
+void f(typename T::template apply<U>::type);
+
+void test_f(int *ip) {
+ f<meta, int>(ip);
+}
diff --git a/clang/test/CXX/temp/temp.param/p1.cpp b/clang/test/CXX/temp/temp.param/p1.cpp
new file mode 100644
index 0000000..e9a9789
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p1.cpp
@@ -0,0 +1,12 @@
+// Suppress 'no run line' failure.
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+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/clang/test/CXX/temp/temp.param/p10-0x.cpp b/clang/test/CXX/temp/temp.param/p10-0x.cpp
new file mode 100644
index 0000000..37bb284
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p10-0x.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+template<typename> struct Y1;
+template<typename, int> struct Y2;
+
+template<class T1, class T2 = int> using B2 = T1;
+template<class T1 = int, class T2> using B2 = T1;
+
+template<template<class> class F, template<class> class G = Y1> using B2t = F<G<int>>;
+template<template<class> class F = Y2, template<class> class G> using B2t = F<G<int>>;
+
+template<int N, int M = 5> using B2n = Y2<int, N + M>;
+template<int N = 5, int M> using B2n = Y2<int, N + M>;
diff --git a/clang/test/CXX/temp/temp.param/p10.cpp b/clang/test/CXX/temp/temp.param/p10.cpp
new file mode 100644
index 0000000..b9dac75
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p10.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename> struct Y1;
+template<typename, int> struct Y2;
+
+template<class T1, class T2 = int> class B2;
+template<class T1 = int, class T2> class B2;
+
+template<template<class, int> class, template<class> class = Y1> class B2t;
+template<template<class, int> class = Y2, template<class> class> class B2t;
+
+template<int N, int M = 5> class B2n;
+template<int N = 5, int M> class B2n;
diff --git a/clang/test/CXX/temp/temp.param/p11-0x.cpp b/clang/test/CXX/temp/temp.param/p11-0x.cpp
new file mode 100644
index 0000000..d2276a3
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p11-0x.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+// If a template-parameter of a class template or alias 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> struct X3t; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
+template<typename T = int, typename> using A3t = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
+template<int V = 0, int> struct X3nt; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
+template<int V = 0, int> using A3nt = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
+template<template<class> class M = vector, template<class> class> struct X3tt; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
+template<template<class> class M = vector, template<class> class> using A3tt = int; // expected-error{{template parameter missing a default argument}} expected-note{{previous default template argument defined here}}
+
+template<typename T = int, typename ...Types> struct X2t;
+template<typename T = int, typename ...Types> using A2t = X2t<T, Types...>;
+template<int V = 0, int ...Values> struct X2nt;
+template<int V = 0, int ...Values> using A2nt = X2nt<V, Values...>;
+template<template<class> class M = vector, template<class> class... Metas>
+ struct X2tt;
+template<template<class> class M = vector, template<class> class... Metas>
+ using A2tt = X2tt<M, Metas...>;
+
+// If a template-parameter of a primary class template or alias 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, int After2>
+struct X0t;
+X0t<int> pr9789();
+template<typename ...Types, // expected-error{{template parameter pack must be the last template parameter}}
+ int After>
+using A0t = int;
+
+template<int ...Values, // expected-error{{template parameter pack must be the last template parameter}}
+ int After>
+struct X0nt;
+template<int ...Values, // expected-error{{template parameter pack must be the last template parameter}}
+ int After>
+using A0nt = int;
+
+template<template<typename> class ...Templates, // expected-error{{template parameter pack must be the last template parameter}}
+ int After>
+struct X0tt;
+template<template<typename> class ...Templates, // expected-error{{template parameter pack must be the last template parameter}}
+ int After>
+using A0tt = int;
+
+// [ 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/clang/test/CXX/temp/temp.param/p11.cpp b/clang/test/CXX/temp/temp.param/p11.cpp
new file mode 100644
index 0000000..5af0c4e
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p11.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename> struct Y1;
+template<typename, int> struct Y2;
+
+template<class T1 = int, // expected-note{{previous default template argument defined here}}
+ class T2> // expected-error{{template parameter missing a default argument}}
+ class B1;
+
+template<template<class> class = Y1, // expected-note{{previous default template argument defined here}}
+ template<class> class> // expected-error{{template parameter missing a default argument}}
+ class B1t;
+
+template<int N = 5, // expected-note{{previous default template argument defined here}}
+ int M> // expected-error{{template parameter missing a default argument}}
+ class B1n;
diff --git a/clang/test/CXX/temp/temp.param/p12.cpp b/clang/test/CXX/temp/temp.param/p12.cpp
new file mode 100644
index 0000000..7be3879
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p12.cpp
@@ -0,0 +1,39 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename> struct Y1; // expected-note{{too few template parameters in template template argument}}
+template<typename, int> struct Y2;
+
+// C++ [temp.param]p12:
+template<class T1,
+ class T2 = int> // expected-note{{previous default template argument defined here}}
+ class B3;
+template<class T1, typename T2> class B3;
+template<class T1,
+ typename T2 = float> // expected-error{{template parameter redefines default argument}}
+ class B3;
+
+template<template<class, int> class,
+ template<class> class = Y1> // expected-note{{previous default template argument defined here}}
+ class B3t;
+
+template<template<class, int> class, template<class> class> class B3t;
+
+template<template<class, int> class,
+ template<class> class = Y1> // expected-error{{template parameter redefines default argument}}
+ class B3t;
+
+template<int N,
+ int M = 5> // expected-note{{previous default template argument defined here}}
+ class B3n;
+
+template<int N, int M> class B3n;
+
+template<int N,
+ int M = 7> // expected-error{{template parameter redefines default argument}}
+ class B3n;
+
+// Check validity of default arguments
+template<template<class, int> class // expected-note{{previous template template parameter is here}}
+ = Y1> // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+ class C1 {};
+
+C1<> c1; // expected-note{{while checking a default template argument}}
diff --git a/clang/test/CXX/temp/temp.param/p13.cpp b/clang/test/CXX/temp/temp.param/p13.cpp
new file mode 100644
index 0000000..7e7dbe5
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p13.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// The scope of atemplate-parameterextends from its point of
+// declaration until the end of its template. In particular, a
+// template-parameter can be used in the declaration of subsequent
+// template-parameters and their default arguments.
+
+template<class T, T* p, class U = T> class X { /* ... */ };
+// FIXME: template<class T> void f(T* p = new T);
+
+// Check for bogus template parameter shadow warning.
+template<template<class T> class,
+ template<class T> class>
+ class B1noshadow;
diff --git a/clang/test/CXX/temp/temp.param/p14.cpp b/clang/test/CXX/temp/temp.param/p14.cpp
new file mode 100644
index 0000000..a6c53c1
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p14.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// XFAIL: *
+
+// A template-parameter shall not be used in its own default argument.
+template<typename T = typename T::type> struct X; // expected-error{{default}}
diff --git a/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp b/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp
new file mode 100644
index 0000000..5fc57a4
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+template<typename T> struct X;
+template<int I> struct Y;
+
+X<X<int>> *x1;
+
+Y<(1 >> 2)> *y1;
+Y<1 >> 2> *y2; // FIXME: expected-error{{expected unqualified-id}}
+
+X<X<X<X<X<int>>>>> *x2;
+
+template<> struct X<int> { };
+typedef X<int> X_int;
+struct Z : X_int { };
+
+void f(const X<int> x) {
+ (void)reinterpret_cast<X<int>>(x); // expected-error{{reinterpret_cast from}}
+ (void)reinterpret_cast<X<X<X<int>>>>(x); // expected-error{{reinterpret_cast from}}
+
+ X<X<int>> *x1;
+}
+
+template<typename T = void> struct X1 { };
+X1<X1<>> x1a;
diff --git a/clang/test/CXX/temp/temp.param/p15.cpp b/clang/test/CXX/temp/temp.param/p15.cpp
new file mode 100644
index 0000000..ee572e9
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p15.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
+template<typename T> struct X;
+template<int I> struct Y;
+
+X<X<int> > *x1;
+X<X<int>> *x2; // expected-error{{a space is required between consecutive right angle brackets (use '> >')}}
+
+X<X<X<X<int>> // expected-error{{a space is required between consecutive right angle brackets (use '> >')}}
+ >> *x3; // expected-error{{a space is required between consecutive right angle brackets (use '> >')}}
+
+Y<(1 >> 2)> *y1;
+Y<1 >> 2> *y2; // expected-warning{{use of right-shift operator ('>>') in template argument will require parentheses in C++11}}
diff --git a/clang/test/CXX/temp/temp.param/p2.cpp b/clang/test/CXX/temp/temp.param/p2.cpp
new file mode 100644
index 0000000..fed6e9c
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p2.cpp
@@ -0,0 +1,22 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// There is no semantic difference between class and typename in a
+// template-parameter. typename followed by an unqualified-id names a
+// template type parameter.
+template<class T> struct X;
+template<typename T> struct X;
+
+// typename followed by aqualified-id denotes the type in a non-type
+// parameter-declaration.
+template<typename T, typename T::type Value> struct Y0;
+template<typename T, typename X<T>::type Value> struct Y1;
+
+// A storage class shall not be specified in a template-parameter declaration.
+template<static int Value> struct Z; // FIXME: expect an error
+
+// Make sure that we properly disambiguate non-type template parameters that
+// start with 'class'.
+class X1 { };
+template<class X1 *xptr> struct Y2 { };
+
+// FIXME: add the example from p2
diff --git a/clang/test/CXX/temp/temp.param/p3.cpp b/clang/test/CXX/temp/temp.param/p3.cpp
new file mode 100644
index 0000000..dc40c4b
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p3.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// A type-parameter defines its identifier to be a type-name (if
+// declared with class or typename) or template-name (if declared with
+// template) in the scope of the template declaration.
+template<typename T> struct X0 {
+ T* value;
+};
+
+template<template<class T> class Y> struct X1 {
+ Y<int> value;
+};
+
+// [Note: because of the name lookup rules, a template-parameter that
+// could be interpreted as either a non-type template-parameter or a
+// type-parameter (because its identifier is the name of an already
+// existing class) is taken as a type-parameter. For example,
+class T { /* ... */ }; // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
+int i;
+
+template<class T, T i> struct X2 {
+ void f(T t)
+ {
+ T t1 = i; //template-parameters T and i
+ ::T t2 = ::i; // global namespace members T and i \
+ // expected-error{{no viable conversion}}
+ }
+};
+
+namespace PR6831 {
+ namespace NA { struct S; }
+ namespace NB { struct S; }
+
+ using namespace NA;
+ using namespace NB;
+
+ template <typename S> void foo();
+ template <int S> void bar();
+ template <template<typename> class S> void baz();
+}
diff --git a/clang/test/CXX/temp/temp.param/p4.cpp b/clang/test/CXX/temp/temp.param/p4.cpp
new file mode 100644
index 0000000..809fb20
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p4.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class X;
+
+// C++ [temp.param]p4
+typedef int INT;
+enum E { enum1, enum2 };
+template<int N> struct A1;
+template<INT N, INT M> struct A2;
+template<enum E x, E y> struct A3;
+template<int &X> struct A4;
+template<int *Ptr> struct A5;
+template<int (&f)(int, int)> struct A6;
+template<int (*fp)(float, double)> struct A7;
+template<int X::*pm> struct A8;
+template<float (X::*pmf)(float, int)> struct A9;
+template<typename T, T x> struct A10;
+
+template<float f> struct A11; // expected-error{{a non-type template parameter cannot have type 'float'}}
+
+template<void *Ptr> struct A12;
+template<int (*IncompleteArrayPtr)[]> struct A13;
diff --git a/clang/test/CXX/temp/temp.param/p5.cpp b/clang/test/CXX/temp/temp.param/p5.cpp
new file mode 100644
index 0000000..3cbb3b7
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p5.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -verify %s -std=c++11
+
+template<const int I> struct S {
+ decltype(I) n;
+ int &&r = I;
+};
+S<5> s;
+
+template<typename T, T v> struct U {
+ decltype(v) n;
+ int &&r = v;
+};
+U<const int, 6> u;
diff --git a/clang/test/CXX/temp/temp.param/p7.cpp b/clang/test/CXX/temp/temp.param/p7.cpp
new file mode 100644
index 0000000..13f0367
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p7.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// A non-type template-parameter shall not be declared to have
+// floating point, class, or void type.
+struct A;
+
+template<double d> class X; // expected-error{{cannot have type}}
+template<double* pd> class Y; //OK
+template<double& rd> class Z; //OK
+
+template<A a> class X0; // expected-error{{cannot have type}}
+
+typedef void VOID;
+template<VOID a> class X01; // expected-error{{cannot have type}}
+
diff --git a/clang/test/CXX/temp/temp.param/p8.cpp b/clang/test/CXX/temp/temp.param/p8.cpp
new file mode 100644
index 0000000..fed048c
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p8.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<int X[10]> struct A;
+template<int *X> struct A;
+template<int f(float, double)> struct B;
+typedef float FLOAT;
+template<int (*f)(FLOAT, double)> struct B;
diff --git a/clang/test/CXX/temp/temp.param/p9-0x.cpp b/clang/test/CXX/temp/temp.param/p9-0x.cpp
new file mode 100644
index 0000000..29a7549
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p9-0x.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -std=c++11 -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() {}
+}
+
+namespace PR10069 {
+ template<typename T, T a, T b=0, T c=1>
+ T f(T x);
+
+ void g() {
+ f<unsigned int, 0>(0);
+ }
+}
diff --git a/clang/test/CXX/temp/temp.param/p9.cpp b/clang/test/CXX/temp/temp.param/p9.cpp
new file mode 100644
index 0000000..b2318c2
--- /dev/null
+++ b/clang/test/CXX/temp/temp.param/p9.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -verify %s
+
+// A default template-argument shall not be specified in a function
+// template declaration or a function template definition
+template<typename T = int> // expected-warning{{default template arguments for a function template are a C++11 extension}}
+ void foo0(T);
+template<typename T = int> // expected-warning{{default template arguments for a function template are a C++11 extension}}
+ void foo1(T) { }
+
+// [...] nor in the template-parameter-list of the definition of a
+// member of a class template.
+template<int N>
+struct X0 {
+ void f();
+};
+
+template<int N = 0> // expected-error{{cannot add a default template argument}}
+void X0<N>::f() { }
+
+class X1 {
+ template<template<int> class TT = X0> // expected-error{{not permitted on a friend template}}
+ friend void f2();
+};
diff --git a/clang/test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp b/clang/test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp
new file mode 100644
index 0000000..75580d2
--- /dev/null
+++ b/clang/test/CXX/temp/temp.res/temp.dep.res/temp.point/p1.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// XFAIL: *
+
+// Note: we fail this test because we perform template instantiation
+// at the end of the translation unit, so argument-dependent lookup
+// finds functions that occur after the point of instantiation. Note
+// that GCC fails this test; EDG passes the test in strict mode, but
+// not in relaxed mode.
+namespace N {
+ struct A { };
+ struct B : public A { };
+
+ int& f0(A&);
+}
+
+template<typename T, typename Result>
+struct X0 {
+ void test_f0(T t) {
+ Result r = f0(t);
+ };
+};
+
+void test_f0() {
+ X0<N::A, int&> xA;
+ xA.test_f0(N::A());
+ X0<N::B, int&> xB;
+ xB.test_f0(N::B());
+}
+
+namespace N {
+ char& f0(B&);
+}
diff --git a/clang/test/CXX/temp/temp.res/temp.dep/p3.cpp b/clang/test/CXX/temp/temp.res/temp.dep/p3.cpp
new file mode 100644
index 0000000..c41a4c6
--- /dev/null
+++ b/clang/test/CXX/temp/temp.res/temp.dep/p3.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A0 {
+ struct K { };
+};
+
+template <typename T> struct B0: A0 {
+ static void f() {
+ K k;
+ }
+};
+
+namespace E1 {
+ typedef double A;
+
+ template<class T> class B {
+ typedef int A;
+ };
+
+ template<class T>
+ struct X : B<T> {
+ A* blarg(double *dp) {
+ return dp;
+ }
+ };
+}
+
+namespace E2 {
+ struct A {
+ struct B;
+ int *a;
+ int Y;
+ };
+
+ int a;
+ template<class T> struct Y : T {
+ struct B { /* ... */ };
+ B b;
+ void f(int i) { a = i; }
+ Y* p;
+ };
+
+ Y<A> ya;
+}
diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2-0x.cpp b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2-0x.cpp
new file mode 100644
index 0000000..0aba402
--- /dev/null
+++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2-0x.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+template<int n> struct S;
+
+template<int n> struct T {
+ T() {
+ // An identifier is value-dependent if it is:
+ // - a name declared with a dependent type
+ S<n> s;
+ S<s> check1; // ok, s is value-dependent
+ // - the name of a non-type template parameter
+ typename S<n>::T check2; // ok, n is value-dependent
+ // - a constant with literal type and is initialized with an expression
+ // that is value-dependent.
+ const int k = n;
+ typename S<k>::T check3a; // ok, u is value-dependent
+
+ constexpr const int *p = &k;
+ typename S<*p>::T check3b; // ok, p is value-dependent
+
+ // (missing from the standard)
+ // - a reference and is initialized with an expression that is
+ // value-dependent.
+ const int &i = k;
+ typename S<i>::T check4; // ok, i is value-dependent
+ }
+};
diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp
new file mode 100644
index 0000000..68a41c7
--- /dev/null
+++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++98 -verify %s
+
+template<int n> struct S;
+
+template<int n> struct T {
+ T() {
+ // An identifier is value-dependent if it is:
+ // - a name declared with a dependent type
+ S<n> s;
+ S<s> check1; // ok, s is value-dependent
+ // - the name of a non-type template parameter
+ typename S<n>::T check2; // ok, n is value-dependent
+ // - a constant with literal type and is initialized with an expression
+ // that is value-dependent.
+ const int k = n;
+ typename S<k>::T check3; // ok, u is value-dependent
+
+ const int &i = k;
+ typename S<i>::T check4; // expected-error {{not an integral constant expression}} expected-error {{qualified name}}
+ }
+};
diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
new file mode 100644
index 0000000..81b070f
--- /dev/null
+++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p1.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// Examples from CWG1056.
+namespace Example1 {
+ template<class T> struct A;
+ template<class T> using B = A<T>;
+
+ template<class T> struct A {
+ struct C {};
+ B<T>::C bc; // ok, B<T> is the current instantiation.
+ };
+
+ template<class T> struct A<A<T>> {
+ struct C {};
+ B<B<T>>::C bc; // ok, B<B<T>> is the current instantiation.
+ };
+
+ template<class T> struct A<A<A<T>>> {
+ struct C {};
+ B<B<T>>::C bc; // expected-error {{missing 'typename'}}
+ };
+}
+
+namespace Example2 {
+ template<class T> struct A {
+ void g();
+ };
+ template<class T> using B = A<T>;
+ template<class T> void B<T>::g() {} // ok.
+}
diff --git a/clang/test/CXX/temp/temp.res/temp.local/p1.cpp b/clang/test/CXX/temp/temp.res/temp.local/p1.cpp
new file mode 100644
index 0000000..1ad4464
--- /dev/null
+++ b/clang/test/CXX/temp/temp.res/temp.local/p1.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// C++0x [temp.local]p1:
+// Like normal (non-template) classes, class templates have an
+// injected-class-name (Clause 9). The injected-class-name can be used with
+// or without a template-argument-list. When it is used without
+// a template-argument-list, it is equivalent to the injected-class-name
+// followed by the template-parameters of the class template enclosed in <>.
+
+template <typename T> struct X0 {
+ X0();
+ ~X0();
+ X0 f(const X0&);
+};
+
+// Test non-type template parameters.
+template <int N1, const int& N2, const int* N3> struct X1 {
+ X1();
+ ~X1();
+ X1 f(const X1& x1a) { X1 x1b(x1a); return x1b; }
+};
+
+// When it is used with a template-argument-list, it refers to the specified
+// class template specialization, which could be the current specialization
+// or another specialization.
+// FIXME: Test this clause.
+
+int i = 42;
+void test() {
+ X0<int> x0; (void)x0;
+ X1<42, i, &i> x1; (void)x1;
+}
diff --git a/clang/test/CXX/temp/temp.res/temp.local/p3.cpp b/clang/test/CXX/temp/temp.res/temp.local/p3.cpp
new file mode 100644
index 0000000..54da885
--- /dev/null
+++ b/clang/test/CXX/temp/temp.res/temp.local/p3.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -verify %s
+
+template <class T> struct Base { // expected-note 4 {{member found by ambiguous name lookup}}
+ static void f();
+};
+
+struct X0 { };
+
+template <class T> struct Derived: Base<int>, Base<char> {
+ typename Derived::Base b; // expected-error{{member 'Base' found in multiple base classes of different types}}
+ typename Derived::Base<double> d; // OK
+
+ void g(X0 *t) {
+ t->Derived::Base<T>::f();
+ t->Base<T>::f();
+ t->Base::f(); // expected-error{{member 'Base' found in multiple base classes of different types}} \
+ // expected-error{{no member named 'f' in 'X0'}} \
+ // expected-error{{expected a class or namespace}}
+ }
+};
+
+namespace PR6717 {
+ template <typename T>
+ class WebVector {
+ } // expected-error {{expected ';' after class}}
+
+ WebVector(const WebVector<T>& other) { } // expected-error{{undeclared identifier 'T'}} \
+ expected-error{{requires a type specifier}}
+
+ template <typename C>
+ WebVector<T>& operator=(const C& other) { } // expected-error{{undeclared identifier 'T'}}
+}
diff --git a/clang/test/CXX/temp/temp.res/temp.local/p7.cpp b/clang/test/CXX/temp/temp.res/temp.local/p7.cpp
new file mode 100644
index 0000000..bd05e75
--- /dev/null
+++ b/clang/test/CXX/temp/temp.res/temp.local/p7.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T> struct A {
+ int B;
+ int f();
+};
+
+template<class B> int A<B>::f() {
+ return B;
+}
diff --git a/clang/test/CXX/temp/temp.res/temp.local/p8.cpp b/clang/test/CXX/temp/temp.res/temp.local/p8.cpp
new file mode 100644
index 0000000..5d9d509
--- /dev/null
+++ b/clang/test/CXX/temp/temp.res/temp.local/p8.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N {
+ enum { C };
+ template<class T> class B {
+ void f(T);
+ };
+}
+
+template<class C> void N::B<C>::f(C) {
+ C b;
+}
+
+namespace N {
+ enum { D };
+ namespace M {
+ enum { C , D };
+ template<typename C> class X {
+ template<typename U> void f(C, U);
+
+ template<typename D> void g(C, D) {
+ C c;
+ D d;
+ }
+ };
+
+ struct Y {
+ template<typename U> void f(U);
+ };
+ }
+
+ struct Y {
+ template<typename D> void f(D);
+ };
+}
+
+template<typename C>
+template<typename D>
+void N::M::X<C>::f(C, D) {
+ C c;
+ D d;
+}
+
+template<typename C>
+void N::M::Y::f(C) {
+ C c;
+}
+
+template<typename D>
+void N::Y::f(D) {
+ D d;
+}
+
diff --git a/clang/test/CXX/temp/temp.res/temp.local/p9.cpp b/clang/test/CXX/temp/temp.res/temp.local/p9.cpp
new file mode 100644
index 0000000..9ca8d88
--- /dev/null
+++ b/clang/test/CXX/temp/temp.res/temp.local/p9.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A {
+ struct B { void f(); };
+ int a;
+ int Y;
+};
+
+template<class B, class a> struct X : A {
+ B b; // A's B
+ a c; // expected-error{{unknown type name 'a'}}
+
+ void g() {
+ b.g(); // expected-error{{no member named 'g' in 'A::B'}}
+ }
+};
diff --git a/clang/test/CXX/temp/temp.spec/p5.cpp b/clang/test/CXX/temp/temp.spec/p5.cpp
new file mode 100644
index 0000000..0e69a26
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/p5.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> inline void f(T) { }
+template void f(int); // expected-note{{previous explicit instantiation}}
+template void f(int); // expected-error{{duplicate explicit instantiation}}
+
+template<typename T>
+struct X0 {
+ union Inner { };
+
+ void f(T) { }
+
+ static T value;
+};
+
+template<typename T>
+T X0<T>::value = 3.14; // expected-warning{{implicit conversion turns literal floating-point number into integer}}
+
+template struct X0<int>; // expected-note{{previous explicit instantiation}} \
+ expected-note{{requested here}}
+template struct X0<int>; // expected-error{{duplicate explicit instantiation}}
+
+template void X0<float>::f(float); // expected-note{{previous explicit instantiation}}
+template void X0<float>::f(float); // expected-error{{duplicate explicit instantiation}}
+
+template union X0<float>::Inner; // expected-note{{previous explicit instantiation}}
+template union X0<float>::Inner; // expected-error{{duplicate explicit instantiation}}
+
+template float X0<float>::value; // expected-note{{previous explicit instantiation}}
+template float X0<float>::value; // expected-error{{duplicate explicit instantiation}}
+
+// Make sure that we don't get tricked by redeclarations of nested classes.
+namespace NestedClassRedecls {
+ template<typename T>
+ struct X {
+ struct Nested;
+ friend struct Nested;
+
+ struct Nested {
+ Nested() {}
+ } nested;
+ };
+
+ X<int> xi;
+
+ template struct X<int>;
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
new file mode 100644
index 0000000..aecbfb5
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/examples.cpp
@@ -0,0 +1,334 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR5907 {
+ template<typename T> struct identity { typedef T type; };
+ struct A { A(); };
+ identity<A>::type::A() { }
+
+ struct B { void f(); };
+ template<typename T> struct C { typedef B type; };
+
+ void C<int>::type::f() { }
+}
+
+namespace PR9421 {
+ namespace N { template<typename T> struct S { void f(); }; }
+ typedef N::S<int> T;
+ namespace N { template<> void T::f() {} }
+}
+
+namespace PR8277 {
+ template< typename S >
+ struct C
+ {
+ template< int >
+ void F( void )
+ {
+ }
+ };
+
+ template< typename S >
+ struct D
+ {
+ typedef C< int > A;
+ };
+
+ typedef D< int >::A A;
+
+ template<>
+ template<>
+ void A::F< 0 >( void )
+ {
+ }
+}
+
+namespace PR8277b {
+ template<typename S> struct C {
+ void f();
+ };
+ template<typename S> struct D {
+ typedef C<int> A;
+ };
+ template<> void D<int>::A::f() {
+ }
+}
+
+namespace PR8708 {
+ template<typename T> struct A {
+ template<typename U> struct B {
+ // #2
+ void f();
+ };
+ };
+
+ // #A specialize the member template for
+ // implicit instantiation of A<int>,
+ // leaving the member template "unspecialized"
+ // (14.7.3/16). Specialization uses the syntax
+ // for explicit specialization (14.7.3/14)
+ template<> template<typename U>
+ struct A<int>::B {
+ // #1
+ void g();
+ };
+
+ // #1 define its function g. There is an enclosing
+ // class template, so we write template<> for each
+ // specialized template (14.7.3/15).
+ template<> template<typename U>
+ void A<int>::B<U>::g() { }
+
+ // #2 define the unspecialized member template's
+ // f
+ template<typename T> template<typename U>
+ void A<T>::B<U>::f() { }
+
+
+ // specialize the member template again, now
+ // specializing the member too. This specializes
+ // #A
+ template<> template<>
+ struct A<int>::B<int> {
+ // #3
+ void h();
+ };
+
+ // defines #3. There is no enclosing class template, so
+ // we write no "template<>".
+ void A<int>::B<int>::h() { }
+
+ void test() {
+ // calls #1
+ A<int>::B<float> a; a.g();
+
+ // calls #2
+ A<float>::B<int> b; b.f();
+
+ // calls #3
+ A<int>::B<int> c; c.h();
+ }
+}
+
+namespace PR9482 {
+ namespace N1 {
+ template <typename T> struct S {
+ void foo() {}
+ };
+ }
+
+ namespace N2 {
+ typedef N1::S<int> X;
+ }
+
+ namespace N1 {
+ template<> void N2::X::foo() {}
+ }
+}
+
+namespace PR9668 {
+ namespace First
+ {
+ template<class T>
+ class Bar
+ {
+ protected:
+
+ static const bool static_bool;
+ };
+ }
+
+ namespace Second
+ {
+ class Foo;
+ }
+
+ typedef First::Bar<Second::Foo> Special;
+
+ namespace
+ First
+ {
+ template<>
+ const bool Special::static_bool(false);
+ }
+}
+
+namespace PR9877 {
+ template<int>
+ struct X
+ {
+ struct Y;
+ };
+
+ template<> struct X<0>::Y { static const int Z = 1; };
+ template<> struct X<1>::Y { static const int Z = 1; };
+
+ const int X<0>::Y::Z;
+ template<> const int X<1>::Y::Z; // expected-error{{extraneous 'template<>' in declaration of variable 'Z'}}
+}
+
+namespace PR9913 {
+ template<class,class=int>struct S;
+ template<class X>struct S<X> {
+ template<class T> class F;
+ };
+
+ template<class A>
+ template<class B>
+ class S<A>::F{};
+}
+
+namespace template_class_spec_perClassDecl_nested
+{
+ template <typename T1> struct A {
+ template <typename T2> struct B {
+ template <typename T3> struct C {
+ static void foo();
+ };
+ };
+ };
+
+ template <> struct A<int> {
+ template <typename T2> struct B {
+ template <typename T3> struct C {
+ static void foo();
+ };
+ };
+ };
+
+ template <> template <typename T3> struct A<int>::B<int>::C {
+ static void foo();
+ };
+
+ template <> template <> struct A<int>::B<int>::C<int> {
+ static void foo();
+ };
+
+ template <> template<> template <typename T2> struct A<bool>::B<bool>::C {
+ static void foo();
+ };
+}
+
+
+namespace spec_vs_expl_inst {
+
+ // Test all permutations of Specialization,
+ // explicit instantiation Declaration, and explicit instantiation defInition.
+
+ namespace SDI { // PR11558
+ template <typename STRING_TYPE> class BasicStringPiece;
+ template <> class BasicStringPiece<int> { };
+ extern template class BasicStringPiece<int>;
+ template class BasicStringPiece<int>;
+ }
+
+ namespace SID {
+ template <typename STRING_TYPE> class BasicStringPiece;
+ template <> class BasicStringPiece<int> { };
+ template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}}
+ extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
+ }
+
+ namespace ISD {
+ template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}}
+ template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::ISD::BasicStringPiece<int>'}}
+ template <> class BasicStringPiece<int> { };
+ extern template class BasicStringPiece<int>;
+ }
+
+ namespace IDS {
+ template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}}
+ template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::IDS::BasicStringPiece<int>'}} // expected-note {{explicit instantiation definition is here}}
+ extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
+ template <> class BasicStringPiece<int> { };
+ }
+
+ namespace DIS {
+ template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}}
+ extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DIS::BasicStringPiece<int>'}}
+ template class BasicStringPiece<int>;
+ template <> class BasicStringPiece<int> { };
+ }
+
+ namespace DSI {
+ template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}}
+ extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation of undefined template 'spec_vs_expl_inst::DSI::BasicStringPiece<int>'}}
+ template <> class BasicStringPiece<int> { };
+ template class BasicStringPiece<int>;
+ }
+
+ // The same again, with a defined template class.
+
+ namespace SDI_WithDefinedTemplate {
+ template <typename STRING_TYPE> class BasicStringPiece {};
+ template <> class BasicStringPiece<int> { };
+ extern template class BasicStringPiece<int>;
+ template class BasicStringPiece<int>;
+ }
+
+ namespace SID_WithDefinedTemplate {
+ template <typename STRING_TYPE> class BasicStringPiece {};
+ template <> class BasicStringPiece<int> { };
+ template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}}
+ extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
+ }
+
+ namespace ISD_WithDefinedTemplate {
+ template <typename STRING_TYPE> class BasicStringPiece {};
+ template class BasicStringPiece<int>; // expected-note {{explicit instantiation first required here}}
+ template <> class BasicStringPiece<int> { }; // expected-error {{explicit specialization of 'spec_vs_expl_inst::ISD_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}}
+ extern template class BasicStringPiece<int>;
+ }
+
+ namespace IDS_WithDefinedTemplate {
+ template <typename STRING_TYPE> class BasicStringPiece {};
+ template class BasicStringPiece<int>; // expected-note {{explicit instantiation definition is here}} expected-note {{previous definition is here}}
+ extern template class BasicStringPiece<int>; // expected-error {{explicit instantiation declaration (with 'extern') follows explicit instantiation definition (without 'extern')}}
+ template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::IDS_WithDefinedTemplate::BasicStringPiece<int>'}}
+ }
+
+ namespace DIS_WithDefinedTemplate {
+ template <typename STRING_TYPE> class BasicStringPiece {};
+ extern template class BasicStringPiece<int>; // expected-note {{explicit instantiation first required here}}
+ template class BasicStringPiece<int>;
+ template <> class BasicStringPiece<int> { }; // expected-error {{explicit specialization of 'spec_vs_expl_inst::DIS_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}}
+ }
+
+ namespace DSI_WithDefinedTemplate {
+ template <typename STRING_TYPE> class BasicStringPiece {};
+ extern template class BasicStringPiece<int>; // expected-note {{explicit instantiation first required here}}
+ template <> class BasicStringPiece<int> { }; // expected-error {{explicit specialization of 'spec_vs_expl_inst::DSI_WithDefinedTemplate::BasicStringPiece<int>' after instantiation}}
+ template class BasicStringPiece<int>;
+ }
+
+ // And some more random tests.
+
+ namespace SII_WithDefinedTemplate {
+ template <typename STRING_TYPE> class BasicStringPiece {};
+ template <> class BasicStringPiece<int> { };
+ template class BasicStringPiece<int>; // expected-note {{previous explicit instantiation is here}}
+ template class BasicStringPiece<int>; // expected-error {{duplicate explicit instantiation of 'BasicStringPiece<int>'}}
+ }
+
+ namespace SIS {
+ template <typename STRING_TYPE> class BasicStringPiece;
+ template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}}
+ template class BasicStringPiece<int>;
+ template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SIS::BasicStringPiece<int>'}}
+ }
+
+ namespace SDS {
+ template <typename STRING_TYPE> class BasicStringPiece;
+ template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}}
+ extern template class BasicStringPiece<int>;
+ template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SDS::BasicStringPiece<int>'}}
+ }
+
+ namespace SDIS {
+ template <typename STRING_TYPE> class BasicStringPiece;
+ template <> class BasicStringPiece<int> { }; // expected-note {{previous definition is here}}
+ extern template class BasicStringPiece<int>;
+ template class BasicStringPiece<int>;
+ template <> class BasicStringPiece<int> { }; // expected-error {{redefinition of 'spec_vs_expl_inst::SDIS::BasicStringPiece<int>'}}
+ }
+
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp
new file mode 100644
index 0000000..3843c0d
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p1.cpp
@@ -0,0 +1,99 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %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 intent is to verify that
+// implicit instantiations do not occur (because the explicit specialization
+// is used instead).
+struct NonDefaultConstructible {
+ NonDefaultConstructible(int);
+};
+
+
+// C++ [temp.expl.spec]p1:
+// An explicit specialization of any of the following:
+
+// -- function template
+template<typename T> void f0(T) {
+ T t;
+}
+
+template<> void f0(NonDefaultConstructible) { }
+
+void test_f0(NonDefaultConstructible NDC) {
+ f0(NDC);
+}
+
+// -- class template
+template<typename T>
+struct X0 {
+ static T member;
+
+ void f1(T t) {
+ t = 17;
+ }
+
+ struct Inner : public T { };
+
+ template<typename U>
+ struct InnerTemplate : public T { };
+
+ template<typename U>
+ void ft1(T t, U u);
+};
+
+template<typename T>
+template<typename U>
+void X0<T>::ft1(T t, U u) {
+ t = u;
+}
+
+template<typename T> T X0<T>::member;
+
+template<> struct X0<void> { };
+X0<void> test_X0;
+
+
+// -- member function of a class template
+template<> void X0<void*>::f1(void *) { }
+
+void test_spec(X0<void*> xvp, void *vp) {
+ xvp.f1(vp);
+}
+
+// -- static data member of a class template
+template<>
+NonDefaultConstructible X0<NonDefaultConstructible>::member = 17;
+
+NonDefaultConstructible &get_static_member() {
+ return X0<NonDefaultConstructible>::member;
+}
+
+// -- member class of a class template
+template<>
+struct X0<void*>::Inner { };
+
+X0<void*>::Inner inner0;
+
+// -- member class template of a class template
+template<>
+template<>
+struct X0<void*>::InnerTemplate<int> { };
+
+X0<void*>::InnerTemplate<int> inner_template0;
+
+// -- member function template of a class template
+template<>
+template<>
+void X0<void*>::ft1(void*, const void*) { }
+
+void test_func_template(X0<void *> xvp, void *vp, const void *cvp) {
+ xvp.ft1(vp, cvp);
+}
+
+// example from the standard:
+template<class T> class stream;
+template<> class stream<char> { /* ... */ };
+template<class T> class Array { /* ... */ };
+template<class T> void sort(Array<T>& v) { /* ... */ }
+template<> void sort<char*>(Array<char*>&) ;
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p10.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p10.cpp
new file mode 100644
index 0000000..b81c1e7
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p10.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T> class X;
+template<> class X<int>; // expected-note{{forward}}
+X<int>* p;
+
+X<int> x; // expected-error{{incomplete type}}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p11.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p11.cpp
new file mode 100644
index 0000000..5fa2f62
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p11.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T> class Array { /* ... */ };
+template<class T> void sort(Array<T>& v);
+
+// explicit specialization for sort(Array<int>&)
+// with deduced template-argument of type int
+template<> void sort(Array<int>&);
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p13.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p13.cpp
new file mode 100644
index 0000000..fb6d1be
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p13.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<typename T> void f(T);
+
+template<> void f(int) { }
+void f(int) { }
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp
new file mode 100644
index 0000000..121cb8e
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p14.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s | FileCheck %s
+
+template<class T> void f(T) { /* ... */ }
+template<class T> inline void g(T) { /* ... */ }
+
+// CHECK: define void @_Z1gIiEvT_
+template<> void g<>(int) { /* ... */ }
+
+template<class T>
+struct X {
+ void f() { }
+ void g();
+ void h();
+};
+
+template<class T>
+void X<T>::g() {
+}
+
+template<class T>
+inline void X<T>::h() {
+}
+
+// CHECK: define void @_ZN1XIiE1fEv
+template<> void X<int>::f() { }
+
+// CHECK: define void @_ZN1XIiE1hEv
+template<> void X<int>::h() { }
+
+// CHECK: define linkonce_odr void @_Z1fIiEvT_
+template<> inline void f<>(int) { /* ... */ }
+
+// CHECK: define linkonce_odr void @_ZN1XIiE1gEv
+template<> inline void X<int>::g() { }
+
+void test(X<int> xi) {
+ f(17);
+ g(17);
+ xi.f();
+ xi.g();
+ xi.h();
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp
new file mode 100644
index 0000000..72f33df
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p15.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct NonDefaultConstructible {
+ NonDefaultConstructible(const NonDefaultConstructible&); // expected-note{{candidate constructor}}
+};
+
+template<typename T, typename U>
+struct X {
+ static T member;
+};
+
+template<typename T, typename U>
+T X<T, U>::member; // expected-error{{no matching constructor}}
+
+// Okay; this is a declaration, not a definition.
+template<>
+NonDefaultConstructible X<NonDefaultConstructible, long>::member;
+
+NonDefaultConstructible &test(bool b) {
+ return b? X<NonDefaultConstructible, int>::member // expected-note{{instantiation}}
+ : X<NonDefaultConstructible, long>::member;
+}
+
+namespace rdar9422013 {
+ template<int>
+ struct X {
+ struct Inner {
+ static unsigned array[17];
+ };
+ };
+
+ template<> unsigned X<1>::Inner::array[]; // okay
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp
new file mode 100644
index 0000000..c7597e9
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p16.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<class T> struct A {
+ void f(T);
+ template<class X1> void g1(T, X1);
+ template<class X2> void g2(T, X2);
+ void h(T) { }
+};
+
+// specialization
+template<> void A<int>::f(int);
+
+// out of class member template definition
+template<class T> template<class X1> void A<T>::g1(T, X1) { }
+
+// member template specialization
+template<> template<class X1> void A<int>::g1(int, X1);
+
+// member template specialization
+template<> template<>
+ void A<int>::g1(int, char); // X1 deduced as char
+
+template<> template<>
+ void A<int>::g2<char>(int, char); // X2 specified as char
+ // member specialization even if defined in class definition
+
+template<> void A<int>::h(int) { }
+
+namespace PR10024 {
+ template <typename T>
+ struct Test{
+ template <typename U>
+ void get(U i) {}
+ };
+
+ template <typename T>
+ template <>
+ void Test<T>::get<double>(double i) {} // expected-error{{cannot specialize (with 'template<>') a member of an unspecialized template}}
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
new file mode 100644
index 0000000..56231e2
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p17.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<class T1>
+class A {
+ template<class T2> class B {
+ void mf();
+ };
+};
+
+template<> template<> class A<int>::B<double>;
+template<> template<> void A<char>::B<char>::mf();
+
+template<> void A<char>::B<int>::mf(); // expected-error{{requires 'template<>'}}
+
+namespace test1 {
+ template <class> class A {
+ static int foo;
+ static int bar;
+ };
+ typedef A<int> AA;
+
+ template <> int AA::foo = 0;
+ int AA::bar = 1; // expected-error {{template specialization requires 'template<>'}}
+ int A<float>::bar = 2; // expected-error {{template specialization requires 'template<>'}}
+
+ template <> class A<double> {
+ public:
+ static int foo;
+ static int bar;
+ };
+
+ typedef A<double> AB;
+ template <> int AB::foo = 0; // expected-error{{extraneous 'template<>'}}
+ int AB::bar = 1;
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp
new file mode 100644
index 0000000..4d175a8
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p18.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<class T1> class A {
+ template<class T2> class B {
+ template<class T3> void mf1(T3);
+ void mf2();
+ };
+};
+
+template<> template<class X>
+class A<long>::B { };
+
+template<> template<> template<class T>
+ void A<int>::B<double>::mf1(T t) { }
+
+template<> template<> template<class T>
+void A<long>::B<double>::mf1(T t) { } // expected-error{{does not match}}
+
+// FIXME: This diagnostic could probably be better.
+template<class Y> template<>
+ void A<Y>::B<double>::mf2() { } // expected-error{{does not refer}}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp
new file mode 100644
index 0000000..1c2ea7e
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p19.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X {
+ template<typename U> struct Inner { };
+
+ template<typename U> void f(T, U) { }
+};
+
+template<> template<typename U>
+struct X<int>::Inner {
+ U member;
+};
+
+template<> template<typename U>
+void X<int>::f(int x, U y) {
+ x = y; // expected-error{{incompatible type}}
+}
+
+void test(X<int> xi, X<long> xl, float *fp) {
+ X<int>::Inner<float*> xii;
+ xii.member = fp;
+ xi.f(17, 25);
+ xi.f(17, 3.14159);
+ xi.f(17, fp); // expected-note{{instantiation}}
+ X<long>::Inner<float*> xli;
+
+ xli.member = fp; // expected-error{{no member}}
+ xl.f(17, fp); // okay
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
new file mode 100644
index 0000000..b0a19fb
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2-0x.cpp
@@ -0,0 +1,302 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %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{{does not enclose namespace}}
+}
+
+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{{does not enclose namespace}}
+}
+
+// -- 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{{does not enclose namespace}}
+}
+
+
+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);
+}
+
+namespace has_inline_namespaces {
+ inline namespace inner {
+ template<class T> void f(T&);
+
+ template<class T>
+ struct X0 {
+ struct MemberClass;
+
+ void mem_func();
+
+ template<typename U>
+ struct MemberClassTemplate;
+
+ template<typename U>
+ void mem_func_template(U&);
+
+ static int value;
+ };
+ }
+
+ struct X1;
+ struct X2;
+
+ // An explicit specialization whose declarator-id is not qualified
+ // shall be declared in the nearest enclosing namespace of the
+ // template, or, if the namespace is inline (7.3.1), any namespace
+ // from its enclosing namespace set.
+ template<> void f(X1&);
+ template<> void f<X2>(X2&);
+
+ template<> struct X0<X1> { };
+
+ template<> struct X0<X2>::MemberClass { };
+
+ template<> void X0<X2>::mem_func();
+
+ template<> template<typename T> struct X0<X2>::MemberClassTemplate { };
+
+ template<> template<typename T> void X0<X2>::mem_func_template(T&) { }
+
+ template<> int X0<X2>::value = 12;
+}
+
+struct X3;
+struct X4;
+
+template<> void has_inline_namespaces::f(X3&);
+template<> void has_inline_namespaces::f<X4>(X4&);
+
+template<> struct has_inline_namespaces::X0<X3> { };
+
+template<> struct has_inline_namespaces::X0<X4>::MemberClass { };
+
+template<> void has_inline_namespaces::X0<X4>::mem_func();
+
+template<> template<typename T>
+struct has_inline_namespaces::X0<X4>::MemberClassTemplate { };
+
+template<> template<typename T>
+void has_inline_namespaces::X0<X4>::mem_func_template(T&) { }
+
+template<> int has_inline_namespaces::X0<X4>::value = 13;
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
new file mode 100644
index 0000000..c972bf7
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p2.cpp
@@ -0,0 +1,252 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %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) { // expected-note{{here}}
+ 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{{does not enclose namespace}}
+}
+
+template<> void N0::f0(double); // expected-warning{{C++11 extension}}
+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 2{{here}}
+ static T member; // expected-note{{here}}
+
+ void f1(T t) { // expected-note{{explicitly specialized declaration is here}}
+ t = 17;
+ }
+
+ struct Inner : public T { }; // expected-note 3{{here}}
+
+ template<typename U>
+ struct InnerTemplate : public T { }; // expected-note 2{{explicitly specialized}} \
+ // expected-error{{base specifier}}
+
+ template<typename U>
+ void ft1(T t, U u); // expected-note{{explicitly specialized}}
+};
+
+}
+
+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> { }; // expected-warning{{C++11 extension}}
+N0::X0<void> test_X0;
+
+namespace N1 {
+ template<> struct N0::X0<const void> { }; // expected-error{{originally}}
+}
+
+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 *) { } // expected-warning{{member function specialization}}
+
+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; // expected-warning{{C++11 extension}}
+
+template<> float N0::X0<float>::member = 3.14f;
+
+namespace N1 {
+ template<> double N0::X0<double>::member = 3.14; // expected-error{{does not enclose namespace}}
+}
+
+// -- 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 { }; // expected-warning{{C++11 extension}}
+
+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> { }; // expected-warning{{class template specialization}}
+
+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) { } // expected-warning{{function template specialization}}
+
+namespace N1 {
+ template<> template<>
+ void N0::X0<void*>::ft1(void *, long) { } // expected-error{{does not enclose namespace}}
+}
+
+
+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);
+}
+
+namespace PR8979 {
+ template<typename Z>
+ struct X0 {
+ template <class T, class U> class Inner;
+ struct OtherInner;
+ template<typename T, typename U> void f(Inner<T, U>&);
+
+ typedef Inner<OtherInner, OtherInner> MyInner;
+ template<> void f(MyInner&); // expected-error{{cannot specialize a function 'f' within class scope}}
+ };
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp
new file mode 100644
index 0000000..86cdcf8
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+void f(T);
+
+template<typename T>
+struct A { };
+
+struct X {
+ template<> friend void f<int>(int); // expected-error{{in a friend}}
+ template<> friend class A<int>; // expected-error{{cannot be a friend}}
+
+ friend void f<float>(float); // okay
+ friend class A<float>; // okay
+};
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp
new file mode 100644
index 0000000..ab26f40
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p21.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X {
+ void mf1(T);
+ template<typename U> void mf2(T, U); // expected-note{{previous}}
+};
+
+template<>
+void X<int>::mf1(int i = 17) // expected-error{{default}}
+{
+}
+
+template<> template<>
+void X<int>::mf2(int, int = 17) // expected-error{{default}}
+{ }
+
+template<> template<typename U>
+void X<int>::mf2(int, U = U()) // expected-error{{default}}
+{
+}
+
+template<>
+struct X<float> {
+ void mf1(float);
+};
+
+void X<float>::mf1(float = 3.14f) // okay
+{
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp
new file mode 100644
index 0000000..84841cb
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p3.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N {
+ template<class T> class X;
+}
+
+template<> class X<int> { /* ... */ }; // expected-error {{non-template class 'X'}}
+
+namespace N {
+
+template<> class X<char*> { /* ... */ }; // OK: X is a template
+
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
new file mode 100644
index 0000000..772aef6
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p4.cpp
@@ -0,0 +1,58 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct IntHolder { // expected-note{{here}} // expected-note 2{{candidate constructor (the implicit copy constructor)}}
+ IntHolder(int); // expected-note 2{{candidate constructor}}
+};
+
+template<typename T, typename U>
+struct X { // expected-note{{here}}
+ void f() {
+ T t; // expected-error{{no matching}}
+ }
+
+ void g() { }
+
+ struct Inner { // expected-error{{implicit default}}
+ T value; // expected-note {{member is declared here}}
+ };
+
+ static T value;
+};
+
+template<typename T, typename U>
+T X<T, U>::value; // expected-error{{no matching constructor}}
+
+IntHolder &test_X_IntHolderInt(X<IntHolder, int> xih) {
+ xih.g(); // okay
+ xih.f(); // expected-note{{instantiation}}
+
+ X<IntHolder, int>::Inner inner; // expected-note {{first required here}}
+
+ return X<IntHolder, int>::value; // expected-note{{instantiation}}
+}
+
+// Explicitly specialize the members of X<IntHolder, long> to not cause
+// problems with instantiation.
+template<>
+void X<IntHolder, long>::f() { }
+
+template<>
+struct X<IntHolder, long>::Inner {
+ Inner() : value(17) { }
+ IntHolder value;
+};
+
+template<>
+IntHolder X<IntHolder, long>::value = 17;
+
+IntHolder &test_X_IntHolderInt(X<IntHolder, long> xih) {
+ xih.g(); // okay
+ xih.f(); // okay, uses specialization
+
+ X<IntHolder, long>::Inner inner; // okay, uses specialization
+
+ return X<IntHolder, long>::value; // okay, uses specialization
+}
+
+template<>
+X<IntHolder, long>::X() { } // expected-error{{instantiated member}}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp
new file mode 100644
index 0000000..f49190e
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p5-example.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<class T> struct A {
+ struct B { };
+ template<class U> struct C { };
+};
+ template<> struct A<int> {
+ void f(int);
+};
+void h() {
+ A<int> a;
+ a.f(16);
+}
+// A<int>::f must be defined somewhere
+// template<> not used for a member of an // explicitly specialized class template
+void A<int>::f(int) { /* ... */ }
+ template<> struct A<char>::B {
+ void f();
+};
+// template<> also not used when defining a member of // an explicitly specialized member class
+void A<char>::B::f() { /* ... */ }
+ template<> template<class U> struct A<char>::C {
+ void f();
+};
+
+template<>
+template<class U> void A<char>::C<U>::f() { /* ... */ }
+ template<> struct A<short>::B {
+ void f();
+};
+template<> void A<short>::B::f() { /* ... */ } // expected-error{{no function template matches function template specialization 'f'}}
+ template<> template<class U> struct A<short>::C {
+ void f();
+};
+template<class U> void A<short>::C<U>::f() { /* ... */ } // expected-error{{template parameter list matching the non-templated nested type 'A<short>' should be empty ('template<>')}}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp
new file mode 100644
index 0000000..512ea47
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p5.cpp
@@ -0,0 +1,61 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct IntHolder {
+ IntHolder(int);
+};
+
+template<typename T, typename U>
+struct X {
+ void f() {
+ T t;
+ }
+
+ void g() { }
+
+ struct Inner {
+ T value;
+ };
+
+ static T value;
+};
+
+template<typename T, typename U>
+T X<T, U>::value;
+
+// Explicitly specialize the members of X<IntHolder, long> to not cause
+// problems with instantiation, but only provide declarations (not definitions).
+template<>
+void X<IntHolder, long>::f();
+
+template<>
+struct X<IntHolder, long>::Inner; // expected-note{{forward declaration}}
+
+template<>
+IntHolder X<IntHolder, long>::value;
+
+IntHolder &test_X_IntHolderInt(X<IntHolder, long> xih) {
+ xih.g(); // okay
+ xih.f(); // okay, uses specialization
+
+ X<IntHolder, long>::Inner inner; // expected-error {{incomplete}}
+
+ return X<IntHolder, long>::value; // okay, uses specialization
+}
+
+
+template<class T> struct A {
+ void f(T) { /* ... */ }
+};
+
+template<> struct A<int> {
+ void f(int);
+};
+
+void h() {
+ A<int> a;
+ a.f(16); // A<int>::f must be defined somewhere
+}
+
+// explicit specialization syntax not used for a member of
+// explicitly specialized class template specialization
+void A<int>::f(int) { /* ... */ }
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp
new file mode 100644
index 0000000..f539471
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p6.cpp
@@ -0,0 +1,63 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 {
+ void f();
+
+ template<typename U>
+ void g(U);
+
+ struct Nested {
+ };
+
+ static T member;
+};
+
+int &use_X0_int(X0<int> x0i, // expected-note{{implicit instantiation first required here}}
+ int i) {
+ x0i.f(); // expected-note{{implicit instantiation first required here}}
+ x0i.g(i); // expected-note{{implicit instantiation first required here}}
+ X0<int>::Nested nested; // expected-note{{implicit instantiation first required here}}
+ return X0<int>::member; // expected-note{{implicit instantiation first required here}}
+}
+
+template<>
+void X0<int>::f() { // expected-error{{after instantiation}}
+}
+
+template<> template<>
+void X0<int>::g(int) { // expected-error{{after instantiation}}
+}
+
+template<>
+struct X0<int>::Nested { }; // expected-error{{after instantiation}}
+
+template<>
+int X0<int>::member = 17; // expected-error{{after instantiation}}
+
+template<>
+struct X0<int> { }; // expected-error{{after instantiation}}
+
+// Example from the standard
+template<class T> class Array { /* ... */ };
+
+template<class T> void sort(Array<T>& v) { /* ... */ }
+
+struct String {};
+
+void f(Array<String>& v) {
+
+ sort(v); // expected-note{{required}}
+ // use primary template
+ // sort(Array<T>&), T is String
+}
+
+template<> void sort<String>(Array<String>& v); // // expected-error{{after instantiation}}
+template<> void sort<>(Array<char*>& v); // OK: sort<char*> not yet used
+
+namespace PR6160 {
+ template<typename T> void f(T);
+ template<> void f(int);
+ extern template void f(int);
+ template<> void f(int) { }
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p9.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p9.cpp
new file mode 100644
index 0000000..d4ce01f
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p9.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N {
+ template<class T> class X { /* ... */ };
+ template<class T> class Y { /* ... */ };
+ template<> class X<int> { /* ... */ };
+ template<> class Y<double>;
+
+ const unsigned NumElements = 17;
+}
+
+template<> class N::Y<double> {
+ int array[NumElements];
+};
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp
new file mode 100644
index 0000000..80f0598
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p1-0x.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+template<typename T>
+struct X {
+ void f() {}
+};
+
+template inline void X<int>::f(); // expected-error{{explicit instantiation cannot be 'inline'}}
+
+template<typename T>
+struct Y {
+ constexpr int f() { return 0; }
+};
+
+template constexpr int Y<int>::f(); // expected-error{{explicit instantiation cannot be 'constexpr'}}
+
+template<typename T>
+struct Z {
+ enum E : T { e1, e2 };
+ T t; // expected-note {{refers here}}
+};
+
+template enum Z<int>::E; // expected-error {{enumerations cannot be explicitly instantiated}}
+template int Z<int>::t; // expected-error {{explicit instantiation of 't' does not refer to}}
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp
new file mode 100644
index 0000000..d0df305
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p1-emit.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -emit-llvm -triple x86_64-apple-darwin10 -o - %s | FileCheck %s
+template<typename T>
+struct X {
+ static T member1;
+ static T member2;
+ static T member3;
+};
+
+template<typename T>
+T X<T>::member1;
+
+template<typename T>
+T X<T>::member2 = 17;
+
+// CHECK: @_ZN1XIiE7member1E = weak_odr global i32 0
+template int X<int>::member1;
+
+// CHECK: @_ZN1XIiE7member2E = weak_odr global i32 17
+template int X<int>::member2;
+
+// For implicit instantiation of
+long& get(bool Cond1, bool Cond2) {
+ // CHECK: @_ZN1XIlE7member1E = weak_odr global i64 0
+ // CHECK: @_ZN1XIlE7member2E = weak_odr global i64 17
+ // CHECK: @_ZN1XIlE7member3E = external global i64
+ return Cond1? X<long>::member1
+ : Cond2? X<long>::member2
+ : X<long>::member3;
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p1.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p1.cpp
new file mode 100644
index 0000000..b426339
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p1.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct C { };
+
+template<typename T>
+struct X0 {
+ T value; // expected-error{{incomplete}}
+};
+
+// Explicitly instantiate a class template specialization
+template struct X0<int>;
+template struct X0<void>; // expected-note{{instantiation}}
+
+// Explicitly instantiate a function template specialization
+template<typename T>
+void f0(T t) {
+ ++t; // expected-error{{cannot increment}}
+}
+
+template void f0(int);
+template void f0<long>(long);
+template void f0<>(unsigned);
+template void f0(int C::*); // expected-note{{instantiation}}
+
+// Explicitly instantiate a member template specialization
+template<typename T>
+struct X1 {
+ template<typename U>
+ struct Inner {
+ T member1;
+ U member2; // expected-error{{incomplete}}
+ };
+
+ template<typename U>
+ void f(T& t, U u) {
+ t = u; // expected-error{{incompatible}}
+ }
+};
+
+template struct X1<int>::Inner<float>;
+template struct X1<int>::Inner<double>;
+template struct X1<int>::Inner<void>; // expected-note{{instantiation}}
+
+template void X1<int>::f(int&, float);
+template void X1<int>::f<long>(int&, long);
+template void X1<int>::f<>(int&, double);
+template void X1<int>::f<>(int&, int*); // expected-note{{instantiation}}
+
+// Explicitly instantiate members of a class template
+struct Incomplete; // expected-note{{forward declaration}}
+struct NonDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor) not viable}}
+ NonDefaultConstructible(int); // expected-note{{candidate constructor}}
+};
+
+template<typename T, typename U>
+struct X2 {
+ void f(T &t, U u) {
+ t = u; // expected-error{{incompatible}}
+ }
+
+ struct Inner {
+ T member1;
+ U member2; // expected-error{{incomplete}}
+ };
+
+ static T static_member1;
+ static U static_member2;
+};
+
+template<typename T, typename U>
+T X2<T, U>::static_member1 = 17; // expected-error{{cannot initialize}}
+
+template<typename T, typename U>
+U X2<T, U>::static_member2; // expected-error{{no matching}}
+
+template void X2<int, float>::f(int &, float);
+template void X2<int, float>::f(int &, double); // expected-error{{does not refer}}
+template void X2<int, int*>::f(int&, int*); // expected-note{{instantiation}}
+
+template struct X2<int, float>::Inner;
+template struct X2<int, Incomplete>::Inner; // expected-note{{instantiation}}
+
+template int X2<int, float>::static_member1;
+template int* X2<int*, float>::static_member1; // expected-note{{instantiation}}
+template
+ NonDefaultConstructible X2<NonDefaultConstructible, int>::static_member1;
+
+template
+ NonDefaultConstructible X2<int, NonDefaultConstructible>::static_member2; // expected-note{{instantiation}}
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p10.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p10.cpp
new file mode 100644
index 0000000..290a874
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p10.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 {
+ void f(T&);
+
+ struct Inner;
+
+ static T static_var;
+};
+
+template<typename T>
+void X0<T>::f(T& t) {
+ t = 1; // expected-error{{incompatible type}}
+}
+
+template<typename T>
+struct X0<T>::Inner {
+ T member;
+};
+
+template<typename T>
+T X0<T>::static_var = 1; // expected-error{{cannot initialize}}
+
+extern template struct X0<void*>;
+template struct X0<void*>; // expected-note 2{{instantiation}}
+
+template struct X0<int>; // expected-note 4{{explicit instantiation definition is here}}
+
+extern template void X0<int>::f(int&); // expected-error{{follows explicit instantiation definition}}
+extern template struct X0<int>::Inner; // expected-error{{follows explicit instantiation definition}}
+extern template int X0<int>::static_var; // expected-error{{follows explicit instantiation definition}}
+extern template struct X0<int>; // expected-error{{follows explicit instantiation definition}}
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p11.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p11.cpp
new file mode 100644
index 0000000..4ca5428
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p11.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+class X {
+ template <typename T> class Y {};
+};
+
+class A {
+ class B {};
+ class C {};
+};
+
+// C++0x [temp.explicit] 14.7.2/11:
+// The usual access checking rules do not apply to names used to specify
+// explicit instantiations.
+template class X::Y<A::B>;
+
+// As an extension, this rule is applied to explicit specializations as well.
+template <> class X::Y<A::C> {};
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p12.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p12.cpp
new file mode 100644
index 0000000..c756486
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p12.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+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.
+
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp
new file mode 100644
index 0000000..1dfcf0c
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p2.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat %s
+
+// Example from the standard
+template<class T> class Array { void mf() { } };
+
+template class Array<char>;
+template void Array<int>::mf();
+template<class T> void sort(Array<T>& v) { /* ... */ }
+template void sort(Array<char>&);
+namespace N {
+ template<class T> void f(T&) { }
+}
+template void N::f<int>(int&);
+
+
+template<typename T>
+struct X0 {
+ struct Inner {};
+ void f() { }
+ static T value;
+};
+
+template<typename T>
+T X0<T>::value = 17;
+
+typedef X0<int> XInt;
+
+template struct XInt::Inner; // expected-warning{{template-id}}
+template void XInt::f(); // expected-warning{{template-id}}
+template int XInt::value; // expected-warning{{template-id}}
+
+namespace N {
+ template<typename T>
+ struct X1 { // expected-note{{explicit instantiation refers here}}
+ };
+
+ template<typename T>
+ void f1(T) {} // expected-note{{explicit instantiation refers here}}
+}
+using namespace N;
+
+template struct X1<int>; // expected-warning{{must occur in}}
+template void f1(int); // expected-warning{{must occur in}}
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p3-0x.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p3-0x.cpp
new file mode 100644
index 0000000..1028830
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p3-0x.cpp
@@ -0,0 +1,65 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// If the name declared in the explicit instantiation is an
+// unqualified name, the explicit instantiation shall appear in the
+// namespace where its template is declared or, if that namespace is
+// inline (7.3.1), any namespace from its enclosing namespace set.
+
+namespace has_inline_namespaces {
+ inline namespace inner {
+ template<class T> void f(T&) {}
+
+ template<class T>
+ struct X0 {
+ struct MemberClass {};
+
+ void mem_func() {}
+
+ template<typename U>
+ struct MemberClassTemplate {};
+
+ template<typename U>
+ void mem_func_template(U&) {}
+
+ static int value;
+ };
+ }
+
+ template<typename T> int X0<T>::value = 17;
+
+ struct X1 {};
+ struct X2 {};
+
+ template void f(X1&);
+ template void f<X2>(X2&);
+
+ template struct X0<X1>;
+
+ template struct X0<X2>::MemberClass;
+
+ template void X0<X2>::mem_func();
+
+ template struct X0<X2>::MemberClassTemplate<X1>;
+
+ template void X0<X2>::mem_func_template(X1&);
+
+ template int X0<X2>::value;
+}
+
+struct X3;
+struct X4;
+
+template void has_inline_namespaces::f(X3&);
+template void has_inline_namespaces::f<X4>(X4&);
+
+template struct has_inline_namespaces::X0<X3>;
+
+template struct has_inline_namespaces::X0<X4>::MemberClass;
+
+template void has_inline_namespaces::X0<X4>::mem_func();
+
+template
+struct has_inline_namespaces::X0<X4>::MemberClassTemplate<X3>;
+
+template
+void has_inline_namespaces::X0<X4>::mem_func_template(X3&);
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p3.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p3.cpp
new file mode 100644
index 0000000..38ae768
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p3.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wc++11-compat %s
+
+// A declaration of a function template shall be in scope at the point of the
+// explicit instantiation of the function template.
+template<typename T> void f0(T);
+template void f0(int); // okay
+template<typename T> void f0(T) { }
+
+// A definition of the class or class template containing a member function
+// template shall be in scope at the point of the explicit instantiation of
+// the member function template.
+struct X0; // expected-note {{forward declaration}}
+template<typename> struct X1; // expected-note 5{{declared here}}
+
+template void X0::f0<int>(int); // expected-error {{incomplete type}}
+template void X1<int>::f0<int>(int); // expected-error {{implicit instantiation of undefined template}}
+
+// A definition of a class template or class member template shall be in scope
+// at the point of the explicit instantiation of the class template or class
+// member template.
+template struct X1<float>; // expected-error{{explicit instantiation of undefined template}}
+
+template<typename T>
+struct X2 { // expected-note 4{{refers here}}
+ template<typename U>
+ struct Inner; // expected-note{{declared here}}
+
+ struct InnerClass; // expected-note{{forward declaration}}
+};
+
+template struct X2<int>::Inner<float>; // expected-error{{explicit instantiation of undefined template}}
+
+// A definition of a class template shall be in scope at the point of an
+// explicit instantiation of a member function or a static data member of the
+// class template.
+template void X1<int>::f1(int); // expected-error {{undefined template}}
+template void X1<int>::f1<int>(int); // expected-error {{undefined template}}
+
+template int X1<int>::member; // expected-error {{undefined template}}
+
+// A definition of a member class of a class template shall be in scope at the
+// point of an explicit instantiation of the member class.
+template struct X2<float>::InnerClass; // expected-error{{undefined member}}
+
+// If the declaration of the explicit instantiation names an implicitly-declared
+// special member function (Clause 12), the program is ill-formed.
+template X2<int>::X2(); // expected-error{{not an instantiation}}
+template X2<int>::X2(const X2&); // expected-error{{not an instantiation}}
+template X2<int>::~X2(); // expected-error{{not an instantiation}}
+template X2<int> &X2<int>::operator=(const X2<int>&); // expected-error{{not an instantiation}}
+
+
+// A definition of a class template is sufficient to explicitly
+// instantiate a member of the class template which itself is not yet defined.
+namespace PR7979 {
+ template <typename T> struct S {
+ void f();
+ static void g();
+ static int i;
+ struct S2 {
+ void h();
+ };
+ };
+
+ template void S<int>::f();
+ template void S<int>::g();
+ template int S<int>::i;
+ template void S<int>::S2::h();
+
+ template <typename T> void S<T>::f() {}
+ template <typename T> void S<T>::g() {}
+ template <typename T> int S<T>::i;
+ template <typename T> void S<T>::S2::h() {}
+}
+
+namespace PR11599 {
+ template <typename STRING_TYPE> class BasicStringPiece; // expected-note {{template is declared here}}
+
+ extern template class BasicStringPiece<int>; // expected-error{{explicit instantiation of undefined template 'PR11599::BasicStringPiece<int>}}
+ template class BasicStringPiece<int>;
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
new file mode 100644
index 0000000..09c428e
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p4.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
+
+template<typename T> void f0(T); // expected-note{{here}}
+template void f0(int); // expected-error{{explicit instantiation of undefined function template}}
+
+template<typename T>
+struct X0 {
+ struct Inner;
+
+ void f1(); // expected-note{{here}}
+
+ static T value; // expected-note{{here}}
+};
+
+template void X0<int>::f1(); // expected-error{{explicit instantiation of undefined member function}}
+
+template int X0<int>::value; // expected-error{{explicit instantiation of undefined static data member}}
+
+template<> void f0(long); // expected-note{{previous template specialization is here}}
+template void f0(long); // expected-warning{{explicit instantiation of 'f0<long>' that occurs after an explicit specialization will be ignored}}
+
+template<> void X0<long>::f1(); // expected-note{{previous template specialization is here}}
+template void X0<long>::f1(); // expected-warning{{explicit instantiation of 'f1' that occurs after an explicit specialization will be ignored}}
+
+template<> struct X0<long>::Inner; // expected-note{{previous template specialization is here}}
+template struct X0<long>::Inner; // expected-warning{{explicit instantiation of 'Inner' that occurs after an explicit specialization will be ignored}}
+
+template<> long X0<long>::value; // expected-note{{previous template specialization is here}}
+template long X0<long>::value; // expected-warning{{explicit instantiation of 'value' that occurs after an explicit specialization will be ignored}}
+
+template<> struct X0<double>; // expected-note{{previous template specialization is here}}
+template struct X0<double>; // expected-warning{{explicit instantiation of 'X0<double>' that occurs after an explicit specialization will be ignored}}
+
+// PR 6458
+namespace test0 {
+ template <class T> class foo {
+ int compare(T x, T y);
+ };
+
+ template <> int foo<char>::compare(char x, char y);
+ template <class T> int foo<T>::compare(T x, T y) {
+ // invalid at T=char; if we get a diagnostic here, we're
+ // inappropriately instantiating this template.
+ void *ptr = x;
+ }
+ extern template class foo<char>; // expected-warning {{extern templates are a C++11 extension}}
+ template class foo<char>;
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p5.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p5.cpp
new file mode 100644
index 0000000..8422c51
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p5.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wc++11-compat %s
+
+namespace N {
+ template<class T> class Y { // expected-note{{explicit instantiation refers here}}
+ void mf() { }
+ };
+}
+
+template class Z<int>; // expected-error{{explicit instantiation of non-template class 'Z'}}
+
+// FIXME: This example from the standard is wrong; note posted to CWG reflector
+// on 10/27/2009
+using N::Y;
+template class Y<int>; // expected-warning{{must occur in}}
+
+template class N::Y<char*>;
+template void N::Y<double>::mf();
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p6.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p6.cpp
new file mode 100644
index 0000000..1382272
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p6.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T> class Array { /* ... */ };
+template<class T> void sort(Array<T>& v) { }
+
+// instantiate sort(Array<int>&) - template-argument deduced
+template void sort<>(Array<int>&);
+
+template void sort(Array<long>&);
+
+template<typename T, typename U> void f0(T, U*) { }
+
+template void f0<int>(int, float*);
+template void f0<>(double, float*);
+
+template<typename T> struct hash { };
+struct S {
+ bool operator==(const S&) const { return false; }
+};
+
+template<typename T> struct Hash_map {
+ void Method(const T& x) { h(x); }
+ hash<T> h;
+};
+
+Hash_map<S> *x;
+const Hash_map<S> *foo() {
+ return x;
+}
+
+template<> struct hash<S> {
+ int operator()(const S& k) const {
+ return 0;
+ }
+};
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p7.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p7.cpp
new file mode 100644
index 0000000..7398dca
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p7.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 {
+ struct MemberClass {
+ T member; // expected-error{{with function type}}
+ };
+
+ T* f0(T* ptr) {
+ return ptr + 1; // expected-error{{pointer to the function}}
+ }
+
+ static T* static_member;
+};
+
+template<typename T>
+T* X0<T>::static_member = ((T*)0) + 1; // expected-error{{pointer to the function}}
+
+template class X0<int>; // okay
+
+template class X0<int(int)>; // expected-note 3{{requested here}}
+
+// Specialize everything, so that the explicit instantiation does not trigger
+// any diagnostics.
+template<>
+struct X0<int(long)>::MemberClass { };
+
+typedef int int_long_func(long);
+template<>
+int_long_func *X0<int_long_func>::f0(int_long_func *) { return 0; }
+
+template<>
+int_long_func *X0<int(long)>::static_member;
+
+template class X0<int(long)>;
+
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p8.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p8.cpp
new file mode 100644
index 0000000..550078a
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p8.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+template<typename T>
+struct X0 {
+ struct MemberClass;
+
+ T* f0(T* ptr);
+
+ static T* static_member;
+};
+
+template class X0<int(int)>; // ok; nothing gets instantiated.
+
+template<typename T>
+struct X0<T>::MemberClass {
+ T member;
+};
+
+template<typename T>
+T* X0<T>::f0(T* ptr) {
+ return ptr + 1;
+}
+
+template<typename T>
+T* X0<T>::static_member = 0;
+
+template class X0<int>; // ok
+
+
+template<typename T>
+struct X1 {
+ enum class E {
+ e = T::error // expected-error 2{{no members}}
+ };
+};
+template struct X1<int>; // expected-note {{here}}
+
+extern template struct X1<char>; // ok
+
+template struct X1<char>; // expected-note {{here}}
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
new file mode 100644
index 0000000..04e7df5
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p9-linkage.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -O1 -emit-llvm -std=c++11 -o - %s | FileCheck %s
+
+template<typename T>
+struct X0 {
+ void f(T &t) {
+ t = 0;
+ }
+
+ void g(T &t);
+
+ void h(T &t);
+
+ static T static_var;
+};
+
+template<typename T>
+inline void X0<T>::g(T & t) {
+ t = 0;
+}
+
+template<typename T>
+void X0<T>::h(T & t) {
+ t = 0;
+}
+
+template<typename T>
+T X0<T>::static_var = 0;
+
+extern template struct X0<int*>;
+
+int *&test(X0<int*> xi, int *ip) {
+ // CHECK: define available_externally void @_ZN2X0IPiE1fERS0_
+ xi.f(ip);
+ // CHECK: define available_externally void @_ZN2X0IPiE1gERS0_
+ xi.g(ip);
+ // CHECK: declare void @_ZN2X0IPiE1hERS0_
+ xi.h(ip);
+ return X0<int*>::static_var;
+}
+
+template<typename T>
+void f0(T& t) {
+ t = 0;
+}
+
+template<typename T>
+inline void f1(T& t) {
+ t = 0;
+}
+
+extern template void f0<>(int *&);
+extern template void f1<>(int *&);
+
+void test_f0(int *ip, float *fp) {
+ // CHECK: declare void @_Z2f0IPiEvRT_
+ f0(ip);
+ // CHECK: define linkonce_odr void @_Z2f0IPfEvRT_
+ f0(fp);
+}
+
+void test_f1(int *ip, float *fp) {
+ // CHECK: define available_externally void @_Z2f1IPiEvRT_
+ f1(ip);
+ // CHECK: define linkonce_odr void @_Z2f1IPfEvRT_
+ f1(fp);
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.explicit/p9.cpp b/clang/test/CXX/temp/temp.spec/temp.explicit/p9.cpp
new file mode 100644
index 0000000..8649017
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.explicit/p9.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+template<typename T>
+struct X0 {
+ void f(T &t) {
+ t = 1; // expected-error{{incompatible type}}
+ }
+
+ void g(T &t);
+
+ void h(T &t);
+
+ static T static_var;
+};
+
+template<typename T>
+inline void X0<T>::g(T & t) {
+ t = 1; // expected-error{{incompatible type}}
+}
+
+template<typename T>
+void X0<T>::h(T & t) {
+ t = 1;
+}
+
+template<typename T>
+T X0<T>::static_var = 1;
+
+extern template struct X0<int*>;
+
+int *&test(X0<int*> xi, int *ip) {
+ xi.f(ip); // expected-note{{instantiation}}
+ xi.g(ip); // expected-note{{instantiation}}
+ xi.h(ip);
+ return X0<int*>::static_var;
+}
+
+template<typename T>
+void f0(T& t) {
+ t = 1; // expected-error{{incompatible type}}
+}
+
+template<typename T>
+inline void f1(T& t) {
+ t = 1; // expected-error 2{{incompatible type}}
+}
+
+extern template void f0<>(int *&);
+extern template void f1<>(int *&);
+
+void test_f0(int *ip, float *fp) {
+ f0(ip);
+ f0(fp); // expected-note{{instantiation}}
+}
+
+void test_f1(int *ip, float *fp) {
+ f1(ip); // expected-note{{instantiation}}
+ f1(fp); // expected-note{{instantiation}}
+}
diff --git a/clang/test/CXX/temp/temp.spec/temp.inst/p1.cpp b/clang/test/CXX/temp/temp.spec/temp.inst/p1.cpp
new file mode 100644
index 0000000..8684fc4
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.inst/p1.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// The implicit specialization of a class template specialuzation causes the
+// implicit instantiation of the declarations, but not the definitions or
+// default arguments, of:
+
+// FIXME: Many omitted cases
+
+// - scoped member enumerations
+namespace ScopedEnum {
+ template<typename T> struct ScopedEnum1 {
+ enum class E {
+ e = T::error // expected-error {{'double' cannot be used prior to '::'}}
+ };
+ };
+ ScopedEnum1<int> se1; // ok
+
+ template<typename T> struct ScopedEnum2 {
+ enum class E : T { // expected-error {{non-integral type 'void *' is an invalid underlying type}}
+ e = 0
+ };
+ };
+ ScopedEnum2<void*> se2; // expected-note {{here}}
+
+ template<typename T> struct UnscopedEnum3 {
+ enum class E : T {
+ e = 4
+ };
+ int arr[(int)E::e];
+ };
+ UnscopedEnum3<int> ue3; // ok
+
+ ScopedEnum1<double>::E e1; // ok
+ ScopedEnum1<double>::E e2 = decltype(e2)::e; // expected-note {{in instantiation of enumeration 'ScopedEnum::ScopedEnum1<double>::E' requested here}}
+
+ // The behavior for enums defined within function templates is not clearly
+ // specified by the standard. We follow the rules for enums defined within
+ // class templates.
+ template<typename T>
+ int f() {
+ enum class E {
+ e = T::error
+ };
+ return (int)E();
+ }
+ int test1 = f<int>();
+
+ template<typename T>
+ int g() {
+ enum class E {
+ e = T::error // expected-error {{has no members}}
+ };
+ return E::e; // expected-note {{here}}
+ }
+ int test2 = g<int>(); // expected-note {{here}}
+}
+
+// And it cases the implicit instantiations of the definitions of:
+
+// - unscoped member enumerations
+namespace UnscopedEnum {
+ template<typename T> struct UnscopedEnum1 {
+ enum E {
+ e = T::error // expected-error {{'int' cannot be used prior to '::'}}
+ };
+ };
+ UnscopedEnum1<int> ue1; // expected-note {{here}}
+
+ template<typename T> struct UnscopedEnum2 {
+ enum E : T { // expected-error {{non-integral type 'void *' is an invalid underlying type}}
+ e = 0
+ };
+ };
+ UnscopedEnum2<void*> ue2; // expected-note {{here}}
+
+ template<typename T> struct UnscopedEnum3 {
+ enum E : T {
+ e = 4
+ };
+ int arr[E::e];
+ };
+ UnscopedEnum3<int> ue3; // ok
+
+ template<typename T>
+ int f() {
+ enum E {
+ e = T::error // expected-error {{has no members}}
+ };
+ return (int)E();
+ }
+ int test1 = f<int>(); // expected-note {{here}}
+
+ template<typename T>
+ int g() {
+ enum E {
+ e = T::error // expected-error {{has no members}}
+ };
+ return E::e;
+ }
+ int test2 = g<int>(); // expected-note {{here}}
+}
+
+// FIXME:
+//- - member anonymous unions
diff --git a/clang/test/CXX/temp/temp.spec/temp.inst/p11.cpp b/clang/test/CXX/temp/temp.spec/temp.inst/p11.cpp
new file mode 100644
index 0000000..8184071
--- /dev/null
+++ b/clang/test/CXX/temp/temp.spec/temp.inst/p11.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -verify -emit-llvm-only %s
+
+// rdar://problem/7838962
+namespace test0 {
+ template<typename T> unsigned f0() {
+ return T::MaxSize; // expected-error {{'int' cannot be used prior to '::'}}
+ };
+ template<typename T> struct A {
+ void Allocate(unsigned Alignment
+ = f0<T>()) // expected-note {{in instantiation}}
+ {}
+ };
+ void f1(A<int> x) { x.Allocate(); }
+
+}
diff --git a/clang/test/CXX/temp/temp.type/p1-0x.cpp b/clang/test/CXX/temp/temp.type/p1-0x.cpp
new file mode 100644
index 0000000..35d00c2
--- /dev/null
+++ b/clang/test/CXX/temp/temp.type/p1-0x.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+namespace Old {
+ template<template<class> class TT> struct X { };
+ template<class> struct Y { };
+ template<class T> using Z = Y<T>;
+ X<Y> y;
+ X<Z> z;
+
+ using SameType = decltype(y); // expected-note {{here}}
+ using SameType = decltype(z); // expected-error {{different types}}
+}
+
+namespace New {
+ template<class T> struct X { };
+ template<class> struct Y { };
+ template<class T> using Z = Y<T>;
+ X<Y<int>> y;
+ X<Z<int>> z;
+
+ using SameType = decltype(y);
+ using SameType = decltype(z); // ok
+}