summaryrefslogtreecommitdiff
path: root/clang/test/CXX/temp/temp.spec
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/CXX/temp/temp.spec')
-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
40 files changed, 2347 insertions, 0 deletions
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(); }
+
+}