summaryrefslogtreecommitdiff
path: root/clang/test/SemaTemplate
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaTemplate')
-rw-r--r--clang/test/SemaTemplate/ackermann.cpp38
-rw-r--r--clang/test/SemaTemplate/address-spaces.cpp86
-rw-r--r--clang/test/SemaTemplate/alias-church-numerals.cpp34
-rw-r--r--clang/test/SemaTemplate/alias-nested-nontag.cpp6
-rw-r--r--clang/test/SemaTemplate/alias-template-template-param.cpp7
-rw-r--r--clang/test/SemaTemplate/alias-templates.cpp102
-rw-r--r--clang/test/SemaTemplate/ambiguous-ovl-print.cpp9
-rw-r--r--clang/test/SemaTemplate/anonymous-union.cpp40
-rw-r--r--clang/test/SemaTemplate/array-to-pointer-decay.cpp25
-rw-r--r--clang/test/SemaTemplate/atomics.cpp16
-rw-r--r--clang/test/SemaTemplate/attributes.cpp34
-rw-r--r--clang/test/SemaTemplate/canonical-expr-type-0x.cpp25
-rw-r--r--clang/test/SemaTemplate/canonical-expr-type.cpp53
-rw-r--r--clang/test/SemaTemplate/class-template-ctor-initializer.cpp55
-rw-r--r--clang/test/SemaTemplate/class-template-decl.cpp97
-rw-r--r--clang/test/SemaTemplate/class-template-id-2.cpp24
-rw-r--r--clang/test/SemaTemplate/class-template-id.cpp47
-rw-r--r--clang/test/SemaTemplate/class-template-spec.cpp121
-rw-r--r--clang/test/SemaTemplate/constexpr-instantiate.cpp77
-rw-r--r--clang/test/SemaTemplate/constructor-template.cpp128
-rw-r--r--clang/test/SemaTemplate/copy-ctor-assign.cpp52
-rw-r--r--clang/test/SemaTemplate/crash-10438657.cpp15
-rw-r--r--clang/test/SemaTemplate/crash-8204126.cpp6
-rw-r--r--clang/test/SemaTemplate/current-instantiation.cpp237
-rw-r--r--clang/test/SemaTemplate/deduction-crash.cpp89
-rw-r--r--clang/test/SemaTemplate/deduction.cpp164
-rw-r--r--clang/test/SemaTemplate/default-arguments-cxx0x.cpp26
-rw-r--r--clang/test/SemaTemplate/default-arguments.cpp138
-rw-r--r--clang/test/SemaTemplate/default-expr-arguments-2.cpp19
-rw-r--r--clang/test/SemaTemplate/default-expr-arguments.cpp305
-rw-r--r--clang/test/SemaTemplate/delegating-constructors.cpp31
-rw-r--r--clang/test/SemaTemplate/dependent-base-classes.cpp137
-rw-r--r--clang/test/SemaTemplate/dependent-base-member-init.cpp68
-rw-r--r--clang/test/SemaTemplate/dependent-class-member-operator.cpp11
-rw-r--r--clang/test/SemaTemplate/dependent-expr.cpp73
-rw-r--r--clang/test/SemaTemplate/dependent-names-no-std.cpp21
-rw-r--r--clang/test/SemaTemplate/dependent-names.cpp326
-rw-r--r--clang/test/SemaTemplate/dependent-sized_array.cpp17
-rw-r--r--clang/test/SemaTemplate/dependent-template-recover.cpp60
-rw-r--r--clang/test/SemaTemplate/dependent-type-identity.cpp100
-rw-r--r--clang/test/SemaTemplate/destructor-template.cpp59
-rw-r--r--clang/test/SemaTemplate/elaborated-type-specifier.cpp40
-rw-r--r--clang/test/SemaTemplate/enum-argument.cpp36
-rw-r--r--clang/test/SemaTemplate/enum-forward.cpp8
-rw-r--r--clang/test/SemaTemplate/example-dynarray.cpp177
-rw-r--r--clang/test/SemaTemplate/example-typelist.cpp98
-rw-r--r--clang/test/SemaTemplate/explicit-instantiation.cpp107
-rw-r--r--clang/test/SemaTemplate/explicit-specialization-member.cpp21
-rw-r--r--clang/test/SemaTemplate/ext-vector-type.cpp94
-rw-r--r--clang/test/SemaTemplate/extern-templates.cpp64
-rw-r--r--clang/test/SemaTemplate/fibonacci.cpp66
-rw-r--r--clang/test/SemaTemplate/friend-template.cpp245
-rw-r--r--clang/test/SemaTemplate/friend.cpp33
-rw-r--r--clang/test/SemaTemplate/fun-template-def.cpp48
-rw-r--r--clang/test/SemaTemplate/function-template-specialization.cpp48
-rw-r--r--clang/test/SemaTemplate/implicit-instantiation-1.cpp25
-rw-r--r--clang/test/SemaTemplate/inject-templated-friend-post.cpp72
-rw-r--r--clang/test/SemaTemplate/inject-templated-friend.cpp48
-rw-r--r--clang/test/SemaTemplate/injected-class-name.cpp62
-rw-r--r--clang/test/SemaTemplate/instantiate-anonymous-union.cpp89
-rw-r--r--clang/test/SemaTemplate/instantiate-array.cpp28
-rw-r--r--clang/test/SemaTemplate/instantiate-attr.cpp26
-rw-r--r--clang/test/SemaTemplate/instantiate-c99.cpp81
-rw-r--r--clang/test/SemaTemplate/instantiate-call.cpp51
-rw-r--r--clang/test/SemaTemplate/instantiate-case.cpp21
-rw-r--r--clang/test/SemaTemplate/instantiate-cast.cpp117
-rw-r--r--clang/test/SemaTemplate/instantiate-clang.cpp35
-rw-r--r--clang/test/SemaTemplate/instantiate-complete.cpp146
-rw-r--r--clang/test/SemaTemplate/instantiate-decl-dtor.cpp11
-rw-r--r--clang/test/SemaTemplate/instantiate-decl-init.cpp46
-rw-r--r--clang/test/SemaTemplate/instantiate-declref-ice.cpp34
-rw-r--r--clang/test/SemaTemplate/instantiate-declref.cpp117
-rw-r--r--clang/test/SemaTemplate/instantiate-deeply.cpp36
-rw-r--r--clang/test/SemaTemplate/instantiate-default-assignment-operator.cpp17
-rw-r--r--clang/test/SemaTemplate/instantiate-dependent-nested-name.cpp7
-rw-r--r--clang/test/SemaTemplate/instantiate-elab-type-specifier.cpp13
-rw-r--r--clang/test/SemaTemplate/instantiate-enum-2.cpp9
-rw-r--r--clang/test/SemaTemplate/instantiate-enum.cpp27
-rw-r--r--clang/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp133
-rw-r--r--clang/test/SemaTemplate/instantiate-exception-spec.cpp11
-rw-r--r--clang/test/SemaTemplate/instantiate-expr-1.cpp192
-rw-r--r--clang/test/SemaTemplate/instantiate-expr-2.cpp245
-rw-r--r--clang/test/SemaTemplate/instantiate-expr-3.cpp119
-rw-r--r--clang/test/SemaTemplate/instantiate-expr-4.cpp354
-rw-r--r--clang/test/SemaTemplate/instantiate-expr-5.cpp38
-rw-r--r--clang/test/SemaTemplate/instantiate-expr-basic.cpp17
-rw-r--r--clang/test/SemaTemplate/instantiate-field.cpp104
-rw-r--r--clang/test/SemaTemplate/instantiate-friend-class.cpp9
-rw-r--r--clang/test/SemaTemplate/instantiate-function-1.cpp249
-rw-r--r--clang/test/SemaTemplate/instantiate-function-1.mm17
-rw-r--r--clang/test/SemaTemplate/instantiate-function-2.cpp66
-rw-r--r--clang/test/SemaTemplate/instantiate-function-params.cpp90
-rw-r--r--clang/test/SemaTemplate/instantiate-init.cpp109
-rw-r--r--clang/test/SemaTemplate/instantiate-invalid.cpp52
-rw-r--r--clang/test/SemaTemplate/instantiate-local-class.cpp67
-rw-r--r--clang/test/SemaTemplate/instantiate-member-class.cpp142
-rw-r--r--clang/test/SemaTemplate/instantiate-member-expr.cpp68
-rw-r--r--clang/test/SemaTemplate/instantiate-member-initializers.cpp27
-rw-r--r--clang/test/SemaTemplate/instantiate-member-pointers.cpp67
-rw-r--r--clang/test/SemaTemplate/instantiate-member-template.cpp261
-rw-r--r--clang/test/SemaTemplate/instantiate-method.cpp177
-rw-r--r--clang/test/SemaTemplate/instantiate-non-dependent-types.cpp14
-rw-r--r--clang/test/SemaTemplate/instantiate-non-type-template-parameter.cpp55
-rw-r--r--clang/test/SemaTemplate/instantiate-objc-1.mm48
-rw-r--r--clang/test/SemaTemplate/instantiate-overload-candidates.cpp21
-rw-r--r--clang/test/SemaTemplate/instantiate-overloaded-arrow.cpp20
-rw-r--r--clang/test/SemaTemplate/instantiate-self.cpp89
-rw-r--r--clang/test/SemaTemplate/instantiate-sizeof.cpp10
-rw-r--r--clang/test/SemaTemplate/instantiate-static-var.cpp116
-rw-r--r--clang/test/SemaTemplate/instantiate-subscript.cpp41
-rw-r--r--clang/test/SemaTemplate/instantiate-template-template-parm.cpp97
-rw-r--r--clang/test/SemaTemplate/instantiate-try-catch.cpp31
-rw-r--r--clang/test/SemaTemplate/instantiate-type.cpp17
-rw-r--r--clang/test/SemaTemplate/instantiate-typedef.cpp15
-rw-r--r--clang/test/SemaTemplate/instantiate-typeof.cpp10
-rw-r--r--clang/test/SemaTemplate/instantiate-using-decl.cpp82
-rw-r--r--clang/test/SemaTemplate/instantiation-backtrace.cpp32
-rw-r--r--clang/test/SemaTemplate/instantiation-default-1.cpp102
-rw-r--r--clang/test/SemaTemplate/instantiation-default-2.cpp18
-rw-r--r--clang/test/SemaTemplate/instantiation-default-3.cpp21
-rw-r--r--clang/test/SemaTemplate/instantiation-depth.cpp13
-rw-r--r--clang/test/SemaTemplate/instantiation-order.cpp15
-rw-r--r--clang/test/SemaTemplate/issue150.cpp107
-rw-r--r--clang/test/SemaTemplate/lookup-dependent-bases.cpp19
-rw-r--r--clang/test/SemaTemplate/member-access-ambig.cpp45
-rw-r--r--clang/test/SemaTemplate/member-access-expr.cpp149
-rw-r--r--clang/test/SemaTemplate/member-function-template.cpp103
-rw-r--r--clang/test/SemaTemplate/member-inclass-init-value-dependent.cpp18
-rw-r--r--clang/test/SemaTemplate/member-initializers.cpp13
-rw-r--r--clang/test/SemaTemplate/member-template-access-expr.cpp144
-rw-r--r--clang/test/SemaTemplate/metafun-apply.cpp40
-rw-r--r--clang/test/SemaTemplate/missing-class-keyword-crash.cpp7
-rw-r--r--clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp71
-rw-r--r--clang/test/SemaTemplate/ms-if-exists.cpp68
-rw-r--r--clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp145
-rw-r--r--clang/test/SemaTemplate/nested-incomplete-class.cpp21
-rw-r--r--clang/test/SemaTemplate/nested-linkage.cpp3
-rw-r--r--clang/test/SemaTemplate/nested-name-spec-template.cpp142
-rw-r--r--clang/test/SemaTemplate/nested-template.cpp157
-rw-r--r--clang/test/SemaTemplate/operator-function-id-template.cpp28
-rw-r--r--clang/test/SemaTemplate/operator-template.cpp18
-rw-r--r--clang/test/SemaTemplate/overload-candidates.cpp40
-rw-r--r--clang/test/SemaTemplate/overload-uneval.cpp42
-rw-r--r--clang/test/SemaTemplate/partial-spec-instantiate.cpp50
-rw-r--r--clang/test/SemaTemplate/pragma-ms_struct.cpp10
-rw-r--r--clang/test/SemaTemplate/qualified-id.cpp56
-rw-r--r--clang/test/SemaTemplate/qualified-names-diag.cpp16
-rw-r--r--clang/test/SemaTemplate/rdar9173693.cpp6
-rw-r--r--clang/test/SemaTemplate/recovery-crash.cpp19
-rw-r--r--clang/test/SemaTemplate/recursive-template-instantiation.cpp10
-rw-r--r--clang/test/SemaTemplate/resolve-single-template-id.cpp82
-rw-r--r--clang/test/SemaTemplate/self-comparison.cpp48
-rw-r--r--clang/test/SemaTemplate/temp.cpp19
-rw-r--r--clang/test/SemaTemplate/temp_arg.cpp20
-rw-r--r--clang/test/SemaTemplate/temp_arg_nontype.cpp325
-rw-r--r--clang/test/SemaTemplate/temp_arg_template.cpp62
-rw-r--r--clang/test/SemaTemplate/temp_arg_type.cpp42
-rw-r--r--clang/test/SemaTemplate/temp_class_order.cpp42
-rw-r--r--clang/test/SemaTemplate/temp_class_spec.cpp363
-rw-r--r--clang/test/SemaTemplate/temp_class_spec_blocks.cpp34
-rw-r--r--clang/test/SemaTemplate/temp_class_spec_neg.cpp45
-rw-r--r--clang/test/SemaTemplate/temp_explicit.cpp151
-rw-r--r--clang/test/SemaTemplate/temp_explicit_cxx0x.cpp24
-rw-r--r--clang/test/SemaTemplate/temp_func_order.cpp95
-rw-r--r--clang/test/SemaTemplate/template-class-traits.cpp8
-rw-r--r--clang/test/SemaTemplate/template-decl-fail.cpp10
-rw-r--r--clang/test/SemaTemplate/template-id-expr.cpp98
-rw-r--r--clang/test/SemaTemplate/template-id-printing.cpp141
-rw-r--r--clang/test/SemaTemplate/typename-specifier-2.cpp30
-rw-r--r--clang/test/SemaTemplate/typename-specifier-3.cpp19
-rw-r--r--clang/test/SemaTemplate/typename-specifier-4.cpp164
-rw-r--r--clang/test/SemaTemplate/typename-specifier.cpp117
-rw-r--r--clang/test/SemaTemplate/typo-dependent-name.cpp17
-rw-r--r--clang/test/SemaTemplate/unresolved-construct.cpp19
-rw-r--r--clang/test/SemaTemplate/unused-variables.cpp21
-rw-r--r--clang/test/SemaTemplate/value-dependent-null-pointer-constant.cpp29
-rw-r--r--clang/test/SemaTemplate/virtual-member-functions.cpp86
177 files changed, 12320 insertions, 0 deletions
diff --git a/clang/test/SemaTemplate/ackermann.cpp b/clang/test/SemaTemplate/ackermann.cpp
new file mode 100644
index 0000000..9525bfc
--- /dev/null
+++ b/clang/test/SemaTemplate/ackermann.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// template<unsigned M, unsigned N>
+// struct Ackermann {
+// enum {
+// value = M ? (N ? Ackermann<M-1, Ackermann<M, N-1> >::value
+// : Ackermann<M-1, 1>::value)
+// : N + 1
+// };
+// };
+
+template<unsigned M, unsigned N>
+struct Ackermann {
+ enum {
+ value = Ackermann<M-1, Ackermann<M, N-1>::value >::value
+ };
+};
+
+template<unsigned M> struct Ackermann<M, 0> {
+ enum {
+ value = Ackermann<M-1, 1>::value
+ };
+};
+
+template<unsigned N> struct Ackermann<0, N> {
+ enum {
+ value = N + 1
+ };
+};
+
+template<> struct Ackermann<0, 0> {
+ enum {
+ value = 1
+ };
+};
+
+int g0[Ackermann<3, 4>::value == 125 ? 1 : -1];
+
diff --git a/clang/test/SemaTemplate/address-spaces.cpp b/clang/test/SemaTemplate/address-spaces.cpp
new file mode 100644
index 0000000..eda03db
--- /dev/null
+++ b/clang/test/SemaTemplate/address-spaces.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+typedef int __attribute__((address_space(1))) int_1;;
+typedef int __attribute__((address_space(2))) int_2;;
+typedef int __attribute__((address_space(1))) *int_1_ptr;
+typedef int_2 *int_2_ptr;
+
+// Check that we maintain address spaces through template argument
+// deduction from a type.
+template<typename T>
+struct remove_pointer {
+ typedef T type;
+};
+
+template<typename T>
+struct remove_pointer<T *> {
+ typedef T type;
+};
+
+int check_remove0[is_same<remove_pointer<int_1_ptr>::type, int_1>::value? 1 : -1];
+int check_remove1[is_same<remove_pointer<int_2_ptr>::type, int_2>::value? 1 : -1];
+int check_remove2[is_same<remove_pointer<int_2_ptr>::type, int>::value? -1 : 1];
+int check_remove3[is_same<remove_pointer<int_2_ptr>::type, int_1>::value? -1 : 1];
+
+template<typename T>
+struct is_pointer_in_address_space_1 {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_pointer_in_address_space_1<T __attribute__((address_space(1))) *> {
+ static const bool value = true;
+};
+
+int check_ptr_in_as1[is_pointer_in_address_space_1<int_1_ptr>::value? 1 : -1];
+int check_ptr_in_as2[is_pointer_in_address_space_1<int_2_ptr>::value? -1 : 1];
+int check_ptr_in_as3[is_pointer_in_address_space_1<int*>::value? -1 : 1];
+
+// Check that we maintain address spaces through template argument
+// deduction for a call.
+template<typename T>
+void accept_any_pointer(T*) {
+ T *x = 1; // expected-error{{cannot initialize a variable of type '__attribute__((address_space(1))) int *' with an rvalue of type 'int'}} \
+ // expected-error{{cannot initialize a variable of type '__attribute__((address_space(3))) int *' with an rvalue of type 'int'}}
+}
+
+void test_accept_any_pointer(int_1_ptr ip1, int_2_ptr ip2) {
+ static __attribute__((address_space(3))) int array[17];
+ accept_any_pointer(ip1); // expected-note{{in instantiation of}}
+ accept_any_pointer(array); // expected-note{{in instantiation of}}
+}
+
+template<typename T> struct identity {};
+
+template<typename T>
+identity<T> accept_arg_in_address_space_1(__attribute__((address_space(1))) T &ir1);
+
+template<typename T>
+identity<T> accept_any_arg(T &ir1);
+
+void test_arg_in_address_space_1() {
+ static int __attribute__((address_space(1))) int_1;
+ identity<int> ii = accept_arg_in_address_space_1(int_1);
+ identity<int __attribute__((address_space(1)))> ii2 = accept_any_arg(int_1);
+}
+
+// Partial ordering
+template<typename T> int &order1(__attribute__((address_space(1))) T&);
+template<typename T> float &order1(T&);
+
+void test_order1() {
+ static __attribute__((address_space(1))) int i1;
+ int i;
+ int &ir = order1(i1);
+ float &fr = order1(i);
+}
diff --git a/clang/test/SemaTemplate/alias-church-numerals.cpp b/clang/test/SemaTemplate/alias-church-numerals.cpp
new file mode 100644
index 0000000..69d7716
--- /dev/null
+++ b/clang/test/SemaTemplate/alias-church-numerals.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+template<template<template<typename> class, typename> class T, template<typename> class V> struct PartialApply {
+ template<typename W> using R = T<V, W>;
+};
+
+template<typename T> using Id = T;
+template<template<typename> class, typename X> using Zero = X;
+template<template<template<typename> class, typename> class N, template<typename> class F, typename X> using Succ = F<N<F,X>>;
+
+template<template<typename> class F, typename X> using One = Succ<Zero, F, X>;
+template<template<typename> class F, typename X> using Two = Succ<One, F, X>;
+
+template<template<template<typename> class, typename> class A,
+ template<template<typename> class, typename> class B,
+ template<typename> class F,
+ typename X> using Add = A<F, B<F, X>>;
+
+template<template<template<typename> class, typename> class A,
+ template<template<typename> class, typename> class B,
+ template<typename> class F,
+ typename X> using Mul = A<PartialApply<B,F>::template R, X>;
+
+template<template<typename> class F, typename X> using Four = Add<Two, Two, F, X>;
+template<template<typename> class F, typename X> using Sixteen = Mul<Four, Four, F, X>;
+template<template<typename> class F, typename X> using TwoHundredAndFiftySix = Mul<Sixteen, Sixteen, F, X>;
+
+template<typename T, T N> struct Const { static const T value = N; };
+template<typename A> struct IncrementHelper;
+template<typename T, T N> struct IncrementHelper<Const<T, N>> { using Result = Const<T, N+1>; };
+template<typename A> using Increment = typename IncrementHelper<A>::Result;
+
+using Arr = int[TwoHundredAndFiftySix<Increment, Const<int, 0>>::value];
+using Arr = int[256];
diff --git a/clang/test/SemaTemplate/alias-nested-nontag.cpp b/clang/test/SemaTemplate/alias-nested-nontag.cpp
new file mode 100644
index 0000000..4b5226b
--- /dev/null
+++ b/clang/test/SemaTemplate/alias-nested-nontag.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+template<typename T> using Id = T; // expected-note {{type alias template 'Id' declared here}}
+struct U { static Id<int> V; };
+Id<int> ::U::V; // expected-error {{type 'Id<int>' (aka 'int') cannot be used prior to '::' because it has no members}} \
+ expected-error {{C++ requires a type specifier}}
diff --git a/clang/test/SemaTemplate/alias-template-template-param.cpp b/clang/test/SemaTemplate/alias-template-template-param.cpp
new file mode 100644
index 0000000..c22fccb
--- /dev/null
+++ b/clang/test/SemaTemplate/alias-template-template-param.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+template<template<typename> class D> using C = D<int>;
+
+// Substitution of the alias template transforms the TemplateSpecializationType
+// 'D<int>' into the DependentTemplateSpecializationType 'T::template U<int>'.
+template<typename T> void f(C<T::template U>);
diff --git a/clang/test/SemaTemplate/alias-templates.cpp b/clang/test/SemaTemplate/alias-templates.cpp
new file mode 100644
index 0000000..75615ee
--- /dev/null
+++ b/clang/test/SemaTemplate/alias-templates.cpp
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+template<typename S>
+struct A {
+ typedef S B;
+ template<typename T> using C = typename T::B;
+ template<typename T> struct D {
+ template<typename U> using E = typename A<U>::template C<A<T>>;
+ template<typename U> using F = A<E<U>>;
+ template<typename U> using G = C<F<U>>;
+ G<T> g;
+ };
+ typedef decltype(D<B>().g) H;
+ D<H> h;
+ template<typename T> using I = A<decltype(h.g)>;
+ template<typename T> using J = typename A<decltype(h.g)>::template C<I<T>>;
+};
+
+A<int> a;
+A<char>::D<double> b;
+
+template<typename T> T make();
+
+namespace X {
+ template<typename T> struct traits {
+ typedef T thing;
+ typedef decltype(val(make<thing>())) inner_ptr;
+
+ template<typename U> using rebind_thing = typename thing::template rebind<U>;
+ template<typename U> using rebind = traits<rebind_thing<U>>;
+
+ inner_ptr &&alloc();
+ void free(inner_ptr&&);
+ };
+
+ template<typename T> struct ptr_traits {
+ typedef T *type;
+ };
+ template<typename T> using ptr = typename ptr_traits<T>::type;
+
+ template<typename T> struct thing {
+ typedef T inner;
+ typedef ptr<inner> inner_ptr;
+ typedef traits<thing<inner>> traits_type;
+
+ template<typename U> using rebind = thing<U>;
+
+ thing(traits_type &traits) : traits(traits), val(traits.alloc()) {}
+ ~thing() { traits.free(static_cast<inner_ptr&&>(val)); }
+
+ traits_type &traits;
+ inner_ptr val;
+
+ friend inner_ptr val(const thing &t) { return t.val; }
+ };
+
+ template<> struct ptr_traits<bool> {
+ typedef bool &type;
+ };
+ template<> bool &traits<thing<bool>>::alloc() { static bool b; return b; }
+ template<> void traits<thing<bool>>::free(bool&) {}
+}
+
+typedef X::traits<X::thing<int>> itt;
+
+itt::thing::traits_type itr;
+itt::thing ith(itr);
+
+itt::rebind<bool> btr;
+itt::rebind_thing<bool> btt(btr);
+
+namespace PR11848 {
+ template<typename T> using U = int;
+
+ template<typename T, typename ...Ts>
+ void f(U<T> i, U<Ts> ...is) { // expected-error {{type 'U<Ts>' (aka 'int') of function parameter pack does not contain any unexpanded parameter packs}}
+ return i + f<Ts...>(is...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}}
+ }
+
+ template<typename ...Ts>
+ struct S {
+ S(U<Ts>...ts); // expected-error {{does not contain any unexpanded parameter packs}}
+ };
+
+ template<typename T>
+ struct Hidden1 {
+ template<typename ...Ts>
+ Hidden1(typename T::template U<Ts> ...ts); // expected-error{{type 'typename Hide::U<Ts>' (aka 'int') of function parameter pack does not contain any unexpanded parameter packs}}
+ };
+
+ template<typename T, typename ...Ts>
+ struct Hidden2 {
+ Hidden2(typename T::template U<Ts> ...ts);
+ };
+
+ struct Hide {
+ template<typename T> using U = int;
+ };
+
+ Hidden1<Hide> h1; // expected-note{{in instantiation of template class 'PR11848::Hidden1<PR11848::Hide>' requested here}}
+ Hidden2<Hide, double, char> h2(1, 2);
+}
diff --git a/clang/test/SemaTemplate/ambiguous-ovl-print.cpp b/clang/test/SemaTemplate/ambiguous-ovl-print.cpp
new file mode 100644
index 0000000..7e3fa24
--- /dev/null
+++ b/clang/test/SemaTemplate/ambiguous-ovl-print.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f(void*, int); // expected-note{{candidate function}}
+template<typename T>
+ void f(T*, long); // expected-note{{candidate function}}
+
+void test_f(int *ip, int i) {
+ f(ip, i); // expected-error{{ambiguous}}
+}
diff --git a/clang/test/SemaTemplate/anonymous-union.cpp b/clang/test/SemaTemplate/anonymous-union.cpp
new file mode 100644
index 0000000..97ecd6e
--- /dev/null
+++ b/clang/test/SemaTemplate/anonymous-union.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5868
+struct T0 {
+ int x;
+ union {
+ void *m0;
+ };
+};
+template <typename T>
+struct T1 : public T0, public T {
+ void f0() {
+ m0 = 0; // expected-error{{ambiguous conversion}}
+ }
+};
+
+struct A : public T0 { };
+
+void f1(T1<A> *S) { S->f0(); } // expected-note{{instantiation of member function}}
+
+namespace rdar8635664 {
+ template<typename T>
+ struct X {
+ struct inner;
+
+ struct inner {
+ union {
+ int x;
+ float y;
+ };
+
+ typedef T type;
+ };
+ };
+
+ void test() {
+ X<int>::inner i;
+ i.x = 0;
+ }
+}
diff --git a/clang/test/SemaTemplate/array-to-pointer-decay.cpp b/clang/test/SemaTemplate/array-to-pointer-decay.cpp
new file mode 100644
index 0000000..072c0e5
--- /dev/null
+++ b/clang/test/SemaTemplate/array-to-pointer-decay.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct mystruct {
+ int member;
+};
+
+template <int i>
+int foo() {
+ mystruct s[1];
+ return s->member;
+}
+
+int main() {
+ foo<1>();
+}
+
+// PR7405
+struct hb_sanitize_context_t {
+ int start;
+};
+template <typename Type> static bool sanitize() {
+ hb_sanitize_context_t c[1];
+ return !c->start;
+}
+bool closure = sanitize<int>();
diff --git a/clang/test/SemaTemplate/atomics.cpp b/clang/test/SemaTemplate/atomics.cpp
new file mode 100644
index 0000000..e9fdc9d
--- /dev/null
+++ b/clang/test/SemaTemplate/atomics.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR8345
+template<typename T> T f(T* value) {
+ return __sync_add_and_fetch(value, 1);
+}
+int g(long long* x) { return f(x); }
+int g(int* x) { return f(x); }
+
+namespace PR11320 {
+ template<typename T>
+ void g(unsigned *x) {
+ __sync_bool_compare_and_swap(x, 1, 4);
+ }
+ void h() { g<int>(0); }
+}
diff --git a/clang/test/SemaTemplate/attributes.cpp b/clang/test/SemaTemplate/attributes.cpp
new file mode 100644
index 0000000..495f4a7
--- /dev/null
+++ b/clang/test/SemaTemplate/attributes.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace attribute_aligned {
+ template<int N>
+ struct X {
+ char c[1] __attribute__((__aligned__((N)))); // expected-error {{alignment is not a power of 2}}
+ };
+
+ template <bool X> struct check {
+ int check_failed[X ? 1 : -1]; // expected-error {{array with a negative size}}
+ };
+
+ template <int N> struct check_alignment {
+ typedef check<N == sizeof(X<N>)> t; // expected-note {{in instantiation}}
+ };
+
+ check_alignment<1>::t c1;
+ check_alignment<2>::t c2;
+ check_alignment<3>::t c3; // expected-note 2 {{in instantiation}}
+ check_alignment<4>::t c4;
+}
+
+namespace PR9049 {
+ extern const void *CFRetain(const void *ref);
+
+ template<typename T> __attribute__((cf_returns_retained))
+ inline T WBCFRetain(T aValue) { return aValue ? (T)CFRetain(aValue) : (T)0; }
+
+
+ extern void CFRelease(const void *ref);
+
+ template<typename T>
+ inline void WBCFRelease(__attribute__((cf_consumed)) T aValue) { if(aValue) CFRelease(aValue); }
+}
diff --git a/clang/test/SemaTemplate/canonical-expr-type-0x.cpp b/clang/test/SemaTemplate/canonical-expr-type-0x.cpp
new file mode 100644
index 0000000..d7379ea
--- /dev/null
+++ b/clang/test/SemaTemplate/canonical-expr-type-0x.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+void f();
+
+// Test typeof(expr) canonicalization
+template<typename T, T N>
+void f0(T x, decltype(f(N, x)) y) { } // expected-note{{previous}}
+
+template<typename T, T N>
+void f0(T x, decltype((f)(N, x)) y) { }
+
+template<typename U, U M>
+void f0(U u, decltype(f(M, u))) { } // expected-error{{redefinition}}
+
+// PR12438: Test sizeof...() canonicalization
+template<int> struct N {};
+
+template<typename...T>
+N<sizeof...(T)> f1() {} // expected-note{{previous}}
+
+template<typename, typename...T>
+N<sizeof...(T)> f1() {}
+
+template<class...U>
+N<sizeof...(U)> f1() {} // expected-error{{redefinition}}
diff --git a/clang/test/SemaTemplate/canonical-expr-type.cpp b/clang/test/SemaTemplate/canonical-expr-type.cpp
new file mode 100644
index 0000000..7582df5
--- /dev/null
+++ b/clang/test/SemaTemplate/canonical-expr-type.cpp
@@ -0,0 +1,53 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+void f();
+
+// Test typeof(expr) canonicalization
+template<typename T>
+void f0(T x, __typeof__(f(x)) y) { } // expected-note{{previous}}
+
+template<typename T>
+void f0(T x, __typeof__((f)(x)) y) { }
+
+template<typename U>
+void f0(U u, __typeof__(f(u))) { } // expected-error{{redefinition}}
+
+// Test insane typeof(expr) overload set canonicalization
+void f(int);
+void f(double);
+
+template<typename T, T N>
+void f0a(T x, __typeof__(f(N)) y) { } // expected-note{{previous}}
+
+void f(int);
+
+template<typename T, T N>
+void f0a(T x, __typeof__(f(N)) y) { } // expected-error{{redefinition}} \
+ // expected-note{{previous}}
+
+void f(float);
+
+template<typename T, T N>
+void f0a(T x, __typeof__(f(N)) y) { } // expected-error{{redefinition}}
+
+// Test dependently-sized array canonicalization
+template<typename T, int N, int M>
+void f1(T (&array)[N + M]) { } // expected-note{{previous}}
+
+template<typename T, int N, int M>
+void f1(T (&array)[M + N]) { }
+
+template<typename T, int M, int N>
+void f1(T (&array)[M + N]) { } // expected-error{{redefinition}}
+
+// Test dependently-sized extended vector type canonicalization
+template<typename T, int N, int M>
+struct X2 {
+ typedef T __attribute__((ext_vector_type(N))) type1;
+ typedef T __attribute__((ext_vector_type(M))) type2;
+ typedef T __attribute__((ext_vector_type(N))) type3;
+
+ void f0(type1); // expected-note{{previous}}
+ void f0(type2);
+ void f0(type3); // expected-error{{redeclared}}
+};
diff --git a/clang/test/SemaTemplate/class-template-ctor-initializer.cpp b/clang/test/SemaTemplate/class-template-ctor-initializer.cpp
new file mode 100644
index 0000000..44bb4bd
--- /dev/null
+++ b/clang/test/SemaTemplate/class-template-ctor-initializer.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class X> struct A {};
+
+template<class X> struct B : A<X> {
+ B() : A<X>() {}
+};
+B<int> x;
+
+template<class X> struct B1 : A<X> {
+ typedef A<X> Base;
+ B1() : Base() {}
+};
+B1<int> x1;
+
+
+template<typename T> struct Tmpl { };
+
+template<typename T> struct TmplB { };
+
+struct TmplC : Tmpl<int> {
+ TmplC() :
+ Tmpl<int>(),
+ TmplB<int>() { } // expected-error {{type 'TmplB<int>' is not a direct or virtual base of 'TmplC'}}
+};
+
+
+struct TmplD : Tmpl<char>, TmplB<char> {
+ TmplD():
+ Tmpl<int>(), // expected-error {{type 'Tmpl<int>' is not a direct or virtual base of 'TmplD'}}
+ TmplB<char>() {}
+};
+
+namespace PR7259 {
+ class Base {
+ public:
+ Base() {}
+ };
+
+ template <class ParentClass>
+ class Derived : public ParentClass {
+ public:
+ Derived() : Base() {}
+ };
+
+ class Final : public Derived<Base> {
+ };
+
+ int
+ main (void)
+ {
+ Final final;
+ return 0;
+ }
+}
diff --git a/clang/test/SemaTemplate/class-template-decl.cpp b/clang/test/SemaTemplate/class-template-decl.cpp
new file mode 100644
index 0000000..ec4e016
--- /dev/null
+++ b/clang/test/SemaTemplate/class-template-decl.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> class A;
+
+extern "C++" {
+ template<typename T> class B;
+}
+
+namespace N {
+ template<typename T> class C;
+}
+
+extern "C" {
+ template<typename T> class D; // expected-error{{templates must have C++ linkage}}
+}
+
+template<class U> class A; // expected-note{{previous template declaration is here}}
+
+template<int N> class A; // expected-error{{template parameter has a different kind in template redeclaration}}
+
+template<int N> class NonTypeTemplateParm;
+
+typedef int INT;
+
+template<INT M> class NonTypeTemplateParm; // expected-note{{previous non-type template parameter with type 'INT' (aka 'int') is here}}
+
+template<long> class NonTypeTemplateParm; // expected-error{{template non-type parameter has a different type 'long' in template redeclaration}}
+
+template<template<typename T> class X> class TemplateTemplateParm;
+
+template<template<class> class Y> class TemplateTemplateParm; // expected-note{{previous template declaration is here}} \
+ // expected-note{{previous template template parameter is here}}
+
+template<typename> class TemplateTemplateParm; // expected-error{{template parameter has a different kind in template redeclaration}}
+
+template<template<typename T, int> class X> class TemplateTemplateParm; // expected-error{{too many template parameters in template template parameter redeclaration}}
+
+template<typename T>
+struct test {}; // expected-note{{previous definition}}
+
+template<typename T>
+struct test : T {}; // expected-error{{redefinition}}
+
+class X {
+public:
+ template<typename T> class C;
+};
+
+void f() {
+ template<typename T> class X; // expected-error{{expression}}
+}
+
+template<typename T> class X1 var; // expected-error{{declared as a template}}
+
+namespace M {
+}
+
+template<typename T> class M::C3 { }; // expected-error{{out-of-line definition of 'C3' does not match any declaration in namespace 'M'}}
+
+namespace PR8001 {
+ template<typename T1>
+ struct Foo {
+ template<typename T2> class Bar;
+ typedef Bar<T1> Baz;
+
+ template<typename T2>
+ struct Bar {
+ Bar() {}
+ };
+ };
+
+ void pr8001() {
+ Foo<int>::Baz x;
+ Foo<int>::Bar<int> y(x);
+ }
+}
+
+namespace rdar9676205 {
+ template <unsigned, class _Tp> class tuple_element;
+
+ template <class _T1, class _T2> class pair;
+
+ template <class _T1, class _T2>
+ class tuple_element<0, pair<_T1, _T2> >
+ {
+ template <class _Tp>
+ struct X
+ {
+ template <class _Up, bool = X<_Up>::value>
+ struct Y
+ : public X<_Up>,
+ public Y<_Up>
+ { };
+ };
+ };
+}
+
diff --git a/clang/test/SemaTemplate/class-template-id-2.cpp b/clang/test/SemaTemplate/class-template-id-2.cpp
new file mode 100644
index 0000000..d09f524
--- /dev/null
+++ b/clang/test/SemaTemplate/class-template-id-2.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace N {
+ template<typename T> class A { };
+
+ template<> class A<int> { };
+
+ template<> class A<float>; // expected-note{{forward declaration of 'N::A<float>'}}
+
+ class B : public A<int> { };
+}
+
+class C1 : public N::A<int> { };
+
+class C2 : public N::A<float> { }; // expected-error{{base class has incomplete type}}
+
+struct D1 {
+ operator N::A<int>();
+};
+
+namespace N {
+ struct D2 {
+ operator A<int>();
+ };
+}
diff --git a/clang/test/SemaTemplate/class-template-id.cpp b/clang/test/SemaTemplate/class-template-id.cpp
new file mode 100644
index 0000000..3b02778
--- /dev/null
+++ b/clang/test/SemaTemplate/class-template-id.cpp
@@ -0,0 +1,47 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U = float> struct A { };
+
+typedef A<int> A_int;
+
+typedef float FLOAT;
+
+A<int, FLOAT> *foo(A<int> *ptr, A<int> const *ptr2, A<int, double> *ptr3) {
+ if (ptr)
+ return ptr; // okay
+ else if (ptr2)
+ return ptr2; // expected-error{{cannot initialize return object of type 'A<int, FLOAT> *' with an lvalue of type 'const A<int> *'}}
+ else {
+ return ptr3; // expected-error{{cannot initialize return object of type 'A<int, FLOAT> *' with an lvalue of type 'A<int, double> *'}}
+ }
+}
+
+template<int I> struct B;
+
+const int value = 12;
+B<17 + 2> *bar(B<(19)> *ptr1, B< (::value + 7) > *ptr2, B<19 - 3> *ptr3) {
+ if (ptr1)
+ return ptr1;
+ else if (ptr2)
+ return ptr2;
+ else
+ return ptr3; // expected-error{{cannot initialize return object of type 'B<17 + 2> *' with an lvalue of type 'B<19 - 3>}}
+}
+
+typedef B<5> B5;
+
+
+namespace N {
+ template<typename T> struct C {};
+}
+
+N::C<int> c1;
+typedef N::C<float> c2;
+
+// PR5655
+template<typename T> struct Foo { }; // expected-note{{template is declared here}}
+
+void f(void) { Foo bar; } // expected-error{{without a template argument list}}
+
+// rdar://problem/8254267
+template <typename T> class Party;
+template <> class Party<T> { friend struct Party<>; }; // expected-error {{use of undeclared identifier 'T'}}
diff --git a/clang/test/SemaTemplate/class-template-spec.cpp b/clang/test/SemaTemplate/class-template-spec.cpp
new file mode 100644
index 0000000..f9015b3
--- /dev/null
+++ b/clang/test/SemaTemplate/class-template-spec.cpp
@@ -0,0 +1,121 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U = int> struct A; // expected-note {{template is declared here}} \
+ // expected-note{{explicitly specialized}}
+
+template<> struct A<double, double>; // expected-note{{forward declaration}}
+
+template<> struct A<float, float> { // expected-note{{previous definition}}
+ int x;
+};
+
+template<> struct A<float> { // expected-note{{previous definition}}
+ int y;
+};
+
+int test_specs(A<float, float> *a1, A<float, int> *a2) {
+ return a1->x + a2->y;
+}
+
+int test_incomplete_specs(A<double, double> *a1,
+ A<double> *a2)
+{
+ (void)a1->x; // expected-error{{member access into incomplete type}}
+ (void)a2->x; // expected-error{{implicit instantiation of undefined template 'A<double, int>'}}
+}
+
+typedef float FLOAT;
+
+template<> struct A<float, FLOAT>;
+
+template<> struct A<FLOAT, float> { }; // expected-error{{redefinition}}
+
+template<> struct A<float, int> { }; // expected-error{{redefinition}}
+
+template<typename T, typename U = int> struct X;
+
+template <> struct X<int, int> { int foo(); }; // #1
+template <> struct X<float> { int bar(); }; // #2
+
+typedef int int_type;
+void testme(X<int_type> *x1, X<float, int> *x2) {
+ (void)x1->foo(); // okay: refers to #1
+ (void)x2->bar(); // okay: refers to #2
+}
+
+// Make sure specializations are proper classes.
+template<>
+struct A<char> {
+ A();
+};
+
+A<char>::A() { }
+
+// Make sure we can see specializations defined before the primary template.
+namespace N{
+ template<typename T> struct A0;
+}
+
+namespace N {
+ template<>
+ struct A0<void> {
+ typedef void* pointer;
+ };
+}
+
+namespace N {
+ template<typename T>
+ struct A0 {
+ void foo(A0<void>::pointer p = 0);
+ };
+}
+
+// Diagnose specialization errors
+struct A<double> { }; // expected-error{{template specialization requires 'template<>'}}
+
+template<> struct ::A<double>;
+
+namespace N {
+ template<typename T> struct B; // expected-note 2{{explicitly specialized}}
+
+ template<> struct ::N::B<char>; // okay
+ template<> struct ::N::B<short>; // okay
+ template<> struct ::N::B<int>; // okay
+
+ int f(int);
+}
+
+template<> struct N::B<int> { }; // okay
+
+template<> struct N::B<float> { }; // expected-warning{{C++11 extension}}
+
+namespace M {
+ template<> struct ::N::B<short> { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}}
+
+ template<> struct ::A<long double>; // expected-error{{originally}}
+}
+
+template<> struct N::B<char> {
+ int testf(int x) { return f(x); }
+};
+
+// PR5264
+template <typename T> class Foo;
+Foo<int>* v;
+Foo<int>& F() { return *v; }
+template <typename T> class Foo {};
+Foo<int> x;
+
+
+// Template template parameters
+template<template<class T> class Wibble>
+class Wibble<int> { }; // expected-error{{cannot specialize a template template parameter}}
+
+namespace rdar9676205 {
+ template<typename T>
+ struct X {
+ template<typename U>
+ struct X<U*> { // expected-error{{explicit specialization of 'X' in class scope}}
+ };
+ };
+
+}
diff --git a/clang/test/SemaTemplate/constexpr-instantiate.cpp b/clang/test/SemaTemplate/constexpr-instantiate.cpp
new file mode 100644
index 0000000..2f9fe0e
--- /dev/null
+++ b/clang/test/SemaTemplate/constexpr-instantiate.cpp
@@ -0,0 +1,77 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+namespace UseBeforeDefinition {
+ struct A {
+ template<typename T> static constexpr T get() { return T(); }
+ // ok, not a constant expression.
+ int n = get<int>();
+ };
+
+ // ok, constant expression.
+ constexpr int j = A::get<int>();
+
+ template<typename T> constexpr int consume(T);
+ // ok, not a constant expression.
+ const int k = consume(0); // expected-note {{here}}
+
+ template<typename T> constexpr int consume(T) { return 0; }
+ // ok, constant expression.
+ constexpr int l = consume(0);
+
+ constexpr int m = k; // expected-error {{constant expression}} expected-note {{initializer of 'k'}}
+}
+
+namespace IntegralConst {
+ template<typename T> constexpr T f(T n) { return n; }
+ enum E {
+ v = f(0), w = f(1) // ok
+ };
+ static_assert(w == 1, "");
+
+ char arr[f('x')]; // ok
+ static_assert(sizeof(arr) == 'x', "");
+}
+
+namespace ConvertedConst {
+ template<typename T> constexpr T f(T n) { return n; }
+ int f() {
+ switch (f()) {
+ case f(4): return 0;
+ }
+ return 1;
+ }
+}
+
+namespace OverloadResolution {
+ template<typename T> constexpr T f(T t) { return t; }
+
+ template<int n> struct S { };
+
+ template<typename T> auto g(T t) -> S<f(sizeof(T))> &;
+ char &f(...);
+
+ template<typename T> auto h(T t[f(sizeof(T))]) -> decltype(&*t) {
+ return t;
+ }
+
+ S<4> &k = g(0);
+ int *p, *q = h(p);
+}
+
+namespace DataMember {
+ template<typename T> struct S { static const int k; };
+ const int n = S<int>::k; // expected-note {{here}}
+ template<typename T> const int S<T>::k = 0;
+ constexpr int m = S<int>::k; // ok
+ constexpr int o = n; // expected-error {{constant expression}} expected-note {{initializer of 'n'}}
+}
+
+namespace Reference {
+ const int k = 5;
+ template<typename T> struct S {
+ static volatile int &r;
+ };
+ template<typename T> volatile int &S<T>::r = const_cast<volatile int&>(k);
+ constexpr int n = const_cast<int&>(S<int>::r);
+ static_assert(n == 5, "");
+}
diff --git a/clang/test/SemaTemplate/constructor-template.cpp b/clang/test/SemaTemplate/constructor-template.cpp
new file mode 100644
index 0000000..cf3fdfb
--- /dev/null
+++ b/clang/test/SemaTemplate/constructor-template.cpp
@@ -0,0 +1,128 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct X0 { // expected-note{{candidate}}
+ X0(int); // expected-note{{candidate}}
+ template<typename T> X0(T); // expected-note {{candidate}}
+ template<typename T, typename U> X0(T*, U*); // expected-note {{candidate}}
+
+ // PR4761
+ template<typename T> X0() : f0(T::foo) {} // expected-note {{candidate}}
+ int f0;
+};
+
+void accept_X0(X0);
+
+void test_X0(int i, float f) {
+ X0 x0a(i);
+ X0 x0b(f);
+ X0 x0c = i;
+ X0 x0d = f;
+ accept_X0(i);
+ accept_X0(&i);
+ accept_X0(f);
+ accept_X0(&f);
+ X0 x0e(&i, &f);
+ X0 x0f(&f, &i);
+
+ X0 x0g(f, &i); // expected-error{{no matching constructor}}
+}
+
+template<typename T>
+struct X1 {
+ X1(const X1&);
+ template<typename U> X1(const X1<U>&);
+};
+
+template<typename T>
+struct Outer {
+ typedef X1<T> A;
+
+ A alloc;
+
+ explicit Outer(const A& a) : alloc(a) { }
+};
+
+void test_X1(X1<int> xi) {
+ Outer<int> oi(xi);
+ Outer<float> of(xi);
+}
+
+// PR4655
+template<class C> struct A {};
+template <> struct A<int>{A(const A<int>&);};
+struct B { A<int> x; B(B& a) : x(a.x) {} };
+
+struct X2 {
+ X2(); // expected-note{{candidate constructor}}
+ X2(X2&); // expected-note {{candidate constructor}}
+ template<typename T> X2(T);
+};
+
+X2 test(bool Cond, X2 x2) {
+ if (Cond)
+ return x2; // okay, uses copy constructor
+
+ return X2(); // expected-error{{no matching constructor}}
+}
+
+struct X3 {
+ template<typename T> X3(T);
+};
+
+template<> X3::X3(X3); // expected-error{{must pass its first argument by reference}}
+
+struct X4 {
+ X4();
+ ~X4();
+ X4(X4&);
+ template<typename T> X4(const T&, int = 17);
+};
+
+X4 test_X4(bool Cond, X4 x4) {
+ X4 a(x4, 17); // okay, constructor template
+ X4 b(x4); // okay, copy constructor
+ return X4();
+}
+
+// Instantiation of a non-dependent use of a constructor
+struct DefaultCtorHasDefaultArg {
+ explicit DefaultCtorHasDefaultArg(int i = 17);
+};
+
+template<typename T>
+void default_ctor_inst() {
+ DefaultCtorHasDefaultArg def;
+}
+
+template void default_ctor_inst<int>();
+
+template<typename T>
+struct X5 {
+ X5();
+ X5(const T &);
+};
+
+struct X6 {
+ template<typename T> X6(T);
+};
+
+void test_X5_X6() {
+ X5<X6> tf;
+ X5<X6> tf2(tf);
+}
+
+namespace PR8182 {
+ struct foo {
+ foo();
+ template<class T> foo(T&);
+
+ private:
+ foo(const foo&);
+ };
+
+ void test_foo() {
+ foo f1;
+ foo f2(f1);
+ foo f3 = f1;
+ }
+
+}
diff --git a/clang/test/SemaTemplate/copy-ctor-assign.cpp b/clang/test/SemaTemplate/copy-ctor-assign.cpp
new file mode 100644
index 0000000..ae6dc9c
--- /dev/null
+++ b/clang/test/SemaTemplate/copy-ctor-assign.cpp
@@ -0,0 +1,52 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Make sure that copy constructors and assignment operators are properly
+// generated when there is a matching
+
+// PR5072
+template<typename T>
+struct X {
+ template<typename U>
+ X(const X<U>& other)
+ : value(other.value + 1) { } // expected-error{{binary expression}}
+
+ template<typename U>
+ X& operator=(const X<U>& other) {
+ value = other.value + 1; // expected-error{{binary expression}}
+ return *this;
+ }
+
+ T value;
+};
+
+struct Y {};
+
+X<int Y::*> test0(X<int Y::*> x) { return x; }
+X<int> test1(X<long> x) { return x; }
+
+
+X<int> test2(X<int Y::*> x) {
+ return x; // expected-note{{instantiation}}
+}
+
+void test3(X<int> &x, X<int> xi, X<long> xl, X<int Y::*> xmptr) {
+ x = xi;
+ x = xl;
+ x = xmptr; // expected-note{{instantiation}}
+}
+
+struct X1 {
+ X1 &operator=(const X1&);
+};
+
+template<typename T>
+struct X2 : X1 {
+ template<typename U> X2 &operator=(const U&);
+};
+
+struct X3 : X2<int> {
+};
+
+void test_X2(X3 &to, X3 from) {
+ to = from;
+}
diff --git a/clang/test/SemaTemplate/crash-10438657.cpp b/clang/test/SemaTemplate/crash-10438657.cpp
new file mode 100644
index 0000000..2ee64bd
--- /dev/null
+++ b/clang/test/SemaTemplate/crash-10438657.cpp
@@ -0,0 +1,15 @@
+// RUN: not %clang_cc1 -fsyntax-only %s 2> %t
+// RUN: FileCheck %s < %t
+// CHECK: 10 errors
+template<typename _CharT>
+class collate : public locale::facet {
+
+protected:
+virtual ~collate() {}
+ class wxObject;
+ class __attribute__ ((visibility("default"))) wxGDIRefData
+ : public wxObjectRefData {};
+ class __attribute__ ((visibility("default"))) wxGDIObject : public wxObject { \
+ public:
+ virtual bool IsOk() const {
+ return m_refData && static_cast<wxGDIRefData *>(m_refData)->IsOk();
diff --git a/clang/test/SemaTemplate/crash-8204126.cpp b/clang/test/SemaTemplate/crash-8204126.cpp
new file mode 100644
index 0000000..eb96560
--- /dev/null
+++ b/clang/test/SemaTemplate/crash-8204126.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct A
+{
+ template<int> template<typename T> friend void foo(T) {} // expected-error{{extraneous template parameter list}}
+ void bar() { foo(0); } // expected-error{{use of undeclared identifier 'foo'}}
+};
diff --git a/clang/test/SemaTemplate/current-instantiation.cpp b/clang/test/SemaTemplate/current-instantiation.cpp
new file mode 100644
index 0000000..ccef811
--- /dev/null
+++ b/clang/test/SemaTemplate/current-instantiation.cpp
@@ -0,0 +1,237 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This test concerns the identity of dependent types within the
+// canonical type system, specifically focusing on the difference
+// between members of the current instantiation and membmers of an
+// unknown specialization. This considers C++ [temp.type], which
+// specifies type equivalence within a template, and C++0x
+// [temp.dep.type], which defines what it means to be a member of the
+// current instantiation.
+
+template<typename T, typename U>
+struct X0 {
+ typedef T T_type;
+ typedef U U_type;
+
+ void f0(T&); // expected-note{{previous}}
+ void f0(typename X0::U_type&);
+ void f0(typename X0::T_type&); // expected-error{{redecl}}
+
+ void f1(T&); // expected-note{{previous}}
+ void f1(typename X0::U_type&);
+ void f1(typename X0<T, U>::T_type&); // expected-error{{redecl}}
+
+ void f2(T&); // expected-note{{previous}}
+ void f2(typename X0::U_type&);
+ void f2(typename X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
+
+ void f3(T&); // expected-note{{previous}}
+ void f3(typename X0::U_type&);
+ void f3(typename ::X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
+
+ struct X1 {
+ typedef T my_T_type;
+
+ void g0(T&); // expected-note{{previous}}
+ void g0(typename X0::U_type&);
+ void g0(typename X0::T_type&); // expected-error{{redecl}}
+
+ void g1(T&); // expected-note{{previous}}
+ void g1(typename X0::U_type&);
+ void g1(typename X0<T, U>::T_type&); // expected-error{{redecl}}
+
+ void g2(T&); // expected-note{{previous}}
+ void g2(typename X0::U_type&);
+ void g2(typename X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
+
+ void g3(T&); // expected-note{{previous}}
+ void g3(typename X0::U_type&);
+ void g3(typename ::X0<T_type, U_type>::T_type&); // expected-error{{redecl}}
+
+ void g4(T&); // expected-note{{previous}}
+ void g4(typename X0::U_type&);
+ void g4(typename X1::my_T_type&); // expected-error{{redecl}}
+
+ void g5(T&); // expected-note{{previous}}
+ void g5(typename X0::U_type&);
+ void g5(typename X0::X1::my_T_type&); // expected-error{{redecl}}
+
+ void g6(T&); // expected-note{{previous}}
+ void g6(typename X0::U_type&);
+ void g6(typename X0<T, U>::X1::my_T_type&); // expected-error{{redecl}}
+
+ void g7(T&); // expected-note{{previous}}
+ void g7(typename X0::U_type&);
+ void g7(typename ::X0<typename X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}}
+
+ void g8(T&); // expected-note{{previous}}
+ void g8(typename X0<U, T_type>::T_type&);
+ void g8(typename ::X0<typename X0<T_type, U>::X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}}
+ };
+};
+
+
+template<typename T, typename U>
+struct X0<T*, U*> {
+ typedef T T_type;
+ typedef U U_type;
+ typedef T* Tptr;
+ typedef U* Uptr;
+
+ void f0(T&); // expected-note{{previous}}
+ void f0(typename X0::U_type&);
+ void f0(typename X0::T_type&); // expected-error{{redecl}}
+
+ void f1(T&); // expected-note{{previous}}
+ void f1(typename X0::U_type&);
+ void f1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}}
+
+ void f2(T&); // expected-note{{previous}}
+ void f2(typename X0::U_type&);
+ void f2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
+
+ void f3(T&); // expected-note{{previous}}
+ void f3(typename X0::U_type&);
+ void f3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
+
+ void f4(T&); // expected-note{{previous}}
+ void f4(typename X0::U_type&);
+ void f4(typename ::X0<Tptr, Uptr>::T_type&); // expected-error{{redecl}}
+
+ void f5(X0*); // expected-note{{previous}}
+ void f5(::X0<T, U>*);
+ void f5(::X0<T*, U*>*); // expected-error{{redecl}}
+
+ struct X2 {
+ typedef T my_T_type;
+
+ void g0(T&); // expected-note{{previous}}
+ void g0(typename X0::U_type&);
+ void g0(typename X0::T_type&); // expected-error{{redecl}}
+
+ void g1(T&); // expected-note{{previous}}
+ void g1(typename X0::U_type&);
+ void g1(typename X0<T*, U*>::T_type&); // expected-error{{redecl}}
+
+ void g2(T&); // expected-note{{previous}}
+ void g2(typename X0::U_type&);
+ void g2(typename X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
+
+ void g3(T&); // expected-note{{previous}}
+ void g3(typename X0::U_type&);
+ void g3(typename ::X0<T_type*, U_type*>::T_type&); // expected-error{{redecl}}
+
+ void g4(T&); // expected-note{{previous}}
+ void g4(typename X0::U_type&);
+ void g4(typename X2::my_T_type&); // expected-error{{redecl}}
+
+ void g5(T&); // expected-note{{previous}}
+ void g5(typename X0::U_type&);
+ void g5(typename X0::X2::my_T_type&); // expected-error{{redecl}}
+
+ void g6(T&); // expected-note{{previous}}
+ void g6(typename X0::U_type&);
+ void g6(typename X0<T*, U*>::X2::my_T_type&); // expected-error{{redecl}}
+
+ void g7(T&); // expected-note{{previous}}
+ void g7(typename X0::U_type&);
+ void g7(typename ::X0<typename X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}}
+
+ void g8(T&); // expected-note{{previous}}
+ void g8(typename X0<U, T_type>::T_type&);
+ void g8(typename ::X0<typename X0<T_type*, U*>::X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}}
+ };
+};
+
+template<typename T>
+struct X1 {
+ static int *a;
+ void f(float *b) {
+ X1<T>::a = b; // expected-error{{incompatible}}
+ X1<T*>::a = b;
+ }
+};
+
+namespace ConstantInCurrentInstantiation {
+ template<typename T>
+ struct X {
+ static const int value = 2;
+ static int array[value];
+ };
+
+ template<typename T> const int X<T>::value;
+
+ template<typename T>
+ int X<T>::array[X<T>::value] = { 1, 2 };
+}
+
+namespace Expressions {
+ template <bool b>
+ struct Bool {
+ enum anonymous_enum { value = b };
+ };
+ struct True : public Bool<true> {};
+ struct False : public Bool<false> {};
+
+ template <typename T1, typename T2>
+ struct Is_Same : public False {};
+ template <typename T>
+ struct Is_Same<T, T> : public True {};
+
+ template <bool b, typename T = void>
+ struct Enable_If {};
+ template <typename T>
+ struct Enable_If<true, T> {
+ typedef T type;
+ };
+
+ template <typename T>
+ class Class {
+ public:
+ template <typename U>
+ typename Enable_If<Is_Same<U, Class>::value, void>::type
+ foo();
+ };
+
+
+ template <typename T>
+ template <typename U>
+ typename Enable_If<Is_Same<U, Class<T> >::value, void>::type
+ Class<T>::foo() {}
+}
+
+namespace PR9255 {
+ template<typename T>
+ class X0 {
+ public:
+ class Inner1;
+
+ class Inner2 {
+ public:
+ void f()
+ {
+ Inner1::f.g();
+ }
+ };
+ };
+}
+
+namespace rdar10194295 {
+ template<typename XT>
+ class X {
+ public:
+ enum Enum { Yes, No };
+ template<Enum> void foo();
+ template<Enum> class Inner;
+ };
+
+ template<typename XT>
+ template<typename X<XT>::Enum>
+ void X<XT>::foo()
+ {
+ }
+
+ template<typename XT>
+ template<typename X<XT>::Enum>
+ class X<XT>::Inner { };
+}
diff --git a/clang/test/SemaTemplate/deduction-crash.cpp b/clang/test/SemaTemplate/deduction-crash.cpp
new file mode 100644
index 0000000..cf3899f
--- /dev/null
+++ b/clang/test/SemaTemplate/deduction-crash.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -fsyntax-only %s 2>&1| FileCheck %s
+
+// Note that the error count below doesn't matter. We just want to
+// make sure that the parser doesn't crash.
+// CHECK: 13 errors
+
+// PR7511
+template<a>
+struct int_;
+
+template<a>
+template<int,typename T1,typename>
+struct ac
+{
+ typedef T1 ae
+};
+
+template<class>struct aaa
+{
+ typedef ac<1,int,int>::ae ae
+};
+
+template<class>
+struct state_machine
+{
+ typedef aaa<int>::ae aaa;
+ int start()
+ {
+ ant(0);
+ }
+
+ template<class>
+ struct region_processing_helper
+ {
+ template<class,int=0>
+ struct In;
+
+ template<int my>
+ struct In<a::int_<aaa::a>,my>;
+
+ template<class Event>
+ int process(Event)
+ {
+ In<a::int_<0> > a;
+ }
+ }
+ template<class Event>
+ int ant(Event)
+ {
+ region_processing_helper<int>* helper;
+ helper->process(0)
+ }
+};
+
+int a()
+{
+ state_machine<int> p;
+ p.ant(0);
+}
+
+// PR9974
+template <int> struct enable_if;
+template <class > struct remove_reference ;
+template <class _Tp> struct remove_reference<_Tp&> ;
+
+template <class > struct __tuple_like;
+
+template <class _Tp, class _Up, int = __tuple_like<typename remove_reference<_Tp>::type>::value>
+struct __tuple_convertible;
+
+struct pair
+{
+template<class _Tuple, int = enable_if<__tuple_convertible<_Tuple, pair>::value>::type>
+pair(_Tuple&& );
+};
+
+template <class> struct basic_ostream;
+
+template <int>
+void endl( ) ;
+
+extern basic_ostream<char> cout;
+
+int operator<<( basic_ostream<char> , pair ) ;
+
+void register_object_imp ( )
+{
+cout << endl<1>;
+}
diff --git a/clang/test/SemaTemplate/deduction.cpp b/clang/test/SemaTemplate/deduction.cpp
new file mode 100644
index 0000000..aecb5ee
--- /dev/null
+++ b/clang/test/SemaTemplate/deduction.cpp
@@ -0,0 +1,164 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Template argument deduction with template template parameters.
+template<typename T, template<T> class A>
+struct X0 {
+ static const unsigned value = 0;
+};
+
+template<template<int> class A>
+struct X0<int, A> {
+ static const unsigned value = 1;
+};
+
+template<int> struct X0i;
+template<long> struct X0l;
+int array_x0a[X0<long, X0l>::value == 0? 1 : -1];
+int array_x0b[X0<int, X0i>::value == 1? 1 : -1];
+
+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 allocator { };
+template<typename T, typename Alloc = allocator<T> > struct vector {};
+
+// Fun with meta-lambdas!
+struct _1 {};
+struct _2 {};
+
+// Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T.
+template<typename T, typename Arg1, typename Arg2>
+struct Replace {
+ typedef T type;
+};
+
+// Replacement of the whole type.
+template<typename Arg1, typename Arg2>
+struct Replace<_1, Arg1, Arg2> {
+ typedef Arg1 type;
+};
+
+template<typename Arg1, typename Arg2>
+struct Replace<_2, Arg1, Arg2> {
+ typedef Arg2 type;
+};
+
+// Replacement through cv-qualifiers
+template<typename T, typename Arg1, typename Arg2>
+struct Replace<const T, Arg1, Arg2> {
+ typedef typename Replace<T, Arg1, Arg2>::type const type;
+};
+
+// Replacement of templates
+template<template<typename> class TT, typename T1, typename Arg1, typename Arg2>
+struct Replace<TT<T1>, Arg1, Arg2> {
+ typedef TT<typename Replace<T1, Arg1, Arg2>::type> type;
+};
+
+template<template<typename, typename> class TT, typename T1, typename T2,
+ typename Arg1, typename Arg2>
+struct Replace<TT<T1, T2>, Arg1, Arg2> {
+ typedef TT<typename Replace<T1, Arg1, Arg2>::type,
+ typename Replace<T2, Arg1, Arg2>::type> type;
+};
+
+// Just for kicks...
+template<template<typename, typename> class TT, typename T1,
+ typename Arg1, typename Arg2>
+struct Replace<TT<T1, _2>, Arg1, Arg2> {
+ typedef TT<typename Replace<T1, Arg1, Arg2>::type, Arg2> type;
+};
+
+int array0[is_same<Replace<_1, int, float>::type, int>::value? 1 : -1];
+int array1[is_same<Replace<const _1, int, float>::type, const int>::value? 1 : -1];
+int array2[is_same<Replace<vector<_1>, int, float>::type, vector<int> >::value? 1 : -1];
+int array3[is_same<Replace<vector<const _1>, int, float>::type, vector<const int> >::value? 1 : -1];
+int array4[is_same<Replace<vector<int, _2>, double, float>::type, vector<int, float> >::value? 1 : -1];
+
+// PR5911
+template <typename T, int N> void f(const T (&a)[N]);
+int iarr[] = { 1 };
+void test_PR5911() { f(iarr); }
+
+// Must not examine base classes of incomplete type during template argument
+// deduction.
+namespace PR6257 {
+ template <typename T> struct X {
+ template <typename U> X(const X<U>& u);
+ };
+ struct A;
+ void f(A& a);
+ void f(const X<A>& a);
+ void test(A& a) { (void)f(a); }
+}
+
+// PR7463
+namespace PR7463 {
+ const int f ();
+ template <typename T_> void g (T_&); // expected-note{{T_ = int}}
+ void h (void) { g(f()); } // expected-error{{no matching function for call}}
+}
+
+namespace test0 {
+ template <class T> void make(const T *(*fn)()); // expected-note {{candidate template ignored: can't deduce a type for 'T' which would make 'const T' equal 'char'}}
+ char *char_maker();
+ void test() {
+ make(char_maker); // expected-error {{no matching function for call to 'make'}}
+ }
+}
+
+namespace test1 {
+ template<typename T> void foo(const T a[3][3]);
+ void test() {
+ int a[3][3];
+ foo(a);
+ }
+}
+
+// PR7708
+namespace test2 {
+ template<typename T> struct Const { typedef void const type; };
+
+ template<typename T> void f(T, typename Const<T>::type*);
+ template<typename T> void f(T, void const *);
+
+ void test() {
+ void *p = 0;
+ f(0, p);
+ }
+}
+
+// rdar://problem/8537391
+namespace test3 {
+ struct Foo {
+ template <void F(char)> static inline void foo();
+ };
+
+ class Bar {
+ template<typename T> static inline void wobble(T ch);
+
+ public:
+ static void madness() {
+ Foo::foo<wobble<char> >();
+ }
+ };
+}
+
+// Verify that we can deduce enum-typed arguments correctly.
+namespace test14 {
+ enum E { E0, E1 };
+ template <E> struct A {};
+ template <E e> void foo(const A<e> &a) {}
+
+ void test() {
+ A<E0> a;
+ foo(a);
+ }
+}
diff --git a/clang/test/SemaTemplate/default-arguments-cxx0x.cpp b/clang/test/SemaTemplate/default-arguments-cxx0x.cpp
new file mode 100644
index 0000000..7714313
--- /dev/null
+++ b/clang/test/SemaTemplate/default-arguments-cxx0x.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+
+// Test default template arguments for function templates.
+template<typename T = int>
+void f0();
+
+template<typename T>
+void f0();
+
+void g0() {
+ f0(); // okay!
+}
+
+template<typename T, int N = T::value>
+int &f1(T);
+
+float &f1(...);
+
+struct HasValue {
+ static const int value = 17;
+};
+
+void g1() {
+ float &fr = f1(15);
+ int &ir = f1(HasValue());
+}
diff --git a/clang/test/SemaTemplate/default-arguments.cpp b/clang/test/SemaTemplate/default-arguments.cpp
new file mode 100644
index 0000000..6391369
--- /dev/null
+++ b/clang/test/SemaTemplate/default-arguments.cpp
@@ -0,0 +1,138 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, int N = 2> struct X; // expected-note{{template is declared here}}
+
+X<int, 1> *x1;
+X<int> *x2;
+
+X<> *x3; // expected-error{{too few template arguments for class template 'X'}}
+
+template<typename U = float, int M> struct X;
+
+X<> *x4;
+
+template<typename T = int> struct Z { };
+template struct Z<>;
+
+// PR4362
+template<class T> struct a { };
+template<> struct a<int> { static const bool v = true; };
+
+template<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}}
+
+template struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}}
+template struct p<int>;
+
+// PR5187
+template<typename T, typename U>
+struct A;
+
+template<typename T, typename U = T>
+struct A;
+
+template<typename T, typename U>
+struct A {
+ void f(A<T>);
+};
+
+template<typename T>
+struct B { };
+
+template<>
+struct B<void> {
+ typedef B<void*> type;
+};
+
+// Nested default arguments for template parameters.
+template<typename T> struct X1 { };
+
+template<typename T>
+struct X2 {
+ template<typename U = typename X1<T>::type> // expected-error{{no type named}}
+ struct Inner1 { };
+
+ template<T Value = X1<T>::value> // expected-error{{no member named 'value'}}
+ struct NonType1 { };
+
+ template<T Value>
+ struct Inner2 { };
+
+ template<typename U>
+ struct Inner3 {
+ template<typename X = T, typename V = U>
+ struct VeryInner { };
+
+ template<T Value1 = sizeof(T), T Value2 = sizeof(U),
+ T Value3 = Value1 + Value2>
+ struct NonType2 { };
+ };
+};
+
+X2<int> x2i;
+X2<int>::Inner1<float> x2iif;
+
+X2<int>::Inner1<> x2bad; // expected-note{{instantiation of default argument}}
+
+X2<int>::NonType1<'a'> x2_nontype1;
+X2<int>::NonType1<> x2_nontype1_bad; // expected-note{{instantiation of default argument}}
+
+// Check multi-level substitution into template type arguments
+X2<int>::Inner3<float>::VeryInner<> vi;
+X2<char>::Inner3<int>::NonType2<> x2_deep_nontype;
+
+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 array1[is_same<__typeof__(vi),
+ X2<int>::Inner3<float>::VeryInner<int, float> >::value? 1 : -1];
+
+int array2[is_same<__typeof(x2_deep_nontype),
+ X2<char>::Inner3<int>::NonType2<sizeof(char), sizeof(int),
+ sizeof(char)+sizeof(int)> >::value? 1 : -1];
+
+// Template template parameter defaults
+template<template<typename T> class X = X2> struct X3 { };
+int array3[is_same<X3<>, X3<X2> >::value? 1 : -1];
+
+struct add_pointer {
+ template<typename T>
+ struct apply {
+ typedef T* type;
+ };
+};
+
+template<typename T, template<typename> class X = T::template apply>
+ struct X4;
+int array4[is_same<X4<add_pointer>,
+ X4<add_pointer, add_pointer::apply> >::value? 1 : -1];
+
+template<int> struct X5 {}; // expected-note{{has a different type 'int'}}
+template<long> struct X5b {};
+template<typename T,
+ template<T> class B = X5> // expected-error{{template template argument has different}} \
+ // expected-note{{previous non-type template parameter}}
+ struct X6 {};
+
+X6<int> x6a;
+X6<long> x6b; // expected-note{{while checking a default template argument}}
+X6<long, X5b> x6c;
+
+
+template<template<class> class X = B<int> > struct X7; // expected-error{{must be a class template}}
+
+namespace PR9643 {
+ template<typename T> class allocator {};
+ template<typename T, typename U = allocator<T> > class vector {};
+
+ template<template<typename U, typename = allocator<U> > class container,
+ typename DT>
+ container<DT> initializer(const DT& d) {
+ return container<DT>();
+ }
+
+ void f() {
+ vector<int, allocator<int> > v = initializer<vector>(5);
+ }
+}
diff --git a/clang/test/SemaTemplate/default-expr-arguments-2.cpp b/clang/test/SemaTemplate/default-expr-arguments-2.cpp
new file mode 100644
index 0000000..378999d
--- /dev/null
+++ b/clang/test/SemaTemplate/default-expr-arguments-2.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -ast-dump %s 2>&1 | FileCheck %s
+
+// This is a wacky test to ensure that we're actually instantiating
+// the default arguments of the constructor when the function type is
+// otherwise non-dependent.
+namespace PR6733 {
+ template <class T>
+ class bar {
+ public: enum { kSomeConst = 128 };
+ bar(int x = kSomeConst) {}
+ };
+
+ // CHECK: void f()
+ void f() {
+ // CHECK: bar<int> tmp =
+ // CHECK: CXXDefaultArgExpr{{.*}}'int'
+ bar<int> tmp;
+ }
+}
diff --git a/clang/test/SemaTemplate/default-expr-arguments.cpp b/clang/test/SemaTemplate/default-expr-arguments.cpp
new file mode 100644
index 0000000..1eefa9f
--- /dev/null
+++ b/clang/test/SemaTemplate/default-expr-arguments.cpp
@@ -0,0 +1,305 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+class C { C(int a0 = 0); };
+
+template<>
+C<char>::C(int a0);
+
+struct S { }; // expected-note 3 {{candidate constructor (the implicit copy constructor)}}
+
+template<typename T> void f1(T a, T b = 10) { } // expected-error{{no viable conversion}} \
+// expected-note{{passing argument to parameter 'b' here}}
+
+template<typename T> void f2(T a, T b = T()) { }
+
+template<typename T> void f3(T a, T b = T() + T()); // expected-error{{invalid operands to binary expression ('S' and 'S')}}
+
+void g() {
+ f1(10);
+ f1(S()); // expected-note{{in instantiation of default function argument expression for 'f1<S>' required here}}
+
+ f2(10);
+ f2(S());
+
+ f3(10);
+ f3(S()); // expected-note{{in instantiation of default function argument expression for 'f3<S>' required here}}
+}
+
+template<typename T> struct F {
+ F(T t = 10); // expected-error{{no viable conversion}} \
+ // expected-note{{passing argument to parameter 't' here}}
+ void f(T t = 10); // expected-error{{no viable conversion}} \
+ // expected-note{{passing argument to parameter 't' here}}
+};
+
+struct FD : F<int> { };
+
+void g2() {
+ F<int> f;
+ FD fd;
+}
+
+void g3(F<int> f, F<struct S> s) {
+ f.f();
+ s.f(); // expected-note{{in instantiation of default function argument expression for 'f<S>' required here}}
+
+ F<int> f2;
+ F<S> s2; // expected-note{{in instantiation of default function argument expression for 'F<S>' required here}}
+}
+
+template<typename T> struct G {
+ G(T) {}
+};
+
+void s(G<int> flags = 10) { }
+
+// Test default arguments
+template<typename T>
+struct X0 {
+ void f(T = T()); // expected-error{{no matching}}
+};
+
+template<typename U>
+void X0<U>::f(U) { }
+
+void test_x0(X0<int> xi) {
+ xi.f();
+ xi.f(17);
+}
+
+struct NotDefaultConstructible { // expected-note 2{{candidate}}
+ NotDefaultConstructible(int); // expected-note 2{{candidate}}
+};
+
+void test_x0_not_default_constructible(X0<NotDefaultConstructible> xn) {
+ xn.f(NotDefaultConstructible(17));
+ xn.f(42);
+ xn.f(); // expected-note{{in instantiation of default function argument}}
+}
+
+template<typename T>
+struct X1 {
+ typedef T value_type;
+ X1(const value_type& value = value_type());
+};
+
+void test_X1() {
+ X1<int> x1;
+}
+
+template<typename T>
+struct X2 {
+ void operator()(T = T()); // expected-error{{no matching}}
+};
+
+void test_x2(X2<int> x2i, X2<NotDefaultConstructible> x2n) {
+ x2i();
+ x2i(17);
+ x2n(NotDefaultConstructible(17));
+ x2n(); // expected-note{{in instantiation of default function argument}}
+}
+
+// PR5283
+namespace PR5283 {
+template<typename T> struct A {
+ A(T = 1); // expected-error 3 {{cannot initialize a parameter of type 'int *' with an rvalue of type 'int'}} \
+ // expected-note 3{{passing argument to parameter here}}
+};
+
+struct B : A<int*> {
+ B();
+};
+B::B() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
+
+struct C : virtual A<int*> {
+ C();
+};
+C::C() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
+
+struct D {
+ D();
+
+ A<int*> a;
+};
+D::D() { } // expected-note {{in instantiation of default function argument expression for 'A<int *>' required he}}
+}
+
+// PR5301
+namespace pr5301 {
+ void f(int, int = 0);
+
+ template <typename T>
+ void g(T, T = 0);
+
+ template <int I>
+ void i(int a = I);
+
+ template <typename T>
+ void h(T t) {
+ f(0);
+ g(1);
+ g(t);
+ i<2>();
+ }
+
+ void test() {
+ h(0);
+ }
+}
+
+// PR5810
+namespace PR5810 {
+ template<typename T>
+ struct allocator {
+ allocator() { int a[sizeof(T) ? -1 : -1]; } // expected-error2 {{array with a negative size}}
+ };
+
+ template<typename T>
+ struct vector {
+ vector(const allocator<T>& = allocator<T>()) {} // expected-note2 {{instantiation of}}
+ };
+
+ struct A { };
+ struct B { };
+
+ template<typename>
+ void FilterVTs() {
+ vector<A> Result;
+ }
+
+ void f() {
+ vector<A> Result;
+ }
+
+ template<typename T>
+ struct X {
+ vector<B> bs;
+ X() { }
+ };
+
+ void f2() {
+ X<float> x; // expected-note{{member function}}
+ }
+}
+
+template<typename T> void f4(T, int = 17);
+template<> void f4<int>(int, int);
+
+void f4_test(int i) {
+ f4(i);
+}
+
+// Instantiate for initialization
+namespace InstForInit {
+ template<typename T>
+ struct Ptr {
+ typedef T* type;
+ Ptr(type);
+ };
+
+ template<typename T>
+ struct Holder {
+ Holder(int i, Ptr<T> ptr = 0);
+ };
+
+ void test_holder(int i) {
+ Holder<int> h(i);
+ }
+};
+
+namespace PR5810b {
+ template<typename T>
+ T broken() {
+ T t;
+ double**** not_it = t;
+ }
+
+ void f(int = broken<int>());
+ void g() { f(17); }
+}
+
+namespace PR5810c {
+ template<typename T>
+ struct X {
+ X() {
+ T t;
+ double *****p = t; // expected-error{{cannot initialize a variable of type 'double *****' with an lvalue of type 'int'}}
+ }
+ X(const X&) { }
+ };
+
+ struct Y : X<int> { // expected-note{{instantiation of}}
+ };
+
+ void f(Y y = Y());
+
+ void g() { f(); }
+}
+
+namespace PR8127 {
+ template< typename T > class PointerClass {
+ public:
+ PointerClass( T * object_p ) : p_( object_p ) {
+ p_->acquire();
+ }
+ private:
+ T * p_;
+ };
+
+ class ExternallyImplementedClass;
+
+ class MyClass {
+ void foo( PointerClass<ExternallyImplementedClass> = 0 );
+ };
+}
+
+namespace rdar8427926 {
+ template<typename T>
+ struct Boom {
+ ~Boom() {
+ T t;
+ double *******ptr = t; // expected-error 2{{cannot initialize}}
+ }
+ };
+
+ Boom<float> *bfp;
+
+ struct X {
+ void f(Boom<int> = Boom<int>()) { } // expected-note{{requested here}}
+ void g(int x = (delete bfp, 0)); // expected-note{{requested here}}
+ };
+
+ void test(X *x) {
+ x->f();
+ x->g();
+ }
+}
+
+namespace PR8401 {
+ template<typename T>
+ struct A {
+ A() { T* x = 1; } // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+ };
+
+ template<typename T>
+ struct B {
+ B(const A<T>& a = A<T>()); // expected-note{{in instantiation of}}
+ };
+
+ void f(B<int> b = B<int>());
+
+ void g() {
+ f();
+ }
+}
+
+namespace PR12581 {
+ const int a = 0;
+ template < typename > struct A;
+ template < typename MatrixType, int =
+ A < MatrixType >::Flags ? : A < MatrixType >::Flags & a > class B;
+ void
+ fn1 ()
+ {
+ }
+}
diff --git a/clang/test/SemaTemplate/delegating-constructors.cpp b/clang/test/SemaTemplate/delegating-constructors.cpp
new file mode 100644
index 0000000..e177b50
--- /dev/null
+++ b/clang/test/SemaTemplate/delegating-constructors.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
+
+namespace PR10457 {
+
+ class string
+ {
+ string(const char* str, unsigned);
+
+ public:
+ template <unsigned N>
+ string(const char (&str)[N])
+ : string(str) {} // expected-error{{constructor for 'string<6>' creates a delegation cycle}}
+ };
+
+ void f() {
+ string s("hello");
+ }
+
+ struct Foo {
+ Foo(int) { }
+
+
+ template <typename T>
+ Foo(T, int i) : Foo(i) { }
+};
+
+ void test_Foo()
+ {
+ Foo f(1, 1);
+ }
+}
diff --git a/clang/test/SemaTemplate/dependent-base-classes.cpp b/clang/test/SemaTemplate/dependent-base-classes.cpp
new file mode 100644
index 0000000..895eacc
--- /dev/null
+++ b/clang/test/SemaTemplate/dependent-base-classes.cpp
@@ -0,0 +1,137 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T, typename U>
+struct X0 : T::template apply<U> {
+ X0(U u) : T::template apply<U>(u) { }
+};
+
+template<typename T, typename U>
+struct X1 : T::apply<U> { }; // expected-error{{use 'template' keyword to treat 'apply' as a dependent template name}}
+
+template<typename T>
+struct X2 : vector<T> { }; // expected-error{{unknown template name 'vector'}}
+
+namespace PR6031 {
+ template<typename T>
+ struct A;
+
+ template <class X>
+ struct C { };
+
+ template <class TT>
+ struct II {
+ typedef typename A<TT>::type type;
+ };
+
+ template <class TT>
+ struct FI : II<TT>
+ {
+ C<typename FI::type> a;
+ };
+
+ template <class TT>
+ struct FI2
+ {
+ C<typename FI2::type> a; // expected-error{{no type named 'type' in 'FI2<TT>'}} \
+ // expected-error{{C++ requires a type specifier for all declarations}}
+ };
+
+ template<typename T>
+ struct Base {
+ class Nested { };
+ template<typename U> struct MemberTemplate { };
+ int a;
+ };
+
+ template<typename T>
+ struct HasDepBase : Base<T> {
+ int foo() {
+ class HasDepBase::Nested nested;
+ typedef typename HasDepBase::template MemberTemplate<T>::type type;
+ return HasDepBase::a;
+ }
+ };
+
+ template<typename T>
+ struct NoDepBase {
+ int foo() {
+ class NoDepBase::Nested nested; // expected-error{{no class named 'Nested' in 'NoDepBase<T>'}}
+ typedef typename NoDepBase::template MemberTemplate<T>::type type; // expected-error{{'MemberTemplate' following the 'template' keyword does not refer to a template}} \
+ // FIXME: expected-error{{unqualified-id}}
+ return NoDepBase::a; // expected-error{{no member named 'a' in 'NoDepBase<T>'}}
+ }
+ };
+}
+
+namespace Ambig {
+ template<typename T>
+ struct Base1 {
+ typedef int type; // expected-note{{member found by ambiguous name lookup}}
+ };
+
+ struct Base2 {
+ typedef float type; // expected-note{{member found by ambiguous name lookup}}
+ };
+
+ template<typename T>
+ struct Derived : Base1<T>, Base2 {
+ typedef typename Derived::type type; // expected-error{{member 'type' found in multiple base classes of different types}}
+ type *foo(float *fp) { return fp; }
+ };
+
+ Derived<int> di; // expected-note{{instantiation of}}
+}
+
+namespace PR6081 {
+ template<typename T>
+ struct A { };
+
+ template<typename T>
+ class B : public A<T>
+ {
+ public:
+ template< class X >
+ void f0(const X & k)
+ {
+ this->template f1<int>()(k);
+ }
+ };
+
+ template<typename T>
+ class C
+ {
+ public:
+ template< class X >
+ void f0(const X & k)
+ {
+ this->template f1<int>()(k); // expected-error{{'f1' following the 'template' keyword does not refer to a template}} \
+ // FIXME: expected-error{{unqualified-id}} \
+ // expected-error{{function-style cast or type construction}} \
+ // expected-error{{expected expression}}
+ }
+ };
+}
+
+namespace PR6413 {
+ template <typename T> class Base_A { };
+
+ class Base_B { };
+
+ template <typename T>
+ class Derived
+ : public virtual Base_A<T>
+ , public virtual Base_B
+ { };
+}
+
+namespace PR5812 {
+ template <class T> struct Base {
+ Base* p;
+ };
+
+ template <class T> struct Derived: public Base<T> {
+ typename Derived::Base* p; // meaning Derived::Base<T>
+ };
+
+ Derived<int> di;
+}
diff --git a/clang/test/SemaTemplate/dependent-base-member-init.cpp b/clang/test/SemaTemplate/dependent-base-member-init.cpp
new file mode 100644
index 0000000..1d4fed3
--- /dev/null
+++ b/clang/test/SemaTemplate/dependent-base-member-init.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR4381
+template<class T> struct X {};
+template<typename T> struct Y : public X<T>::X { };
+
+// PR4621
+class A1 {
+ A1(int x) {}
+};
+template<class C> class B1 : public A1 {
+ B1(C x) : A1(x.x) {}
+};
+class A2 { A2(int x, int y); };
+template <class C> class B2 {
+ A2 x;
+ B2(C x) : x(x.x, x.y) {}
+};
+template <class C> class B3 {
+ C x;
+ B3() : x(1,2) {}
+};
+
+// PR4627
+template<typename _Container> class insert_iterator {
+ _Container* container;
+ insert_iterator(_Container& __x) : container(&__x) {}
+};
+
+// PR4763
+template<typename T> struct s0 {};
+template<typename T> struct s0_traits {};
+template<typename T> struct s1 : s0<typename s0_traits<T>::t0> {
+ s1() {}
+};
+
+// PR6062
+namespace PR6062 {
+ template <typename T>
+ class A : public T::type
+ {
+ A() : T::type()
+ {
+ }
+
+ template <typename U>
+ A(U const& init)
+ : T::type(init)
+ { }
+
+ template<typename U>
+ A(U& init) : U::other_type(init) { }
+ };
+}
+
+template<typename T, typename U>
+struct X0 : T::template apply<U> {
+ X0(int i) : T::template apply<U>(i) { }
+};
+
+// PR7698
+namespace PR7698 {
+ template<typename Type>
+ class A {
+ char mA[sizeof(Type *)];
+ A(): mA() {}
+ };
+}
diff --git a/clang/test/SemaTemplate/dependent-class-member-operator.cpp b/clang/test/SemaTemplate/dependent-class-member-operator.cpp
new file mode 100644
index 0000000..d70a60c
--- /dev/null
+++ b/clang/test/SemaTemplate/dependent-class-member-operator.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR7837
+
+template<class T> struct C1 { void operator()(T); };
+template<class T> struct C2; // expected-note {{template is declared here}}
+template<class T> void foo(T);
+void wrap() {
+ foo(&C1<int>::operator());
+ foo(&C1<int>::operator+); // expected-error {{no member named 'operator+' in 'C1<int>'}}
+ foo(&C2<int>::operator+); // expected-error {{implicit instantiation of undefined template 'C2<int>'}}
+}
diff --git a/clang/test/SemaTemplate/dependent-expr.cpp b/clang/test/SemaTemplate/dependent-expr.cpp
new file mode 100644
index 0000000..a1ddd24
--- /dev/null
+++ b/clang/test/SemaTemplate/dependent-expr.cpp
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5908
+template <typename Iterator>
+void Test(Iterator it) {
+ *(it += 1);
+}
+
+namespace PR6045 {
+ template<unsigned int r>
+ class A
+ {
+ static const unsigned int member = r;
+ void f();
+ };
+
+ template<unsigned int r>
+ const unsigned int A<r>::member;
+
+ template<unsigned int r>
+ void A<r>::f()
+ {
+ unsigned k;
+ (void)(k % member);
+ }
+}
+
+namespace PR7198 {
+ struct A
+ {
+ ~A() { }
+ };
+
+ template<typename T>
+ struct B {
+ struct C : A {};
+ void f()
+ {
+ C c = C();
+ }
+ };
+}
+
+namespace PR7724 {
+ template<typename OT> int myMethod()
+ { return 2 && sizeof(OT); }
+}
+
+namespace test4 {
+ template <typename T> T *addressof(T &v) {
+ return reinterpret_cast<T*>(
+ &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
+ }
+}
+
+namespace test5 {
+ template <typename T> class chained_map {
+ int k;
+ void lookup() const {
+ int &v = (int &)k;
+ }
+ };
+}
+
+namespace PR8795 {
+ template <class _CharT> int test(_CharT t)
+ {
+ int data [] = {
+ sizeof(_CharT) > sizeof(char)
+ };
+ return data[0];
+ }
+}
diff --git a/clang/test/SemaTemplate/dependent-names-no-std.cpp b/clang/test/SemaTemplate/dependent-names-no-std.cpp
new file mode 100644
index 0000000..2fb9d99
--- /dev/null
+++ b/clang/test/SemaTemplate/dependent-names-no-std.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+//
+// The whole point of this test is to verify certain diagnostics work in the
+// absence of namespace 'std'.
+
+namespace PR10053 {
+ namespace ns {
+ struct Data {};
+ }
+
+ template<typename T> struct A {
+ T t;
+ A() {
+ f(t); // expected-error {{call to function 'f' that is neither visible in the template definition nor found by argument-dependent lookup}}
+ }
+ };
+
+ void f(ns::Data); // expected-note {{in namespace 'PR10053::ns'}}
+
+ A<ns::Data> a; // expected-note {{in instantiation of member function}}
+}
diff --git a/clang/test/SemaTemplate/dependent-names.cpp b/clang/test/SemaTemplate/dependent-names.cpp
new file mode 100644
index 0000000..924bad9
--- /dev/null
+++ b/clang/test/SemaTemplate/dependent-names.cpp
@@ -0,0 +1,326 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+typedef double A;
+template<typename T> class B {
+ typedef int A;
+};
+
+template<typename T> struct X : B<T> {
+ static A a;
+};
+
+int a0[sizeof(X<int>::a) == sizeof(double) ? 1 : -1];
+
+// PR4365.
+template<class T> class Q;
+template<class T> class R : Q<T> {T current;};
+
+
+namespace test0 {
+ template <class T> class Base {
+ public:
+ void instance_foo();
+ static void static_foo();
+ class Inner {
+ public:
+ void instance_foo();
+ static void static_foo();
+ };
+ };
+
+ template <class T> class Derived1 : Base<T> {
+ public:
+ void test0() {
+ Base<T>::static_foo();
+ Base<T>::instance_foo();
+ }
+
+ void test1() {
+ Base<T>::Inner::static_foo();
+ Base<T>::Inner::instance_foo(); // expected-error {{call to non-static member function without an object argument}}
+ }
+
+ static void test2() {
+ Base<T>::static_foo();
+ Base<T>::instance_foo(); // expected-error {{call to non-static member function without an object argument}}
+ }
+
+ static void test3() {
+ Base<T>::Inner::static_foo();
+ Base<T>::Inner::instance_foo(); // expected-error {{call to non-static member function without an object argument}}
+ }
+ };
+
+ template <class T> class Derived2 : Base<T>::Inner {
+ public:
+ void test0() {
+ Base<T>::static_foo();
+ Base<T>::instance_foo(); // expected-error {{call to non-static member function without an object argument}}
+ }
+
+ void test1() {
+ Base<T>::Inner::static_foo();
+ Base<T>::Inner::instance_foo();
+ }
+
+ static void test2() {
+ Base<T>::static_foo();
+ Base<T>::instance_foo(); // expected-error {{call to non-static member function without an object argument}}
+ }
+
+ static void test3() {
+ Base<T>::Inner::static_foo();
+ Base<T>::Inner::instance_foo(); // expected-error {{call to non-static member function without an object argument}}
+ }
+ };
+
+ void test0() {
+ Derived1<int> d1;
+ d1.test0();
+ d1.test1(); // expected-note {{in instantiation of member function}}
+ d1.test2(); // expected-note {{in instantiation of member function}}
+ d1.test3(); // expected-note {{in instantiation of member function}}
+
+ Derived2<int> d2;
+ d2.test0(); // expected-note {{in instantiation of member function}}
+ d2.test1();
+ d2.test2(); // expected-note {{in instantiation of member function}}
+ d2.test3(); // expected-note {{in instantiation of member function}}
+ }
+}
+
+namespace test1 {
+ template <class T> struct Base {
+ void foo(T); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
+ };
+
+ template <class T> struct Derived : Base<T> {
+ void doFoo(T v) {
+ foo(v); // expected-error {{use of undeclared identifier}}
+ }
+ };
+
+ template struct Derived<int>; // expected-note {{requested here}}
+}
+
+namespace PR8966 {
+ template <class T>
+ class MyClassCore
+ {
+ };
+
+ template <class T>
+ class MyClass : public MyClassCore<T>
+ {
+ public:
+ enum {
+ N
+ };
+
+ // static member declaration
+ static const char* array [N];
+
+ void f() {
+ MyClass<T>::InBase = 17;
+ }
+ };
+
+ // static member definition
+ template <class T>
+ const char* MyClass<T>::array [MyClass<T>::N] = { "A", "B", "C" };
+}
+
+namespace std {
+ inline namespace v1 {
+ template<typename T> struct basic_ostream;
+ }
+ namespace inner {
+ template<typename T> struct vector {};
+ }
+ using inner::vector;
+ template<typename T, typename U> struct pair {};
+ typedef basic_ostream<char> ostream;
+ extern ostream cout;
+ std::ostream &operator<<(std::ostream &out, const char *);
+}
+
+namespace PR10053 {
+ template<typename T> struct A {
+ T t;
+ A() {
+ f(t); // expected-error {{call to function 'f' that is neither visible in the template definition nor found by argument-dependent lookup}}
+ }
+ };
+
+ void f(int&); // expected-note {{'f' should be declared prior to the call site}}
+
+ A<int> a; // expected-note {{in instantiation of member function}}
+
+
+ namespace N {
+ namespace M {
+ template<typename T> int g(T t) {
+ f(t); // expected-error {{call to function 'f' that is neither visible in the template definition nor found by argument-dependent lookup}}
+ };
+ }
+
+ void f(char&); // expected-note {{'f' should be declared prior to the call site}}
+ }
+
+ void f(char&);
+
+ int k = N::M::g<char>(0);; // expected-note {{in instantiation of function}}
+
+
+ namespace O {
+ void f(char&); // expected-note {{candidate function not viable}}
+
+ template<typename T> struct C {
+ static const int n = f(T()); // expected-error {{no matching function}}
+ };
+ }
+
+ int f(double); // no note, shadowed by O::f
+ O::C<double> c; // expected-note {{requested here}}
+
+
+ // Example from www/compatibility.html
+ namespace my_file {
+ template <typename T> T Squared(T x) {
+ return Multiply(x, x); // expected-error {{neither visible in the template definition nor found by argument-dependent lookup}}
+ }
+
+ int Multiply(int x, int y) { // expected-note {{should be declared prior to the call site}}
+ return x * y;
+ }
+
+ int main() {
+ Squared(5); // expected-note {{here}}
+ }
+ }
+
+ // Example from www/compatibility.html
+ namespace my_file2 {
+ template<typename T>
+ void Dump(const T& value) {
+ std::cout << value << "\n"; // expected-error {{neither visible in the template definition nor found by argument-dependent lookup}}
+ }
+
+ namespace ns {
+ struct Data {};
+ }
+
+ std::ostream& operator<<(std::ostream& out, ns::Data data) { // expected-note {{should be declared prior to the call site or in namespace 'PR10053::my_file2::ns'}}
+ return out << "Some data";
+ }
+
+ void Use() {
+ Dump(ns::Data()); // expected-note {{here}}
+ }
+ }
+
+ namespace my_file2_a {
+ template<typename T>
+ void Dump(const T &value) {
+ print(std::cout, value); // expected-error 4{{neither visible in the template definition nor found by argument-dependent lookup}}
+ }
+
+ namespace ns {
+ struct Data {};
+ }
+ namespace ns2 {
+ struct Data {};
+ }
+
+ std::ostream &print(std::ostream &out, int); // expected-note-re {{should be declared prior to the call site$}}
+ std::ostream &print(std::ostream &out, ns::Data); // expected-note {{should be declared prior to the call site or in namespace 'PR10053::my_file2_a::ns'}}
+ std::ostream &print(std::ostream &out, std::vector<ns2::Data>); // expected-note {{should be declared prior to the call site or in namespace 'PR10053::my_file2_a::ns2'}}
+ std::ostream &print(std::ostream &out, std::pair<ns::Data, ns2::Data>); // expected-note {{should be declared prior to the call site or in an associated namespace of one of its arguments}}
+
+ void Use() {
+ Dump(0); // expected-note {{requested here}}
+ Dump(ns::Data()); // expected-note {{requested here}}
+ Dump(std::vector<ns2::Data>()); // expected-note {{requested here}}
+ Dump(std::pair<ns::Data, ns2::Data>()); // expected-note {{requested here}}
+ }
+ }
+
+ namespace unary {
+ template<typename T>
+ T Negate(const T& value) {
+ return !value; // expected-error {{call to function 'operator!' that is neither visible in the template definition nor found by argument-dependent lookup}}
+ }
+
+ namespace ns {
+ struct Data {};
+ }
+
+ ns::Data operator!(ns::Data); // expected-note {{should be declared prior to the call site or in namespace 'PR10053::unary::ns'}}
+
+ void Use() {
+ Negate(ns::Data()); // expected-note {{requested here}}
+ }
+ }
+}
+
+namespace PR10187 {
+ namespace A {
+ template<typename T>
+ struct S {
+ void f() {
+ for (auto &a : e)
+ __range(a); // expected-error {{undeclared identifier '__range'}}
+ }
+ int e[10];
+ };
+ void g() {
+ S<int>().f(); // expected-note {{here}}
+ }
+ }
+
+ namespace B {
+ template<typename T> void g(); // expected-note {{not viable}}
+ template<typename T> void f() {
+ g<int>(T()); // expected-error {{no matching function}}
+ }
+
+ namespace {
+ struct S {};
+ }
+ void g(S);
+
+ template void f<S>(); // expected-note {{here}}
+ }
+}
+
+namespace rdar11242625 {
+
+template <typename T>
+struct Main {
+ struct default_names {
+ typedef int id;
+ };
+
+ template <typename T2 = typename default_names::id>
+ struct TS {
+ T2 q;
+ };
+};
+
+struct Sub : public Main<int> {
+ TS<> ff;
+};
+
+int arr[sizeof(Sub)];
+
+}
+
+namespace PR11421 {
+template < unsigned > struct X {
+ static const unsigned dimension = 3;
+ template<unsigned dim=dimension>
+ struct Y: Y<dim> { }; // expected-error {{incomplete type}} expected-note {{is not complete until the closing}}
+};
+typedef X<3> X3;
+X3::Y<>::iterator it; // expected-note {{requested here}}
+}
diff --git a/clang/test/SemaTemplate/dependent-sized_array.cpp b/clang/test/SemaTemplate/dependent-sized_array.cpp
new file mode 100644
index 0000000..cf0e0f3
--- /dev/null
+++ b/clang/test/SemaTemplate/dependent-sized_array.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -pedantic -verify %s
+
+template<int N>
+void f() {
+ int a[] = { 1, 2, 3, N };
+ unsigned numAs = sizeof(a) / sizeof(int);
+}
+
+template void f<17>();
+
+
+template<int N>
+void f1() {
+ int a0[] = {}; // expected-warning{{zero}}
+ int a1[] = { 1, 2, 3, N };
+ int a3[sizeof(a1)/sizeof(int) != 4? 1 : -1]; // expected-error{{negative}}
+}
diff --git a/clang/test/SemaTemplate/dependent-template-recover.cpp b/clang/test/SemaTemplate/dependent-template-recover.cpp
new file mode 100644
index 0000000..3c01f65
--- /dev/null
+++ b/clang/test/SemaTemplate/dependent-template-recover.cpp
@@ -0,0 +1,60 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U, int N>
+struct X {
+ void f(T* t) {
+ t->f0<U>(); // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}}
+ t->f0<int>(); // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}}
+
+ t->operator+<U const, 1>(); // expected-error{{use 'template' keyword to treat 'operator +' as a dependent template name}}
+ t->f1<int const, 2>(); // expected-error{{use 'template' keyword to treat 'f1' as a dependent template name}}
+
+ T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
+ t->T::getAs<U>(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}}
+
+ // FIXME: We can't recover from these yet
+ (*t).f2<N>(); // expected-error{{expected expression}}
+ (*t).f2<0>(); // expected-error{{expected expression}}
+ }
+};
+
+namespace PR9401 {
+ // From GCC PR c++/45558
+ template <typename S, typename T>
+ struct C
+ {
+ template <typename U>
+ struct B
+ {
+ template <typename W>
+ struct E
+ {
+ explicit E(const W &x) : w(x) {}
+ const W &w;
+ };
+ };
+ };
+
+ struct F;
+ template <typename X>
+ struct D
+ {
+ D() {}
+ };
+
+ const D<F> g;
+ template <typename S, typename T>
+ struct A
+ {
+ template <typename U>
+ struct B : C<S, T>::template B<U>
+ {
+ typedef typename C<S, T>::template B<U> V;
+ static const D<typename V::template E<D<F> > > a;
+ };
+ };
+
+ template <typename S, typename T>
+ template <typename U>
+ const D<typename C<S, T>::template B<U>::template E<D<F> > >
+ A<S, T>::B<U>::a = typename C<S, T>::template B<U>::template E<D<F> >(g);
+}
diff --git a/clang/test/SemaTemplate/dependent-type-identity.cpp b/clang/test/SemaTemplate/dependent-type-identity.cpp
new file mode 100644
index 0000000..731013c
--- /dev/null
+++ b/clang/test/SemaTemplate/dependent-type-identity.cpp
@@ -0,0 +1,100 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This test concerns the identity of dependent types within the
+// canonical type system. This corresponds to C++ [temp.type], which
+// specifies type equivalence within a template.
+//
+// FIXME: template template parameters
+
+namespace N {
+ template<typename T>
+ struct X2 {
+ template<typename U>
+ struct apply {
+ typedef U* type;
+ };
+ };
+}
+
+namespace Nalias = N;
+
+template<typename T>
+struct X0 { };
+
+using namespace N;
+
+template<typename T, typename U>
+struct X1 {
+ typedef T type;
+ typedef U U_type;
+
+ void f0(T); // expected-note{{previous}}
+ void f0(U);
+ void f0(type); // expected-error{{redeclar}}
+
+ void f1(T*); // expected-note{{previous}}
+ void f1(U*);
+ void f1(type*); // expected-error{{redeclar}}
+
+ void f2(X0<T>*); // expected-note{{previous}}
+ void f2(X0<U>*);
+ void f2(X0<type>*); // expected-error{{redeclar}}
+
+ void f3(X0<T>*); // expected-note{{previous}}
+ void f3(X0<U>*);
+ void f3(::X0<type>*); // expected-error{{redeclar}}
+
+ void f4(typename T::template apply<U>*); // expected-note{{previous}}
+ void f4(typename U::template apply<U>*);
+ void f4(typename type::template apply<T>*);
+ void f4(typename type::template apply<U_type>*); // expected-error{{redeclar}}
+
+ void f5(typename T::template apply<U>::type*); // expected-note{{previous}}
+ void f5(typename U::template apply<U>::type*);
+ void f5(typename U::template apply<T>::type*);
+ void f5(typename type::template apply<T>::type*);
+ void f5(typename type::template apply<U_type>::type*); // expected-error{{redeclar}}
+
+ void f6(typename N::X2<T>::template apply<U> *); // expected-note{{previous}}
+ void f6(typename N::X2<U>::template apply<U> *);
+ void f6(typename N::X2<U>::template apply<T> *);
+ void f6(typename ::N::X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
+
+ void f7(typename N::X2<T>::template apply<U> *); // expected-note{{previous}}
+ void f7(typename N::X2<U>::template apply<U> *);
+ void f7(typename N::X2<U>::template apply<T> *);
+ void f7(typename X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
+
+ void f8(typename N::X2<T>::template apply<U> *); // expected-note{{previous}}
+ void f8(typename N::X2<U>::template apply<U> *);
+ void f8(typename N::X2<U>::template apply<T> *);
+ void f8(typename ::Nalias::X2<type>::template apply<U_type> *); // expected-error{{redeclar}}
+};
+
+namespace PR6851 {
+ template <bool v>
+ struct S;
+
+ struct N {
+ template <bool w>
+ S< S<w>::cond && 1 > foo();
+ };
+
+ struct Alien;
+ bool operator&&(const Alien&, const Alien&);
+
+ template <bool w>
+ S< S<w>::cond && 1 > N::foo() { }
+}
+
+namespace PR7460 {
+ template <typename T>
+ struct TemplateClass2
+ {
+ enum { SIZE = 100 };
+ static T member[SIZE];
+ };
+
+ template <typename T>
+ T TemplateClass2<T>::member[TemplateClass2<T>::SIZE];
+}
diff --git a/clang/test/SemaTemplate/destructor-template.cpp b/clang/test/SemaTemplate/destructor-template.cpp
new file mode 100644
index 0000000..07beda4
--- /dev/null
+++ b/clang/test/SemaTemplate/destructor-template.cpp
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename A> class s0 {
+
+ template<typename B> class s1 : public s0<A> {
+ ~s1() {}
+ s0<A> ms0;
+ };
+
+};
+
+struct Incomplete;
+
+template<typename T>
+void destroy_me(T me) {
+ me.~T();
+}
+
+template void destroy_me(Incomplete*);
+
+namespace PR6152 {
+ template<typename T> struct X { void f(); };
+ template<typename T> struct Y { };
+ template<typename T>
+ void X<T>::f() {
+ Y<T> *y;
+ y->template Y<T>::~Y();
+ y->template Y<T>::~Y<T>();
+ y->~Y();
+ }
+
+ template struct X<int>;
+}
+
+namespace cvquals {
+ template<typename T>
+ void f(int *ptr) {
+ ptr->~T();
+ }
+
+ template void f<const volatile int>(int *);
+}
+
+namespace PR7239 {
+ template<class E> class A { };
+ class B {
+ void f() {
+ A<int>* x;
+ x->A<int>::~A<int>();
+ }
+ };
+}
+
+namespace PR7904 {
+ struct Foo {
+ template <int i> ~Foo() {} // expected-error{{destructor cannot be declared as a template}}
+ };
+ Foo f;
+}
diff --git a/clang/test/SemaTemplate/elaborated-type-specifier.cpp b/clang/test/SemaTemplate/elaborated-type-specifier.cpp
new file mode 100644
index 0000000..514c5f2
--- /dev/null
+++ b/clang/test/SemaTemplate/elaborated-type-specifier.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR6915 {
+ template <typename T>
+ class D {
+ enum T::X v; // expected-error{{use of 'X' with tag type that does not match previous declaration}} \
+ // expected-error{{no enum named 'X' in 'PR6915::D3'}}
+ };
+
+ struct D1 {
+ enum X { value };
+ };
+ struct D2 {
+ class X { }; // expected-note{{previous use is here}}
+ };
+ struct D3 { };
+
+ template class D<D1>;
+ template class D<D2>; // expected-note{{in instantiation of}}
+ template class D<D3>; // expected-note{{in instantiation of}}
+}
+
+template<typename T>
+struct DeclOrDef {
+ enum T::foo; // expected-error{{nested name specifier for a declaration cannot depend on a template parameter}}
+ enum T::bar { // expected-error{{nested name specifier for a declaration cannot depend on a template parameter}}
+ value
+ };
+};
+
+namespace PR6649 {
+ template <typename T> struct foo {
+ class T::bar; // expected-error{{nested name specifier for a declaration cannot depend on a template parameter}}
+ class T::bar { int x; }; // expected-error{{nested name specifier for a declaration cannot depend on a template parameter}}
+ };
+}
+
+namespace rdar8568507 {
+ template <class T> struct A *makeA(T t);
+}
diff --git a/clang/test/SemaTemplate/enum-argument.cpp b/clang/test/SemaTemplate/enum-argument.cpp
new file mode 100644
index 0000000..7d23757
--- /dev/null
+++ b/clang/test/SemaTemplate/enum-argument.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+enum Enum { val = 1 };
+template <Enum v> struct C {
+ typedef C<v> Self;
+};
+template struct C<val>;
+
+template<typename T>
+struct get_size {
+ static const unsigned value = sizeof(T);
+};
+
+template<typename T>
+struct X0 {
+ enum {
+ Val1 = get_size<T>::value,
+ Val2,
+ SumOfValues = Val1 + Val2
+ };
+};
+
+X0<int> x0i;
+
+namespace rdar8020920 {
+ template<typename T>
+ struct X {
+ enum { e0 = 32 };
+
+ unsigned long long bitfield : e0;
+
+ void f(int j) {
+ bitfield + j;
+ }
+ };
+}
diff --git a/clang/test/SemaTemplate/enum-forward.cpp b/clang/test/SemaTemplate/enum-forward.cpp
new file mode 100644
index 0000000..b25c21f
--- /dev/null
+++ b/clang/test/SemaTemplate/enum-forward.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -fms-compatibility %s
+
+template<typename T>
+struct X {
+ enum E *e;
+};
+
+X<int> xi;
diff --git a/clang/test/SemaTemplate/example-dynarray.cpp b/clang/test/SemaTemplate/example-dynarray.cpp
new file mode 100644
index 0000000..999521e
--- /dev/null
+++ b/clang/test/SemaTemplate/example-dynarray.cpp
@@ -0,0 +1,177 @@
+// RUN: %clangxx -emit-llvm -c -o - %s
+#include <stddef.h>
+#include <stdlib.h>
+#include <assert.h>
+
+// Placement new requires <new> to be included, but we don't support that yet.
+void* operator new(size_t, void* ptr) throw() {
+ return ptr;
+}
+void operator delete(void*, void*) throw() {
+}
+
+template<typename T>
+class dynarray {
+public:
+ dynarray() { Start = Last = End = 0; }
+
+ dynarray(const dynarray &other) {
+ Start = (T*)malloc(sizeof(T) * other.size());
+ Last = End = Start + other.size();
+
+ for (unsigned I = 0, N = other.size(); I != N; ++I)
+ new (Start + I) T(other[I]);
+ }
+
+ ~dynarray() {
+ for (unsigned I = 0, N = size(); I != N; ++I)
+ Start[I].~T();
+
+ free(Start);
+ }
+
+ dynarray &operator=(const dynarray &other) {
+ T* NewStart = (T*)malloc(sizeof(T) * other.size());
+
+ for (unsigned I = 0, N = other.size(); I != N; ++I)
+ new (NewStart + I) T(other[I]);
+
+ for (unsigned I = 0, N = size(); I != N; ++I)
+ Start[I].~T();
+
+ free(Start);
+ Start = NewStart;
+ Last = End = NewStart + other.size();
+ return *this;
+ }
+
+ unsigned size() const { return Last - Start; }
+ unsigned capacity() const { return End - Start; }
+
+ void push_back(const T& value);
+
+ void pop_back() {
+ --Last;
+ Last->~T();
+ }
+
+ T& operator[](unsigned Idx) {
+ return Start[Idx];
+ }
+
+ const T& operator[](unsigned Idx) const {
+ return Start[Idx];
+ }
+
+ typedef T* iterator;
+ typedef const T* const_iterator;
+
+ iterator begin() { return Start; }
+ const_iterator begin() const { return Start; }
+
+ iterator end() { return Last; }
+ const_iterator end() const { return Last; }
+
+ bool operator==(const dynarray &other) const {
+ if (size() != other.size())
+ return false;
+
+ for (unsigned I = 0, N = size(); I != N; ++I)
+ if ((*this)[I] != other[I])
+ return false;
+
+ return true;
+ }
+
+ bool operator!=(const dynarray &other) const {
+ return !(*this == other);
+ }
+
+public:
+ T* Start, *Last, *End;
+};
+
+template<typename T>
+void dynarray<T>::push_back(const T& value) {
+ if (Last == End) {
+ unsigned NewCapacity = capacity() * 2;
+ if (NewCapacity == 0)
+ NewCapacity = 4;
+
+ T* NewStart = (T*)malloc(sizeof(T) * NewCapacity);
+
+ unsigned Size = size();
+ for (unsigned I = 0; I != Size; ++I)
+ new (NewStart + I) T(Start[I]);
+
+ for (unsigned I = 0, N = size(); I != N; ++I)
+ Start[I].~T();
+ free(Start);
+
+ Start = NewStart;
+ Last = Start + Size;
+ End = Start + NewCapacity;
+ }
+
+ new (Last) T(value);
+ ++Last;
+}
+
+struct Point {
+ Point() { x = y = z = 0.0; }
+ Point(const Point& other) : x(other.x), y(other.y), z(other.z) { }
+
+ float x, y, z;
+};
+
+int main() {
+ dynarray<int> di;
+ di.push_back(0);
+ di.push_back(1);
+ di.push_back(2);
+ di.push_back(3);
+ di.push_back(4);
+ assert(di.size() == 5);
+ for (dynarray<int>::iterator I = di.begin(), IEnd = di.end(); I != IEnd; ++I)
+ assert(*I == I - di.begin());
+
+ for (int I = 0, N = di.size(); I != N; ++I)
+ assert(di[I] == I);
+
+ di.pop_back();
+ assert(di.size() == 4);
+ di.push_back(4);
+
+ dynarray<int> di2 = di;
+ assert(di2.size() == 5);
+ assert(di.begin() != di2.begin());
+ for (dynarray<int>::iterator I = di2.begin(), IEnd = di2.end();
+ I != IEnd; ++I)
+ assert(*I == I - di2.begin());
+
+ dynarray<int> di3(di);
+ assert(di3.size() == 5);
+ assert(di.begin() != di3.begin());
+ for (dynarray<int>::iterator I = di3.begin(), IEnd = di3.end();
+ I != IEnd; ++I)
+ assert(*I == I - di3.begin());
+
+ dynarray<int> di4;
+ assert(di4.size() == 0);
+ di4 = di;
+ assert(di4.size() == 5);
+ assert(di.begin() != di4.begin());
+ for (dynarray<int>::iterator I = di4.begin(), IEnd = di4.end();
+ I != IEnd; ++I)
+ assert(*I == I - di4.begin());
+
+ assert(di4 == di);
+ di4[3] = 17;
+ assert(di4 != di);
+
+ dynarray<Point> dp;
+ dp.push_back(Point());
+ assert(dp.size() == 1);
+
+ return 0;
+}
diff --git a/clang/test/SemaTemplate/example-typelist.cpp b/clang/test/SemaTemplate/example-typelist.cpp
new file mode 100644
index 0000000..082aeb8
--- /dev/null
+++ b/clang/test/SemaTemplate/example-typelist.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// A simple cons-style typelist
+struct nil { };
+
+template<typename Head, typename Tail = nil>
+struct cons {
+ typedef Head head;
+ typedef Tail tail;
+};
+
+// is_same trait, for testing
+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;
+};
+
+// metaprogram that computes the length of a list
+template<typename T> struct length;
+
+template<typename Head, typename Tail>
+struct length<cons<Head, Tail> > {
+ static const unsigned value = length<Tail>::value + 1;
+};
+
+template<>
+struct length<nil> {
+ static const unsigned value = 0;
+};
+
+typedef cons<unsigned char,
+ cons<unsigned short,
+ cons<unsigned int,
+ cons<unsigned long> > > > unsigned_inttypes;
+int length0[length<unsigned_inttypes>::value == 4? 1 : -1];
+
+// metaprogram that reverses a list
+
+// FIXME: I would prefer that this be a partial specialization, but
+// that requires partial ordering of class template partial
+// specializations.
+template<typename T>
+class reverse {
+ typedef typename reverse<typename T::tail>::type reversed_tail;
+
+ typedef typename reverse<typename reversed_tail::tail>::type most_of_tail;
+
+public:
+ typedef cons<typename reversed_tail::head,
+ typename reverse<cons<typename T::head, most_of_tail> >::type> type;
+};
+
+template<typename Head>
+class reverse<cons<Head> > {
+public:
+ typedef cons<Head> type;
+};
+
+template<>
+class reverse<nil> {
+public:
+ typedef nil type;
+};
+
+int reverse0[is_same<reverse<unsigned_inttypes>::type,
+ cons<unsigned long,
+ cons<unsigned int,
+ cons<unsigned short,
+ cons<unsigned char> > > > >::value? 1 : -1];
+
+// metaprogram that finds a type within a list
+
+// FIXME: I would prefer that this be a partial specialization, but
+// that requires partial ordering of class template partial
+// specializations.
+template<typename List, typename T>
+struct find : find<typename List::tail, T> { };
+
+template<typename Tail, typename T>
+struct find<cons<T, Tail>, T> {
+ typedef cons<T, Tail> type;
+};
+
+template<typename T>
+struct find<nil, T> {
+ typedef nil type;
+};
+
+int find0[is_same<find<unsigned_inttypes, unsigned int>::type,
+ cons<unsigned int, cons<unsigned long> > >::value?
+ 1 : -1];
+int find1[is_same<find<unsigned_inttypes, int>::type, nil>::value? 1 : -1];
+
diff --git a/clang/test/SemaTemplate/explicit-instantiation.cpp b/clang/test/SemaTemplate/explicit-instantiation.cpp
new file mode 100644
index 0000000..13d76be
--- /dev/null
+++ b/clang/test/SemaTemplate/explicit-instantiation.cpp
@@ -0,0 +1,107 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template void *; // expected-error{{expected unqualified-id}}
+
+template typedef void f0; // expected-error{{explicit instantiation of typedef}}
+
+int v0; // expected-note{{refers here}}
+template int v0; // expected-error{{does not refer}}
+
+template<typename T>
+struct X0 {
+ static T value;
+
+ T f0(T x) {
+ return x + 1; // expected-error{{invalid operands}}
+ }
+ T* f0(T*, T*) { return T(); }
+
+ template<typename U>
+ T f0(T, U) { return T(); }
+};
+
+template<typename T>
+T X0<T>::value; // expected-error{{no matching constructor}}
+
+template int X0<int>::value;
+
+struct NotDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor)}}
+ NotDefaultConstructible(int); // expected-note{{candidate constructor}}
+};
+
+template NotDefaultConstructible X0<NotDefaultConstructible>::value; // expected-note{{instantiation}}
+
+template int X0<int>::f0(int);
+template int* X0<int>::f0(int*, int*);
+template int X0<int>::f0(int, float);
+
+template int X0<int>::f0(int) const; // expected-error{{does not refer}}
+template int* X0<int>::f0(int*, float*); // expected-error{{does not refer}}
+
+struct X1 { };
+typedef int X1::*MemPtr;
+
+template MemPtr X0<MemPtr>::f0(MemPtr); // expected-note{{requested here}}
+
+struct X2 {
+ int f0(int); // expected-note{{refers here}}
+
+ template<typename T> T f1(T) { return T(); }
+ template<typename T> T* f1(T*) { return 0; }
+
+ template<typename T, typename U> void f2(T, U*) { } // expected-note{{candidate}}
+ template<typename T, typename U> void f2(T*, U) { } // expected-note{{candidate}}
+};
+
+template int X2::f0(int); // expected-error{{not an instantiation}}
+
+template int *X2::f1(int *); // okay
+
+template void X2::f2(int *, int *); // expected-error{{ambiguous}}
+
+
+template<typename T> void print_type() { }
+
+template void print_type<int>();
+template void print_type<float>();
+
+template<typename T> void print_type(T*) { }
+
+template void print_type(int*);
+template void print_type<int>(float*); // expected-error{{does not refer}}
+
+void print_type(double*);
+template void print_type<double>(double*);
+
+// PR5069
+template<int I> void foo0 (int (&)[I + 1]) { }
+template void foo0<2> (int (&)[3]);
+
+namespace explicit_instantiation_after_implicit_instantiation {
+ template <int I> struct X0 { static int x; };
+ template <int I> int X0<I>::x;
+ void test1() { (void)&X0<1>::x; }
+ template struct X0<1>;
+}
+
+template<typename> struct X3 { };
+inline template struct X3<int>; // expected-warning{{ignoring 'inline' keyword on explicit template instantiation}}
+static template struct X3<float>; // expected-warning{{ignoring 'static' keyword on explicit template instantiation}}
+
+namespace PR7622 {
+ template<typename,typename=int>
+ struct basic_streambuf;
+
+ template<typename,typename>
+ struct basic_streambuf{friend bob<>()}; // expected-error{{unknown type name 'bob'}} \
+ // expected-error{{expected member name or ';' after declaration specifiers}}
+ template struct basic_streambuf<int>;
+}
+
+// Test that we do not crash.
+class TC1 {
+ class TC2 {
+ template // FIXME: error here.
+ void foo() { }
+ };
+};
diff --git a/clang/test/SemaTemplate/explicit-specialization-member.cpp b/clang/test/SemaTemplate/explicit-specialization-member.cpp
new file mode 100644
index 0000000..7fe6bf3
--- /dev/null
+++ b/clang/test/SemaTemplate/explicit-specialization-member.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct X0 {
+ typedef T* type;
+
+ void f0(T);
+ void f1(type);
+};
+
+template<> void X0<char>::f0(char);
+template<> void X0<char>::f1(type);
+
+namespace PR6161 {
+ template<typename _CharT>
+ class numpunct : public locale::facet // expected-error{{use of undeclared identifier 'locale'}} \
+ // expected-error{{expected class name}}
+ {
+ static locale::id id; // expected-error{{use of undeclared identifier}}
+ };
+ numpunct<char>::~numpunct(); // expected-error{{expected the class name after '~' to name a destructor}}
+}
diff --git a/clang/test/SemaTemplate/ext-vector-type.cpp b/clang/test/SemaTemplate/ext-vector-type.cpp
new file mode 100644
index 0000000..f968c13
--- /dev/null
+++ b/clang/test/SemaTemplate/ext-vector-type.cpp
@@ -0,0 +1,94 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, unsigned Length>
+struct make1 {
+ typedef T __attribute__((ext_vector_type(Length))) type;
+};
+
+void test_make1() {
+ make1<int, 5>::type x;
+ x.x = 4;
+}
+
+template<typename T, unsigned Length>
+struct make2 {
+ typedef T __attribute__((ext_vector_type(Length))) type; // expected-error{{zero vector size}}
+};
+
+int test_make2() {
+ make2<int, 0> x; // expected-note{{in instantiation of}}
+}
+
+template<typename T, unsigned Length>
+struct make3 {
+ typedef T __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector element type 's'}}
+};
+
+struct s {};
+
+int test_make3() {
+ make3<s, 3>x; // expected-note{{in instantiation of}}
+}
+
+template<typename T, T Length>
+struct make4 {
+ typedef T __attribute__((ext_vector_type(Length))) type;
+};
+
+int test_make4() {
+ make4<int, 4>::type x;
+ x.w = 7;
+}
+
+typedef int* int_ptr;
+template<unsigned Length>
+struct make5 {
+ typedef int_ptr __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector element type}}
+};
+
+template<int Length>
+struct make6 {
+ typedef int __attribute__((ext_vector_type(Length))) type;
+};
+
+int test_make6() {
+ make6<4>::type x;
+ x.w = 7;
+
+ make6<2>::type y;
+ y.x = -1;
+ y.w = -1; // expected-error{{vector component access exceeds type}}
+}
+
+namespace Deduction {
+ template<typename T> struct X0;
+
+ template<typename T, unsigned N>
+ struct X0<T __attribute__((ext_vector_type(N)))> {
+ static const unsigned value = 0;
+ };
+
+ template<typename T>
+ struct X0<T __attribute__((ext_vector_type(4)))> {
+ static const unsigned value = 1;
+ };
+
+ template<unsigned N>
+ struct X0<float __attribute__((ext_vector_type(N)))> {
+ static const unsigned value = 2;
+ };
+
+ template<>
+ struct X0<float __attribute__((ext_vector_type(4)))> {
+ static const unsigned value = 3;
+ };
+
+ typedef int __attribute__((ext_vector_type(2))) int2;
+ typedef int __attribute__((ext_vector_type(4))) int4;
+ typedef float __attribute__((ext_vector_type(2))) float2;
+ typedef float __attribute__((ext_vector_type(4))) float4;
+
+ int array0[X0<int2>::value == 0? 1 : -1];
+ int array1[X0<int4>::value == 1? 1 : -1];
+ int array2[X0<float2>::value == 2? 1 : -1];
+ int array3[X0<float4>::value == 3? 1 : -1];
+}
diff --git a/clang/test/SemaTemplate/extern-templates.cpp b/clang/test/SemaTemplate/extern-templates.cpp
new file mode 100644
index 0000000..eca64ed
--- /dev/null
+++ b/clang/test/SemaTemplate/extern-templates.cpp
@@ -0,0 +1,64 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+class X0 {
+public:
+ void f(T t);
+
+ struct Inner {
+ void g(T t);
+ };
+};
+
+template<typename T>
+void X0<T>::f(T t) {
+ t = 17; // expected-error{{incompatible}}
+}
+
+extern template class X0<int>;
+
+extern template class X0<int*>;
+
+template<typename T>
+void X0<T>::Inner::g(T t) {
+ t = 17; // expected-error{{incompatible}}
+}
+
+void test_intptr(X0<int*> xi, X0<int*>::Inner xii) {
+ xi.f(0);
+ xii.g(0);
+}
+
+extern template class X0<long*>;
+
+void test_longptr(X0<long*> xl, X0<long*>::Inner xli) {
+ xl.f(0);
+ xli.g(0);
+}
+
+template class X0<long*>; // expected-note 2{{instantiation}}
+
+template<typename T>
+class X1 {
+public:
+ void f(T t) { t += 2; }
+
+ void g(T t);
+};
+
+template<typename T>
+void X1<T>::g(T t) {
+ t += 2;
+}
+
+extern template class X1<void*>;
+
+void g_X1(X1<void*> x1, void *ptr) {
+ x1.g(ptr);
+}
+
+extern template void X1<const void*>::g(const void*);
+
+void g_X1_2(X1<const void *> x1, const void *ptr) {
+ x1.g(ptr);
+}
diff --git a/clang/test/SemaTemplate/fibonacci.cpp b/clang/test/SemaTemplate/fibonacci.cpp
new file mode 100644
index 0000000..ff1711f
--- /dev/null
+++ b/clang/test/SemaTemplate/fibonacci.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<unsigned I>
+struct FibonacciEval;
+
+template<unsigned I>
+struct Fibonacci {
+ enum { value = FibonacciEval<I-1>::value + FibonacciEval<I-2>::value };
+};
+
+template<unsigned I>
+struct FibonacciEval {
+ enum { value = Fibonacci<I>::value };
+};
+
+template<> struct Fibonacci<0> {
+ enum { value = 0 };
+};
+
+template<> struct Fibonacci<1> {
+ enum { value = 1 };
+};
+
+int array5[Fibonacci<5>::value == 5? 1 : -1];
+int array10[Fibonacci<10>::value == 55? 1 : -1];
+
+template<unsigned I>
+struct FibonacciEval2;
+
+template<unsigned I>
+struct Fibonacci2 {
+ static const unsigned value
+ = FibonacciEval2<I-1>::value + FibonacciEval2<I-2>::value;
+};
+
+template<unsigned I>
+struct FibonacciEval2 {
+ static const unsigned value = Fibonacci2<I>::value;
+};
+
+template<> struct Fibonacci2<0> {
+ static const unsigned value = 0;
+};
+
+template<> struct Fibonacci2<1> {
+ static const unsigned value = 1;
+};
+
+int array5_2[Fibonacci2<5>::value == 5? 1 : -1];
+int array10_2[Fibonacci2<10>::value == 55? 1 : -1];
+
+template<unsigned I>
+struct Fibonacci3 {
+ static const unsigned value = Fibonacci3<I-1>::value + Fibonacci3<I-2>::value;
+};
+
+template<> struct Fibonacci3<0> {
+ static const unsigned value = 0;
+};
+
+template<> struct Fibonacci3<1> {
+ static const unsigned value = 1;
+};
+
+int array5_3[Fibonacci3<5>::value == 5? 1 : -1];
+int array10_3[Fibonacci3<10>::value == 55? 1 : -1];
diff --git a/clang/test/SemaTemplate/friend-template.cpp b/clang/test/SemaTemplate/friend-template.cpp
new file mode 100644
index 0000000..9c95fa0
--- /dev/null
+++ b/clang/test/SemaTemplate/friend-template.cpp
@@ -0,0 +1,245 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR5057
+namespace test0 {
+ namespace std {
+ class X {
+ public:
+ template<typename T> friend struct Y;
+ };
+ }
+
+ namespace std {
+ template<typename T> struct Y {};
+ }
+}
+
+namespace test1 {
+ template<typename T> void f1(T) { } // expected-note{{here}}
+
+ class X {
+ template<typename T> friend void f0(T);
+ template<typename T> friend void f1(T);
+ };
+
+ template<typename T> void f0(T) { }
+ template<typename T> void f1(T) { } // expected-error{{redefinition}}
+}
+
+// PR4768
+namespace test2 {
+ template<typename T> struct X0 {
+ template<typename U> friend struct X0;
+ };
+
+ template<typename T> struct X0<T*> {
+ template<typename U> friend struct X0;
+ };
+
+ template<> struct X0<int> {
+ template<typename U> friend struct X0;
+ };
+
+ template<typename T> struct X1 {
+ template<typename U> friend void f2(U);
+ template<typename U> friend void f3(U);
+ };
+
+ template<typename U> void f2(U);
+
+ X1<int> x1i;
+ X0<int*> x0ip;
+
+ template<> void f2(int);
+
+ // FIXME: Should this declaration of f3 be required for the specialization of
+ // f3<int> (further below) to work? GCC and EDG don't require it, we do...
+ template<typename U> void f3(U);
+
+ template<> void f3(int);
+}
+
+// PR5332
+namespace test3 {
+ template <typename T> class Foo {
+ template <typename U>
+ friend class Foo;
+ };
+
+ Foo<int> foo;
+
+ template<typename T, T Value> struct X2a;
+
+ template<typename T, int Size> struct X2b;
+
+ template<typename T>
+ class X3 {
+ template<typename U, U Value> friend struct X2a;
+
+ // FIXME: the redeclaration note ends up here because redeclaration
+ // lookup ends up finding the friend target from X3<int>.
+ template<typename U, T Value> friend struct X2b; // expected-error {{template non-type parameter has a different type 'long' in template redeclaration}} \
+ // expected-note {{previous non-type template parameter with type 'int' is here}}
+ };
+
+ X3<int> x3i; // okay
+
+ X3<long> x3l; // expected-note {{in instantiation}}
+}
+
+// PR5716
+namespace test4 {
+ template<typename> struct A {
+ template<typename T> friend void f(const A<T>&);
+ };
+
+ template<typename T> void f(const A<T>&) {
+ int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}}
+ }
+
+ void f() {
+ f(A<int>()); // expected-note {{in instantiation of function template specialization}}
+ }
+}
+
+namespace test5 {
+ class outer {
+ class foo;
+ template <typename T> friend struct cache;
+ };
+ class outer::foo {
+ template <typename T> friend struct cache;
+ };
+}
+
+// PR6022
+namespace PR6022 {
+ template <class T1, class T2 , class T3 > class A;
+
+ namespace inner {
+ template<class T1, class T2, class T3, class T>
+ A<T1, T2, T3>& f0(A<T1, T2, T3>&, T);
+ }
+
+ template<class T1, class T2, class T3>
+ class A {
+ template<class U1, class U2, class U3, class T>
+ friend A<U1, U2, U3>& inner::f0(A<U1, U2, U3>&, T);
+ };
+}
+
+namespace FriendTemplateDefinition {
+ template<unsigned > struct int_c { };
+
+ template<typename T>
+ struct X {
+ template<unsigned N>
+ friend void f(X, int_c<N>) {
+ int value = N;
+ };
+ };
+
+ void test_X(X<int> x, int_c<5> i5) {
+ f(x, i5);
+ }
+}
+
+namespace PR7013a {
+ template<class > struct X0
+ {
+ typedef int type;
+ };
+ template<typename > struct X1
+ {
+ };
+ template<typename , typename T> struct X2
+ {
+ typename T::type e;
+ };
+ namespace N
+ {
+ template <typename = int, typename = X1<int> > struct X3
+ {
+ template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
+ };
+ template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
+ {
+ X2<int, Tr> s;
+ }
+ }
+ int n()
+ {
+ X2<int, X0<int> > ngs;
+ N::X3<> b;
+ op(ngs, b);
+ return 0;
+ }
+}
+
+namespace PR7013b {
+ template<class > struct X0
+ {
+ typedef int type;
+ };
+ template<typename > struct X1
+ {
+ };
+ template<typename , typename T> struct X2
+ {
+ typename T::type e;
+ };
+ namespace N
+ {
+ template <typename = X1<int> > struct X3
+ {
+ template <typename T1, typename T2, typename B> friend void op(X2<T1, T2>& , B);
+ };
+ template <typename Ch, typename Tr, typename B> void op(X2<Ch, Tr>& , B)
+ {
+ X2<int, Tr> s;
+ }
+ }
+ int n()
+ {
+ X2<int, X0<int> > ngs;
+ N::X3<> b;
+ op(ngs, b);
+ return 0;
+ }
+
+}
+
+namespace PR8649 {
+ template<typename T, typename U, unsigned N>
+ struct X {
+ template<unsigned M> friend class X<T, U, M>; // expected-error{{partial specialization cannot be declared as a friend}}
+ };
+
+ X<int, float, 7> x;
+}
+
+// Don't crash, and error on invalid friend type template.
+namespace friend_type_template_no_tag {
+ template <typename T> struct S {
+ template <typename U> friend S<U>; // expected-error{{friend type templates must use an elaborated type}}
+ };
+ template struct S<int>;
+}
+
+namespace PR10660 {
+ struct A {
+ template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}}
+ };
+}
+
+namespace rdar11147355 {
+ template <class T>
+ struct A {
+ template <class U> class B;
+ template <class S> template <class U> friend class A<S>::B;
+ };
+
+ template <class S> template <class U> class A<S>::B {
+ };
+
+ A<double>::B<double> ab;
+}
diff --git a/clang/test/SemaTemplate/friend.cpp b/clang/test/SemaTemplate/friend.cpp
new file mode 100644
index 0000000..e78a067
--- /dev/null
+++ b/clang/test/SemaTemplate/friend.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T> struct A {
+ struct B { };
+
+ friend struct B;
+};
+
+void f() {
+ A<int>::B b;
+}
+
+struct C0 {
+ friend struct A<int>;
+};
+
+namespace PR6770 {
+ namespace N {
+ int f1(int);
+ }
+ using namespace N;
+
+ namespace M {
+ float f1(float);
+ }
+ using M::f1;
+
+ template<typename T> void f1(T, T);
+ template <class T>
+ void f() {
+ friend class f; // expected-error{{'friend' used outside of class}}
+ friend class f1; // expected-error{{'friend' used outside of class}}
+ }
+}
diff --git a/clang/test/SemaTemplate/fun-template-def.cpp b/clang/test/SemaTemplate/fun-template-def.cpp
new file mode 100644
index 0000000..0427781
--- /dev/null
+++ b/clang/test/SemaTemplate/fun-template-def.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Tests that dependent expressions are always allowed, whereas non-dependent
+// are checked as usual.
+
+#include <stddef.h>
+
+// Fake typeid, lacking a typeinfo header.
+namespace std { class type_info {}; }
+
+struct dummy {}; // expected-note 3 {{candidate constructor (the implicit copy constructor)}}
+
+template<typename T>
+int f0(T x) {
+ return (sizeof(x) == sizeof(int))? 0 : (sizeof(x) == sizeof(double))? 1 : 2;
+}
+
+template <typename T, typename U>
+T f1(T t1, U u1, int i1)
+{
+ T t2 = i1;
+ t2 = i1 + u1;
+ ++u1;
+ u1++;
+ int i2 = u1;
+
+ i1 = t1[u1];
+ i1 *= t1;
+
+ i1(u1, t1); // error
+ u1(i1, t1);
+
+ U u2 = (T)i1;
+ static_cast<void>(static_cast<U>(reinterpret_cast<T>(
+ dynamic_cast<U>(const_cast<T>(i1)))));
+
+ new U(i1, t1);
+ new int(t1, u1);
+ new (t1, u1) int;
+ delete t1;
+
+ dummy d1 = sizeof(t1); // expected-error {{no viable conversion}}
+ dummy d2 = offsetof(T, foo); // expected-error {{no viable conversion}}
+ dummy d3 = __alignof(u1); // expected-error {{no viable conversion}}
+ i1 = typeid(t1); // expected-error {{assigning to 'int' from incompatible type 'const std::type_info'}}
+
+ return u1;
+}
diff --git a/clang/test/SemaTemplate/function-template-specialization.cpp b/clang/test/SemaTemplate/function-template-specialization.cpp
new file mode 100644
index 0000000..a0d41b2
--- /dev/null
+++ b/clang/test/SemaTemplate/function-template-specialization.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<int N> void f0(int (&array)[N]);
+
+// Simple function template specialization (using overloading)
+template<> void f0(int (&array)[1]);
+
+void test_f0() {
+ int iarr1[1];
+ f0(iarr1);
+}
+
+// Function template specialization where there are no matches
+template<> void f0(char (&array)[1]); // expected-error{{no function template matches}}
+template<> void f0<2>(int (&array)[2]) { }
+
+// Function template specialization that requires partial ordering
+template<typename T, int N> void f1(T (&array)[N]); // expected-note{{matches}}
+template<int N> void f1(int (&array)[N]); // expected-note{{matches}}
+
+template<> void f1(float (&array)[1]);
+template<> void f1(int (&array)[1]);
+
+// Function template specialization that results in an ambiguity
+template<typename T> void f1(T (&array)[17]); // expected-note{{matches}}
+template<> void f1(int (&array)[17]); // expected-error{{ambiguous}}
+
+// Resolving that ambiguity with explicitly-specified template arguments.
+template<int N> void f2(double (&array)[N]);
+template<typename T> void f2(T (&array)[42]);
+
+template<> void f2<double>(double (&array)[42]);
+template<> void f2<42>(double (&array)[42]);
+
+void f2<25>(double (&array)[25]); // expected-error{{specialization}}
+
+// PR5833
+namespace PR5833 {
+ template <typename T> bool f0(T &t1);
+ template <> bool f0<float>(float &t1);
+}
+template <> bool PR5833::f0<float>(float &t1) {}
+
+// PR8295
+namespace PR8295 {
+ template <typename T> void f(T t) {}
+ template <typename T> void f<T*>(T* t) {} // expected-error{{function template partial specialization is not allowed}}
+}
diff --git a/clang/test/SemaTemplate/implicit-instantiation-1.cpp b/clang/test/SemaTemplate/implicit-instantiation-1.cpp
new file mode 100644
index 0000000..d1bc5a8
--- /dev/null
+++ b/clang/test/SemaTemplate/implicit-instantiation-1.cpp
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U>
+struct X {
+ T f(T x, U y) { return x + y; }
+
+ unsigned g(T x, U y) { return sizeof(f(x, y)); }
+};
+
+void test(X<int, int> *xii, X<int*, int> *xpi, X<int, int*> *xip) {
+ (void)xii->f(1, 2);
+ (void)xpi->f(0, 2);
+ (void)sizeof(xip->f(2, 0)); // okay: does not instantiate
+ (void)xip->g(2, 0); // okay: does not instantiate
+}
+
+template<typename T, typename U>
+T add(T t, U u) {
+ return t + u; // expected-error{{invalid operands}}
+}
+
+void test_add(char *cp, int i, int *ip) {
+ char* cp2 = add(cp, i);
+ add(cp, cp); // expected-note{{instantiation of}}
+ (void)sizeof(add(ip, ip));
+}
diff --git a/clang/test/SemaTemplate/inject-templated-friend-post.cpp b/clang/test/SemaTemplate/inject-templated-friend-post.cpp
new file mode 100644
index 0000000..39c445c
--- /dev/null
+++ b/clang/test/SemaTemplate/inject-templated-friend-post.cpp
@@ -0,0 +1,72 @@
+// RUN: %clang %s -S -emit-llvm -o - | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
+// RUN: %clang %s -S -emit-llvm -o - -DPROTOTYPE | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
+// RUN: %clang %s -S -emit-llvm -o - -DINSTANTIATE | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
+// RUN: %clang %s -S -emit-llvm -o - -DPROTOTYPE -DINSTANTIATE | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
+// RUN: %clang_cc1 %s -DREDEFINE -verify
+// RUN: %clang_cc1 %s -DPROTOTYPE -DREDEFINE -verify
+// PR8007: friend function not instantiated, reordered version.
+// Corresponds to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38392
+
+struct std_ostream
+{
+ int dummy;
+};
+
+std_ostream cout;
+
+template <typename STRUCT_TYPE>
+struct Streamer;
+
+typedef struct Foo {} Foo;
+
+std_ostream& operator << (std_ostream&, const Streamer<Foo>&);
+
+void test(const Streamer<Foo>& foo)
+{
+ cout << foo;
+}
+
+template <typename STRUCT_TYPE>
+struct Streamer
+{
+ friend std_ostream& operator << (std_ostream& o, const Streamer& f) // expected-error{{redefinition of 'operator<<'}}
+ {
+ Streamer s(f);
+ s(o);
+ return o;
+ }
+
+ Streamer(const STRUCT_TYPE& s) : s(s) {}
+
+ const STRUCT_TYPE& s;
+ void operator () (std_ostream&) const;
+};
+
+#ifdef PROTOTYPE
+std_ostream& operator << (std_ostream&, const Streamer<Foo>&);
+#endif
+
+#ifdef INSTANTIATE
+template struct Streamer<Foo>;
+#endif
+
+#ifdef REDEFINE
+std_ostream& operator << (std_ostream& o, const Streamer<Foo>&) // expected-note{{is here}}
+{
+ return o;
+}
+#endif
+
+#ifndef INSTANTIATE
+template <>
+void Streamer<Foo>::operator () (std_ostream& o) const // expected-note{{requested here}}
+{
+}
+#endif
+
+int main(void)
+{
+ Foo foo;
+ test(foo);
+}
+
diff --git a/clang/test/SemaTemplate/inject-templated-friend.cpp b/clang/test/SemaTemplate/inject-templated-friend.cpp
new file mode 100644
index 0000000..7be613b
--- /dev/null
+++ b/clang/test/SemaTemplate/inject-templated-friend.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang %s -S -emit-llvm -o - | grep -e "define linkonce_odr.*_ZlsR11std_ostreamRK8StreamerI3FooE"
+// RUN: %clang_cc1 %s -DREDEFINE -verify
+// PR8007: friend function not instantiated.
+
+struct std_ostream
+{
+ int dummy;
+};
+
+std_ostream cout;
+
+template <typename STRUCT_TYPE>
+struct Streamer
+{
+ friend std_ostream& operator << (std_ostream& o, const Streamer& f) // expected-error{{redefinition of 'operator<<'}}
+ {
+ Streamer s(f);
+ s(o);
+ return o;
+ }
+
+ Streamer(const STRUCT_TYPE& s) : s(s) {}
+
+ const STRUCT_TYPE& s;
+ void operator () (std_ostream&) const;
+};
+
+typedef struct Foo {} Foo;
+
+std_ostream& operator << (std_ostream&, const Streamer<Foo>&);
+#ifdef REDEFINE
+std_ostream& operator << (std_ostream& o, const Streamer<Foo>&) // expected-note{{is here}}
+{
+ // Sema should flag this as a redefinition
+ return o;
+}
+#endif
+
+template <>
+void Streamer<Foo>::operator () (std_ostream& o) const // expected-note{{requested here}}
+{
+}
+
+int main(void)
+{
+ Foo foo;
+ cout << foo;
+}
diff --git a/clang/test/SemaTemplate/injected-class-name.cpp b/clang/test/SemaTemplate/injected-class-name.cpp
new file mode 100644
index 0000000..4c21d25
--- /dev/null
+++ b/clang/test/SemaTemplate/injected-class-name.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct X {
+ X<T*> *ptr;
+};
+
+X<int> x;
+
+template<>
+struct X<int***> {
+ typedef X<int***> *ptr;
+};
+
+X<float>::X<int> xi = x; // expected-error{{qualified reference to 'X' is a constructor name rather than a template name wherever a constructor can be declared}}
+
+// [temp.local]p1:
+
+// FIXME: test template template parameters
+template<typename T, typename U>
+struct X0 {
+ typedef T type;
+ typedef U U_type;
+ typedef U_type U_type2;
+
+ void f0(const X0&); // expected-note{{here}}
+ void f0(X0&);
+ void f0(const X0<T, U>&); // expected-error{{redecl}}
+
+ void f1(const X0&); // expected-note{{here}}
+ void f1(X0&);
+ void f1(const X0<type, U_type2>&); // expected-error{{redecl}}
+
+ void f2(const X0&); // expected-note{{here}}
+ void f2(X0&);
+ void f2(const ::X0<type, U_type2>&); // expected-error{{redecl}}
+};
+
+template<typename T, T N>
+struct X1 {
+ void f0(const X1&); // expected-note{{here}}
+ void f0(X1&);
+ void f0(const X1<T, N>&); // expected-error{{redecl}}
+};
+
+namespace pr6326 {
+ template <class T> class A {
+ friend class A;
+ };
+ template class A<int>;
+}
+
+namespace ForwardDecls {
+ template<typename T>
+ struct X;
+
+ template<typename T>
+ struct X {
+ typedef T foo;
+ typedef X<T> xt;
+ typename xt::foo *t;
+ };
+}
diff --git a/clang/test/SemaTemplate/instantiate-anonymous-union.cpp b/clang/test/SemaTemplate/instantiate-anonymous-union.cpp
new file mode 100644
index 0000000..68b233a
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-anonymous-union.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -fsyntax-only %s -Wall
+
+template <typename T> class A { struct { }; };
+
+A<int> a0;
+
+template <typename T> struct B {
+ union {
+ int a;
+ void* b;
+ };
+
+ void f() {
+ a = 10;
+ b = 0;
+ }
+};
+
+B<int> b0;
+
+template <typename T> struct C {
+ union {
+ int a;
+ void* b;
+ };
+
+ C(int a) : a(a) { }
+ C(void* b) : b(b) { }
+};
+
+C<int> c0(0);
+
+namespace PR7088 {
+ template<typename T>
+ void f() {
+ union {
+ int a;
+ union {
+ float real;
+ T d;
+ };
+ };
+
+ a = 17;
+ d = 3.14;
+ }
+
+ template void f<double>();
+}
+
+// Check for problems related to PR7402 that occur when template instantiation
+// instantiates implicit initializers.
+namespace PR7402 {
+ struct X {
+ union {
+ struct {
+ int x;
+ int y;
+ };
+ int v[2];
+ };
+
+ // Check that this requirement survives instantiation.
+ template <typename T> X(const T& t) : x(t), y(t) {}
+ };
+
+ X x(42.0);
+}
+
+namespace PR9188 {
+ struct X0 {
+ union {
+ int member;
+ };
+ };
+
+ static union {
+ int global;
+ };
+
+ struct X1 : X0 {
+ template<typename T>
+ int f() {
+ return this->X0::member + PR9188::global;
+ }
+ };
+
+ template int X1::f<int>();
+}
diff --git a/clang/test/SemaTemplate/instantiate-array.cpp b/clang/test/SemaTemplate/instantiate-array.cpp
new file mode 100644
index 0000000..b8229d3
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-array.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++11
+
+#ifndef __GXX_EXPERIMENTAL_CXX0X__
+#define __CONCAT(__X, __Y) __CONCAT1(__X, __Y)
+#define __CONCAT1(__X, __Y) __X ## __Y
+
+#define static_assert(__b, __m) \
+ typedef int __CONCAT(__sa, __LINE__)[__b ? 1 : -1]
+#endif
+
+template <int N> class IntArray {
+ int elems[N];
+};
+
+static_assert(sizeof(IntArray<10>) == sizeof(int) * 10, "Array size mismatch");
+static_assert(sizeof(IntArray<1>) == sizeof(int) * 1, "Array size mismatch");
+
+template <typename T> class TenElementArray {
+ int elems[10];
+};
+
+static_assert(sizeof(TenElementArray<int>) == sizeof(int) * 10, "Array size mismatch");
+
+template<typename T, int N> class Array {
+ T elems[N];
+};
+
+static_assert(sizeof(Array<int, 10>) == sizeof(int) * 10, "Array size mismatch");
diff --git a/clang/test/SemaTemplate/instantiate-attr.cpp b/clang/test/SemaTemplate/instantiate-attr.cpp
new file mode 100644
index 0000000..bbadb63
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-attr.cpp
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template <typename T>
+struct A {
+ char a __attribute__((aligned(16)));
+
+ struct B {
+ typedef T __attribute__((aligned(16))) i16;
+ i16 x;
+ };
+};
+int a[sizeof(A<int>) == 16 ? 1 : -1];
+int a2[sizeof(A<int>::B) == 16 ? 1 : -1];
+
+// rdar://problem/8243419
+namespace test1 {
+ template <typename T> struct A {
+ int a;
+ T b[0];
+ } __attribute__((packed));
+
+ typedef A<unsigned long> type;
+
+ int test0[sizeof(type) == 4 ? 1 : -1];
+ int test1[__builtin_offsetof(type, a) == 0 ? 1 : -1];
+ int test2[__builtin_offsetof(type, b) == 4 ? 1 : -1];
+}
diff --git a/clang/test/SemaTemplate/instantiate-c99.cpp b/clang/test/SemaTemplate/instantiate-c99.cpp
new file mode 100644
index 0000000..ae15528
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-c99.cpp
@@ -0,0 +1,81 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Test template instantiation for C99-specific features.
+
+// ---------------------------------------------------------------------
+// Designated initializers
+// ---------------------------------------------------------------------
+template<typename T, typename XType, typename YType>
+struct DesigInit0 {
+ void f(XType x, YType y) {
+ T agg = {
+ .y = y, // expected-error{{does not refer}}
+ .x = x // expected-error{{does not refer}}
+ };
+ }
+};
+
+struct Point2D {
+ float x, y;
+};
+
+template struct DesigInit0<Point2D, int, double>;
+
+struct Point3D {
+ float x, y, z;
+};
+
+template struct DesigInit0<Point3D, int, double>;
+
+struct Color {
+ unsigned char red, green, blue;
+};
+
+struct ColorPoint3D {
+ Color color;
+ float x, y, z;
+};
+
+template struct DesigInit0<ColorPoint3D, int, double>;
+template struct DesigInit0<Color, int, double>; // expected-note{{instantiation}}
+
+template<typename T, int Subscript1, int Subscript2,
+ typename Val1, typename Val2>
+struct DesigArrayInit0 {
+ void f(Val1 val1, Val2 val2) {
+ T array = {
+ [Subscript1] = val1,
+ [Subscript2] = val2 // expected-error{{exceeds array bounds}}
+ };
+
+ int array2[10] = { [5] = 3 };
+ }
+};
+
+template struct DesigArrayInit0<int[8], 5, 3, float, int>;
+template struct DesigArrayInit0<int[8], 5, 13, float, int>; // expected-note{{instantiation}}
+
+template<typename T, int Subscript1, int Subscript2,
+ typename Val1>
+struct DesigArrayRangeInit0 {
+ void f(Val1 val1) {
+ T array = {
+ [Subscript1...Subscript2] = val1 // expected-error{{exceeds}}
+ };
+ }
+};
+
+template struct DesigArrayRangeInit0<int[8], 3, 5, float>;
+template struct DesigArrayRangeInit0<int[8], 5, 13, float>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// Compound literals
+// ---------------------------------------------------------------------
+template<typename T, typename Arg1, typename Arg2>
+struct CompoundLiteral0 {
+ T f(Arg1 a1, Arg2 a2) {
+ return (T){a1, a2};
+ }
+};
+
+template struct CompoundLiteral0<Point2D, int, float>;
diff --git a/clang/test/SemaTemplate/instantiate-call.cpp b/clang/test/SemaTemplate/instantiate-call.cpp
new file mode 100644
index 0000000..da1eb49
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-call.cpp
@@ -0,0 +1,51 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N1 {
+ struct X0 { };
+
+ int& f0(X0);
+}
+
+namespace N2 {
+ char& f0(char);
+
+ template<typename T, typename Result>
+ struct call_f0 {
+ void test_f0(T t) {
+ Result result = f0(t);
+ }
+ };
+}
+
+template struct N2::call_f0<int, char&>;
+template struct N2::call_f0<N1::X0, int&>;
+
+namespace N3 {
+ template<typename T, typename Result>
+ struct call_f0 {
+ void test_f0(T t) {
+ Result &result = f0(t); // expected-error {{undeclared identifier}} \
+ expected-error {{neither visible in the template definition nor found by argument-dependent lookup}}
+ }
+ };
+}
+
+template struct N3::call_f0<int, char&>; // expected-note{{instantiation}}
+template struct N3::call_f0<N1::X0, int&>;
+
+short& f0(char); // expected-note {{should be declared prior to the call site}}
+namespace N4 {
+ template<typename T, typename Result>
+ struct call_f0 {
+ void test_f0(T t) {
+ Result &result = f0(t);
+ }
+ };
+}
+
+template struct N4::call_f0<int, short&>;
+template struct N4::call_f0<N1::X0, int&>;
+template struct N3::call_f0<int, short&>; // expected-note{{instantiation}}
+
+// FIXME: test overloaded function call operators, calls to member
+// functions, etc.
diff --git a/clang/test/SemaTemplate/instantiate-case.cpp b/clang/test/SemaTemplate/instantiate-case.cpp
new file mode 100644
index 0000000..1cc2d5d
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-case.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<class T>
+static int alpha(T c)
+{
+ return *c; // expected-error{{indirection requires pointer operand}}
+}
+
+template<class T>
+static void
+_shexp_match()
+{
+ switch(1) {
+ case 1:
+ alpha(1); // expected-note{{instantiation of function template}}
+ }
+}
+int main() {
+ _shexp_match<char>(); // expected-note{{instantiation of function template}}
+ return 0;
+}
diff --git a/clang/test/SemaTemplate/instantiate-cast.cpp b/clang/test/SemaTemplate/instantiate-cast.cpp
new file mode 100644
index 0000000..b3babf1
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-cast.cpp
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct A { int x; }; // expected-note 2 {{candidate constructor}}
+
+class Base {
+public:
+ virtual void f();
+};
+
+class Derived : public Base { };
+
+struct ConvertibleToInt {
+ operator int() const;
+};
+
+struct Constructible {
+ Constructible(int, float);
+};
+
+// ---------------------------------------------------------------------
+// C-style casts
+// ---------------------------------------------------------------------
+template<typename T, typename U>
+struct CStyleCast0 {
+ void f(T t) {
+ (void)((U)t); // expected-error{{cannot convert 'A' to 'int' without a conversion operator}}
+ }
+};
+
+template struct CStyleCast0<int, float>;
+template struct CStyleCast0<A, int>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// static_cast
+// ---------------------------------------------------------------------
+template<typename T, typename U>
+struct StaticCast0 {
+ void f(T t) {
+ (void)static_cast<U>(t); // expected-error{{no matching conversion for static_cast from 'int' to 'A'}}
+ }
+};
+
+template struct StaticCast0<ConvertibleToInt, bool>;
+template struct StaticCast0<int, float>;
+template struct StaticCast0<int, A>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// dynamic_cast
+// ---------------------------------------------------------------------
+template<typename T, typename U>
+struct DynamicCast0 {
+ void f(T t) {
+ (void)dynamic_cast<U>(t); // expected-error{{not a reference or pointer}}
+ }
+};
+
+template struct DynamicCast0<Base*, Derived*>;
+template struct DynamicCast0<Base*, A>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// reinterpret_cast
+// ---------------------------------------------------------------------
+template<typename T, typename U>
+struct ReinterpretCast0 {
+ void f(T t) {
+ (void)reinterpret_cast<U>(t); // expected-error{{qualifiers}}
+ }
+};
+
+template struct ReinterpretCast0<void (*)(int), void (*)(float)>;
+template struct ReinterpretCast0<int const *, float *>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// const_cast
+// ---------------------------------------------------------------------
+template<typename T, typename U>
+struct ConstCast0 {
+ void f(T t) {
+ (void)const_cast<U>(t); // expected-error{{not allowed}}
+ }
+};
+
+template struct ConstCast0<int const * *, int * *>;
+template struct ConstCast0<int const *, float *>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// C++ functional cast
+// ---------------------------------------------------------------------
+template<typename T, typename U>
+struct FunctionalCast1 {
+ void f(T t) {
+ (void)U(t); // expected-error{{cannot convert 'A' to 'int' without a conversion operator}}
+ }
+};
+
+template struct FunctionalCast1<int, float>;
+template struct FunctionalCast1<A, int>; // expected-note{{instantiation}}
+
+// Generates temporaries, which we cannot handle yet.
+template<int N, long M>
+struct FunctionalCast2 {
+ void f() {
+ (void)Constructible(N, M);
+ }
+};
+
+template struct FunctionalCast2<1, 3>;
+
+// ---------------------------------------------------------------------
+// implicit casting
+// ---------------------------------------------------------------------
+template<typename T>
+struct Derived2 : public Base { };
+
+void test_derived_to_base(Base *&bp, Derived2<int> *dp) {
+ bp = dp;
+}
diff --git a/clang/test/SemaTemplate/instantiate-clang.cpp b/clang/test/SemaTemplate/instantiate-clang.cpp
new file mode 100644
index 0000000..34d68c4
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-clang.cpp
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Test template instantiation for Clang-specific features.
+
+// ---------------------------------------------------------------------
+// Vector types
+// ---------------------------------------------------------------------
+typedef __attribute__(( ext_vector_type(2) )) double double2;
+typedef __attribute__(( ext_vector_type(4) )) double double4;
+
+template<typename T>
+struct ExtVectorAccess0 {
+ void f(T v1, double4 v2) {
+ v1.xy = v2.yx;
+ }
+};
+
+template struct ExtVectorAccess0<double2>;
+template struct ExtVectorAccess0<double4>;
+
+typedef __attribute__(( ext_vector_type(2) )) double double2;
+
+template<typename T, typename U, int N, int M>
+struct ShuffleVector0 {
+ void f(T t, U u, double2 a, double2 b) {
+ (void)__builtin_shufflevector(t, u, N, M); // expected-error{{index}}
+ (void)__builtin_shufflevector(a, b, N, M); // expected-error{{index}}
+ (void)__builtin_shufflevector(a, b, 2, 1);
+ }
+};
+
+template struct ShuffleVector0<double2, double2, 2, 1>;
+template struct ShuffleVector0<double2, double2, 4, 3>; // expected-note{{instantiation}}
+
+
diff --git a/clang/test/SemaTemplate/instantiate-complete.cpp b/clang/test/SemaTemplate/instantiate-complete.cpp
new file mode 100644
index 0000000..68d5ae3
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-complete.cpp
@@ -0,0 +1,146 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Tests various places where requiring a complete type involves
+// instantiation of that type.
+
+template<typename T>
+struct X {
+ X(T);
+
+ T f; // expected-error{{data member instantiated with function type 'float (int)'}} \
+ // expected-error{{data member instantiated with function type 'int (int)'}} \
+ // expected-error{{data member instantiated with function type 'char (char)'}} \
+ // expected-error{{data member instantiated with function type 'short (short)'}} \
+ // expected-error{{data member instantiated with function type 'float (float)'}}
+};
+
+X<int> f() { return 0; }
+
+struct XField {
+ X<float(int)> xf; // expected-note{{in instantiation of template class 'X<float (int)>' requested here}}
+};
+
+void test_subscript(X<double> *ptr1, X<int(int)> *ptr2, int i) {
+ (void)ptr1[i];
+ (void)ptr2[i]; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}}
+}
+
+void test_arith(X<signed char> *ptr1, X<unsigned char> *ptr2,
+ X<char(char)> *ptr3, X<short(short)> *ptr4) {
+ (void)(ptr1 + 5);
+ (void)(5 + ptr2);
+ (void)(ptr3 + 5); // expected-note{{in instantiation of template class 'X<char (char)>' requested here}}
+ (void)(5 + ptr4); // expected-note{{in instantiation of template class 'X<short (short)>' requested here}}
+}
+
+void test_new() {
+ (void)new X<float>(0);
+ (void)new X<float(float)>; // expected-note{{in instantiation of template class 'X<float (float)>' requested here}}
+}
+
+void test_memptr(X<long> *p1, long X<long>::*pm1,
+ X<long(long)> *p2,
+ long (X<long(long)>::*pm2)(long)) {
+ (void)(p1->*pm1);
+}
+
+// Reference binding to a base
+template<typename T>
+struct X1 { };
+
+template<typename T>
+struct X2 : public T { };
+
+void refbind_base(X2<X1<int> > &x2) {
+ X1<int> &x1 = x2;
+}
+
+// Enumerate constructors for user-defined conversion.
+template<typename T>
+struct X3 {
+ X3(T);
+};
+
+void enum_constructors(X1<float> &x1) {
+ X3<X1<float> > x3 = x1;
+}
+
+namespace PR6376 {
+ template<typename T, typename U> struct W { };
+
+ template<typename T>
+ struct X {
+ template<typename U>
+ struct apply {
+ typedef W<T, U> type;
+ };
+ };
+
+ template<typename T, typename U>
+ struct Y : public X<T>::template apply<U>::type { };
+
+ template struct Y<int, float>;
+}
+
+namespace TemporaryObjectCopy {
+ // Make sure we instantiate classes when we create a temporary copy.
+ template<typename T>
+ struct X {
+ X(T);
+ };
+
+ template<typename T>
+ void f(T t) {
+ const X<int> &x = X<int>(t);
+ }
+
+ template void f(int);
+}
+
+namespace PR7080 {
+ template <class T, class U>
+ class X
+ {
+ typedef char true_t;
+ class false_t { char dummy[2]; };
+ static true_t dispatch(U);
+ static false_t dispatch(...);
+ static T trigger();
+ public:
+ enum { value = sizeof(dispatch(trigger())) == sizeof(true_t) };
+ };
+
+ template <class T>
+ class rv : public T
+ { };
+
+ bool x = X<int, rv<int>&>::value;
+}
+
+namespace pr7199 {
+ template <class T> class A; // expected-note {{template is declared here}}
+ template <class T> class B {
+ class A<T>::C field; // expected-error {{implicit instantiation of undefined template 'pr7199::A<int>'}}
+ };
+
+ template class B<int>; // expected-note {{in instantiation}}
+}
+
+namespace PR8425 {
+ template <typename T>
+ class BaseT {};
+
+ template <typename T>
+ class DerivedT : public BaseT<T> {};
+
+ template <typename T>
+ class FromT {
+ public:
+ operator DerivedT<T>() const { return DerivedT<T>(); }
+ };
+
+ void test() {
+ FromT<int> ft;
+ BaseT<int> bt(ft);
+ }
+}
diff --git a/clang/test/SemaTemplate/instantiate-decl-dtor.cpp b/clang/test/SemaTemplate/instantiate-decl-dtor.cpp
new file mode 100644
index 0000000..193d976
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-decl-dtor.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+template <typename T> struct A {
+ T x;
+ A(int y) { x = y; }
+ ~A() { *x = 10; } // expected-error {{indirection requires pointer operand}}
+};
+
+void a() {
+ A<int> b = 10; // expected-note {{requested here}}
+}
diff --git a/clang/test/SemaTemplate/instantiate-decl-init.cpp b/clang/test/SemaTemplate/instantiate-decl-init.cpp
new file mode 100644
index 0000000..6b76d72
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-decl-init.cpp
@@ -0,0 +1,46 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5426 - the non-dependent obj would be fully processed and wrapped in a
+// CXXConstructExpr at definition time, which would lead to a failure at
+// instantiation time.
+struct arg {
+ arg();
+};
+
+struct oldstylemove {
+ oldstylemove(oldstylemove&);
+ oldstylemove(const arg&);
+};
+
+template <typename T>
+void fn(T t, const arg& arg) {
+ oldstylemove obj(arg);
+}
+
+void test() {
+ fn(1, arg());
+}
+
+struct X0 { };
+
+struct X1 {
+ explicit X1(const X0 &x0 = X0());
+};
+
+template<typename T>
+void f0() {
+ X1 x1;
+}
+
+template void f0<int>();
+template void f0<float>();
+
+struct NonTrivial {
+ NonTrivial();
+ ~NonTrivial();
+};
+
+template<int N> void f1() {
+ NonTrivial array[N];
+}
+template<> void f1<2>();
diff --git a/clang/test/SemaTemplate/instantiate-declref-ice.cpp b/clang/test/SemaTemplate/instantiate-declref-ice.cpp
new file mode 100644
index 0000000..49b1b63
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-declref-ice.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<int i> struct x {
+ static const int j = i;
+ x<j>* y;
+};
+
+template<int i>
+const int x<i>::j;
+
+int array0[x<2>::j];
+
+template<typename T>
+struct X0 {
+ static const unsigned value = sizeof(T);
+};
+
+template<typename T>
+const unsigned X0<T>::value;
+
+int array1[X0<int>::value == sizeof(int)? 1 : -1];
+
+const unsigned& testX0() { return X0<int>::value; }
+
+int array2[X0<int>::value == sizeof(int)? 1 : -1];
+
+template<typename T>
+struct X1 {
+ static const unsigned value;
+};
+
+template<typename T>
+const unsigned X1<T>::value = sizeof(T);
+
+int array3[X1<int>::value == sizeof(int)? 1 : -1];
diff --git a/clang/test/SemaTemplate/instantiate-declref.cpp b/clang/test/SemaTemplate/instantiate-declref.cpp
new file mode 100644
index 0000000..7d4a2ff
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-declref.cpp
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace N {
+ struct Outer {
+ struct Inner {
+ template<typename T>
+ struct InnerTemplate {
+ struct VeryInner {
+ typedef T type;
+
+ static enum K1 { K1Val = sizeof(T) } Kind1;
+ static enum { K2Val = sizeof(T)*2 } Kind2;
+ enum { K3Val = sizeof(T)*2 } Kind3;
+
+ void foo() {
+ K1 k1 = K1Val;
+ Kind1 = K1Val;
+ Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
+ Kind3 = K3Val;
+ }
+
+ struct UeberInner {
+ void bar() {
+ K1 k1 = K1Val;
+ Kind1 = K1Val;
+ Outer::Inner::InnerTemplate<type>::VeryInner::Kind2 = K2Val;
+
+ InnerTemplate t;
+ InnerTemplate<type> t2;
+ }
+ };
+ };
+ };
+ };
+ };
+}
+
+typedef int INT;
+template struct N::Outer::Inner::InnerTemplate<INT>::VeryInner;
+template struct N::Outer::Inner::InnerTemplate<INT>::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate<int>'}}
+
+namespace N2 {
+ struct Outer2 {
+ template<typename T, typename U = T>
+ struct Inner {
+ void foo() {
+ enum { K1Val = sizeof(T) } k1;
+ enum K2 { K2Val = sizeof(T)*2 } k2a;
+
+ K2 k2b = K2Val;
+
+ struct S { T x, y; } s1;
+ struct { U x, y; } s2;
+ s1.x = s2.x; // expected-error{{incompatible}}
+
+ typedef T type;
+ type t2 = s1.x;
+
+ typedef struct { T z; } type2;
+ type2 t3 = { s1.x };
+
+ Inner i1;
+ i1.foo();
+ Inner<T> i2;
+ i2.foo();
+ }
+ };
+ };
+}
+
+template struct N2::Outer2::Inner<float>;
+template struct N2::Outer2::Inner<int*, float*>; // expected-note{{instantiation}}
+
+// Test dependent pointer-to-member expressions.
+template<typename T>
+struct smart_ptr {
+ struct safe_bool {
+ int member;
+ };
+
+ operator int safe_bool::*() const {
+ return ptr? &safe_bool::member : 0;
+ }
+
+ T* ptr;
+};
+
+void test_smart_ptr(smart_ptr<int> p) {
+ if (p) { }
+}
+
+// PR5517
+namespace test0 {
+ template <int K> struct X {
+ X() { extern void x(); }
+ };
+ void g() { X<2>(); }
+}
+
+// <rdar://problem/8302161>
+namespace test1 {
+ template <typename T> void f(T const &t) {
+ union { char c; T t_; };
+ c = 'a'; // <- this shouldn't silently fail to instantiate
+ T::foo(); // expected-error {{has no members}}
+ }
+ template void f(int const &); // expected-note {{requested here}}
+}
+
+namespace test2 {
+ template<typename T> void f() {
+ T::error; // expected-error {{no member}}
+ }
+ void g() {
+ // This counts as an odr-use, so should trigger the instantiation of f<int>.
+ (void)&f<int>; // expected-note {{here}}
+ }
+}
diff --git a/clang/test/SemaTemplate/instantiate-deeply.cpp b/clang/test/SemaTemplate/instantiate-deeply.cpp
new file mode 100644
index 0000000..c5f6594
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-deeply.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -fsyntax-only -Wall -verify %s
+template<typename a> struct A {
+ template <typename b> struct B {
+ template <typename c> struct C {
+ template <typename d> struct D {
+ template <typename e> struct E {
+ e field;
+ E() : field(0) {
+ d v1 = 4;
+ c v2 = v1 * v1;
+ b v3 = 8;
+ a v4 = v3 * v3;
+ field += v2 + v4;
+ }
+ };
+ };
+ };
+ };
+};
+
+A<int>::B<int>::C<int>::D<int>::E<int> global;
+
+// PR5352
+template <typename T>
+class Foo {
+public:
+ Foo() {}
+
+ struct Bar {
+ T value;
+ };
+
+ Bar u;
+};
+
+template class Foo<int>;
diff --git a/clang/test/SemaTemplate/instantiate-default-assignment-operator.cpp b/clang/test/SemaTemplate/instantiate-default-assignment-operator.cpp
new file mode 100644
index 0000000..31cdef5
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-default-assignment-operator.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename> struct PassRefPtr { };
+template<typename T> struct RefPtr {
+ RefPtr& operator=(const RefPtr&) { int a[sizeof(T) ? -1 : -1];} // expected-error 2 {{array with a negative size}}
+ RefPtr& operator=(const PassRefPtr<T>&);
+};
+
+struct A { RefPtr<int> a; }; // expected-note {{instantiation of member function 'RefPtr<int>::operator=' requested here}}
+struct B : RefPtr<float> { }; // expected-note {{in instantiation of member function 'RefPtr<float>::operator=' requested here}}
+
+void f() {
+ A a1, a2;
+ a1 = a2;
+
+ B b1, b2;
+ b1 = b2;
+}
diff --git a/clang/test/SemaTemplate/instantiate-dependent-nested-name.cpp b/clang/test/SemaTemplate/instantiate-dependent-nested-name.cpp
new file mode 100644
index 0000000..eb1d3fb
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-dependent-nested-name.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR4382
+template<typename T> struct X { static const T A = 1; };
+template<typename T, bool = X<T>::A> struct Y { typedef T A; };
+template<typename T> struct Z { typedef typename Y<T>::A A; };
+extern int x;
+extern Z<int>::A x;
diff --git a/clang/test/SemaTemplate/instantiate-elab-type-specifier.cpp b/clang/test/SemaTemplate/instantiate-elab-type-specifier.cpp
new file mode 100644
index 0000000..e5e10a8
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-elab-type-specifier.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5681
+template <class T> struct Base {
+ struct foo {};
+ int foo;
+};
+
+template <class T> struct Derived : Base<T> {
+ typedef struct Base<T>::foo type;
+};
+
+template struct Derived<int>;
diff --git a/clang/test/SemaTemplate/instantiate-enum-2.cpp b/clang/test/SemaTemplate/instantiate-enum-2.cpp
new file mode 100644
index 0000000..aa3b590
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-enum-2.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 %s -fsyntax-only -verify
+
+template<int IntBits> struct X {
+ enum {
+ IntShift = (unsigned long long)IntBits,
+ ShiftedIntMask = (1 << IntShift)
+ };
+};
+X<1> x;
diff --git a/clang/test/SemaTemplate/instantiate-enum.cpp b/clang/test/SemaTemplate/instantiate-enum.cpp
new file mode 100644
index 0000000..5353a92
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-enum.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<typename T, T I, int J>
+struct adder {
+ enum {
+ value = I + J,
+ value2
+ };
+};
+
+int array1[adder<long, 3, 4>::value == 7? 1 : -1];
+
+namespace PR6375 {
+ template<typename T>
+ void f() {
+ enum Enum
+ {
+ enumerator1 = 0xFFFFFFF,
+ enumerator2 = enumerator1 - 1
+ };
+
+ int xb1 = enumerator1;
+ int xe1 = enumerator2;
+ }
+
+ template void f<int>();
+}
diff --git a/clang/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp b/clang/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
new file mode 100644
index 0000000..8a6f9ef
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
@@ -0,0 +1,133 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -ftemplate-depth 16 -fcxx-exceptions -fexceptions %s
+
+// DR1330: an exception specification for a function template is only
+// instantiated when it is needed.
+
+template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}}
+struct Incomplete; // expected-note{{forward}}
+
+void test_f1(Incomplete *incomplete_p, int *int_p) {
+ f1(int_p);
+ f1(incomplete_p); // expected-note{{instantiation of exception spec}}
+}
+
+template<typename T> struct A {
+ template<typename U> struct B {
+ static void f() noexcept(A<U>().n);
+ };
+
+ constexpr A() : n(true) {}
+ bool n;
+};
+
+static_assert(noexcept(A<int>::B<char>::f()), "");
+
+template<unsigned N> struct S {
+ static void recurse() noexcept(noexcept(S<N+1>::recurse())); // \
+ // expected-error {{no member named 'recurse'}} \
+ // expected-note 9{{instantiation of exception spec}}
+};
+decltype(S<0>::recurse()) *pVoid1 = 0; // ok, exception spec not needed
+decltype(&S<0>::recurse) pFn = 0; // ok, exception spec not needed
+
+template<> struct S<10> {};
+void (*pFn2)() noexcept = &S<0>::recurse; // expected-note {{instantiation of exception spec}} expected-error {{not superset}}
+
+
+template<typename T> T go(T a) noexcept(noexcept(go(a))); // \
+// expected-error 16{{call to function 'go' that is neither visible}} \
+// expected-note 16{{'go' should be declared prior to the call site}} \
+// expected-error {{recursive template instantiation exceeded maximum depth of 16}} \
+// expected-error {{use of undeclared identifier 'go'}} \
+
+void f() {
+ int k = go(0); // \
+ // expected-note {{in instantiation of exception specification for 'go<int>' requested here}}
+}
+
+
+namespace dr1330_example {
+ template <class T> struct A {
+ void f(...) throw (typename T::X); // expected-error {{'int'}}
+ void f(int);
+ };
+
+ int main() {
+ A<int>().f(42);
+ }
+
+ int test2() {
+ struct S {
+ template<typename T>
+ static int f() noexcept(noexcept(A<T>().f("boo!"))) { return 0; } // \
+ // expected-note {{instantiation of exception spec}}
+ typedef decltype(f<S>()) X;
+ };
+ S().f<S>(); // ok
+ S().f<int>(); // expected-note {{instantiation of exception spec}}
+ }
+}
+
+namespace core_19754_example {
+ template<typename T> T declval() noexcept;
+
+ template<typename T, typename = decltype(T(declval<T&&>()))>
+ struct is_movable { static const bool value = true; };
+
+ template<typename T>
+ struct wrap {
+ T val;
+ void irrelevant(wrap &p) noexcept(is_movable<T>::value);
+ };
+
+ template<typename T>
+ struct base {
+ base() {}
+ base(const typename T::type1 &);
+ base(const typename T::type2 &);
+ };
+
+ template<typename T>
+ struct type1 {
+ wrap<typename T::base> base;
+ };
+
+ template<typename T>
+ struct type2 {
+ wrap<typename T::base> base;
+ };
+
+ struct types {
+ typedef base<types> base;
+ typedef type1<types> type1;
+ typedef type2<types> type2;
+ };
+
+ base<types> val = base<types>();
+}
+
+namespace pr9485 {
+ template <typename T> void f1(T) throw(typename T::exception); // expected-note {{candidate}}
+ template <typename T> void f1(T, int = 0) throw(typename T::noitpecxe); // expected-note {{candidate}}
+
+ template <typename T> void f2(T) noexcept(T::throws); // expected-note {{candidate}}
+ template <typename T> void f2(T, int = 0) noexcept(T::sworht); // expected-note {{candidate}}
+
+ void test() {
+ f1(0); // expected-error {{ambiguous}}
+ f2(0); // expected-error {{ambiguous}}
+ }
+}
+
+struct Exc1 { char c[4]; };
+struct Exc2 { double x, y, z; };
+struct Base {
+ virtual void f() noexcept; // expected-note {{overridden}}
+};
+template<typename T> struct Derived : Base {
+ void f() noexcept (sizeof(T) == 4); // expected-error {{is more lax}}
+ void g() noexcept (T::error);
+};
+
+Derived<Exc1> d1; // ok
+Derived<Exc2> d2; // expected-note {{in instantiation of}}
diff --git a/clang/test/SemaTemplate/instantiate-exception-spec.cpp b/clang/test/SemaTemplate/instantiate-exception-spec.cpp
new file mode 100644
index 0000000..d4f12df
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-exception-spec.cpp
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// FIXME: the "note" should be down at the call site!
+template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}} \
+ // expected-note{{instantiation of}}
+struct Incomplete; // expected-note{{forward}}
+
+void test_f1(Incomplete *incomplete_p, int *int_p) {
+ f1(int_p);
+ f1(incomplete_p);
+}
diff --git a/clang/test/SemaTemplate/instantiate-expr-1.cpp b/clang/test/SemaTemplate/instantiate-expr-1.cpp
new file mode 100644
index 0000000..9395117
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-expr-1.cpp
@@ -0,0 +1,192 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<int I, int J>
+struct Bitfields {
+ int simple : I; // expected-error{{bit-field 'simple' has zero width}}
+ int parens : (J);
+};
+
+void test_Bitfields(Bitfields<0, 5> *b) {
+ (void)sizeof(Bitfields<10, 5>);
+ (void)sizeof(Bitfields<0, 1>); // expected-note{{in instantiation of template class 'Bitfields<0, 1>' requested here}}
+}
+
+template<int I, int J>
+struct BitfieldPlus {
+ int bitfield : I + J; // expected-error{{bit-field 'bitfield' has zero width}}
+};
+
+void test_BitfieldPlus() {
+ (void)sizeof(BitfieldPlus<0, 1>);
+ (void)sizeof(BitfieldPlus<-5, 5>); // expected-note{{in instantiation of template class 'BitfieldPlus<-5, 5>' requested here}}
+}
+
+template<int I, int J>
+struct BitfieldMinus {
+ int bitfield : I - J; // expected-error{{bit-field 'bitfield' has negative width (-1)}} \
+ // expected-error{{bit-field 'bitfield' has zero width}}
+};
+
+void test_BitfieldMinus() {
+ (void)sizeof(BitfieldMinus<5, 1>);
+ (void)sizeof(BitfieldMinus<0, 1>); // expected-note{{in instantiation of template class 'BitfieldMinus<0, 1>' requested here}}
+ (void)sizeof(BitfieldMinus<5, 5>); // expected-note{{in instantiation of template class 'BitfieldMinus<5, 5>' requested here}}
+}
+
+template<int I, int J>
+struct BitfieldDivide {
+ int bitfield : I / J; // expected-error{{expression is not an integral constant expression}} \
+ // expected-note{{division by zero}}
+};
+
+void test_BitfieldDivide() {
+ (void)sizeof(BitfieldDivide<5, 1>);
+ (void)sizeof(BitfieldDivide<5, 0>); // expected-note{{in instantiation of template class 'BitfieldDivide<5, 0>' requested here}}
+}
+
+template<typename T, T I, int J>
+struct BitfieldDep {
+ int bitfield : I + J;
+};
+
+void test_BitfieldDep() {
+ (void)sizeof(BitfieldDep<int, 1, 5>);
+}
+
+template<int I>
+struct BitfieldNeg {
+ int bitfield : (-I); // expected-error{{bit-field 'bitfield' has negative width (-5)}}
+};
+
+template<typename T, T I>
+struct BitfieldNeg2 {
+ int bitfield : (-I); // expected-error{{bit-field 'bitfield' has negative width (-5)}}
+};
+
+void test_BitfieldNeg() {
+ (void)sizeof(BitfieldNeg<-5>); // okay
+ (void)sizeof(BitfieldNeg<5>); // expected-note{{in instantiation of template class 'BitfieldNeg<5>' requested here}}
+ (void)sizeof(BitfieldNeg2<int, -5>); // okay
+ (void)sizeof(BitfieldNeg2<int, 5>); // expected-note{{in instantiation of template class 'BitfieldNeg2<int, 5>' requested here}}
+}
+
+template<typename T>
+void increment(T &x) {
+ (void)++x;
+}
+
+struct Incrementable {
+ Incrementable &operator++();
+};
+
+void test_increment(Incrementable inc) {
+ increment(inc);
+}
+
+template<typename T>
+void add(const T &x) {
+ (void)(x + x);
+}
+
+namespace PR6237 {
+ template <typename T>
+ void f(T t) {
+ t++;
+ }
+
+ struct B { };
+ B operator++(B &, int);
+
+ template void f(B);
+}
+
+struct Addable {
+ Addable operator+(const Addable&) const;
+};
+
+void test_add(Addable &a) {
+ add(a);
+}
+
+struct CallOperator {
+ int &operator()(int);
+ double &operator()(double);
+};
+
+template<typename Result, typename F, typename Arg1>
+Result test_call_operator(F f, Arg1 arg1) {
+ // PR5266: non-dependent invocations of a function call operator.
+ CallOperator call_op;
+ int &ir = call_op(17);
+ return f(arg1);
+}
+
+void test_call_operator(CallOperator call_op, int i, double d) {
+ int &ir = test_call_operator<int&>(call_op, i);
+ double &dr = test_call_operator<double&>(call_op, d);
+}
+
+template<typename T>
+void test_asm(T t) {
+ asm ("nop" : "=a"(*t) : "r"(*t)); // expected-error {{indirection requires pointer operand ('int' invalid)}}
+}
+
+void test_asm() {
+ int* a;
+ test_asm(a);
+
+ int b;
+ test_asm(b); // expected-note {{in instantiation of function template specialization 'test_asm<int>' requested here}}
+}
+
+namespace PR6424 {
+ template<int I> struct X {
+ X() {
+ int *ip = I; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+ }
+ };
+
+ template<int> struct Y {
+ typedef X<7> X7;
+
+ void f() { X7(); } // expected-note{{instantiation}}
+ };
+
+ template void Y<3>::f();
+
+ template<int I>
+ struct X2 {
+ void *operator new(__SIZE_TYPE__) {
+ int *ip = I; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+ return ip;
+ }
+ };
+
+ template<int> struct Y2 {
+ typedef X2<7> X;
+ void f() {
+ new X(); // expected-note{{instantiation of}}
+ }
+ };
+
+ template void Y2<3>::f();
+
+ template<typename T>
+ void rdar10283928(int count) {
+ (void)new char[count]();
+ }
+
+ template void rdar10283928<int>(int);
+}
+
+namespace PR10864 {
+ template<typename T> class Vals {};
+ template<> class Vals<int> { public: static const int i = 1; };
+ template<> class Vals<float> { public: static const double i; };
+ template<typename T> void test_asm_tied(T o) {
+ __asm("addl $1, %0" : "=r" (o) : "0"(Vals<T>::i)); // expected-error {{input with type 'double' matching output with type 'float'}}
+ }
+ void test_asm_tied() {
+ test_asm_tied(1);
+ test_asm_tied(1.f); // expected-note {{instantiation of}}
+ }
+}
diff --git a/clang/test/SemaTemplate/instantiate-expr-2.cpp b/clang/test/SemaTemplate/instantiate-expr-2.cpp
new file mode 100644
index 0000000..eaa68dd
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-expr-2.cpp
@@ -0,0 +1,245 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+typedef char one_byte;
+typedef char (&two_bytes)[2];
+typedef char (&four_bytes)[4];
+typedef char (&eight_bytes)[8];
+
+template<int N> struct A { };
+
+namespace N1 {
+ struct X { };
+}
+
+namespace N2 {
+ struct Y { };
+
+ two_bytes operator+(Y, Y);
+}
+
+namespace N3 {
+ struct Z { };
+
+ eight_bytes operator+(Z, Z);
+}
+
+namespace N4 {
+ one_byte operator+(N1::X, N2::Y);
+
+ template<typename T, typename U>
+ struct BinOpOverload {
+ typedef A<sizeof(T() + U())> type;
+ };
+}
+
+namespace N1 {
+ four_bytes operator+(X, X);
+}
+
+namespace N3 {
+ eight_bytes operator+(Z, Z); // redeclaration
+}
+
+void test_bin_op_overload(A<1> *a1, A<2> *a2, A<4> *a4, A<8> *a8) {
+ typedef N4::BinOpOverload<N1::X, N2::Y>::type XY;
+ XY *xy = a1;
+ typedef N4::BinOpOverload<N1::X, N1::X>::type XX;
+ XX *xx = a4;
+ typedef N4::BinOpOverload<N2::Y, N2::Y>::type YY;
+ YY *yy = a2;
+ typedef N4::BinOpOverload<N3::Z, N3::Z>::type ZZ;
+ ZZ *zz = a8;
+}
+
+namespace N3 {
+ eight_bytes operator-(::N3::Z);
+}
+
+namespace N4 {
+ template<typename T>
+ struct UnaryOpOverload {
+ typedef A<sizeof(-T())> type;
+ };
+}
+
+void test_unary_op_overload(A<8> *a8) {
+ typedef N4::UnaryOpOverload<N3::Z>::type UZ;
+ UZ *uz = a8;
+}
+
+/*
+namespace N5 {
+ template<int I>
+ struct Lookup {
+ enum { val = I, more = val + 1 };
+ };
+
+ template<bool B>
+ struct Cond {
+ enum Junk { is = B ? Lookup<B>::more : Lookup<Lookup<B+1>::more>::val };
+ };
+
+ enum { resultT = Cond<true>::is,
+ resultF = Cond<false>::is };
+}
+*/
+
+namespace N6 {
+ // non-typedependent
+ template<int I>
+ struct Lookup {};
+
+ template<bool B, typename T, typename E>
+ struct Cond {
+ typedef Lookup<B ? sizeof(T) : sizeof(E)> True;
+ typedef Lookup<!B ? sizeof(T) : sizeof(E)> False;
+ };
+
+ typedef Cond<true, int, char>::True True;
+ typedef Cond<true, int, char>::False False;
+
+ // check that we have the right types
+ Lookup<1> const &L1(False());
+ Lookup<sizeof(int)> const &L2(True());
+}
+
+
+namespace N7 {
+ // type dependent
+ template<int I>
+ struct Lookup {};
+
+ template<bool B, typename T, typename E>
+ struct Cond {
+ T foo() { return B ? T() : E(); }
+ typedef Lookup<sizeof(B ? T() : E())> Type;
+ };
+
+ //Cond<true, int*, double> C; // Errors
+ //int V(C.foo()); // Errors
+ //typedef Cond<true, int*, double>::Type Type; // Errors
+ typedef Cond<true, int, double>::Type Type;
+}
+
+template<typename T, unsigned long N> struct IntegralConstant { };
+
+template<typename T>
+struct X0 {
+ void f(T x, IntegralConstant<T, sizeof(x)>);
+};
+
+void test_X0(X0<int> x, IntegralConstant<int, sizeof(int)> ic) {
+ x.f(5,ic);
+}
+
+namespace N8 {
+ struct X {
+ X operator+(const X&) const;
+ };
+
+ template<typename T>
+ T test_plus(const T* xp, const T& x, const T& y) {
+ x.operator+(y);
+ return xp->operator+(y);
+ }
+
+ void test_test_plus(X x) {
+ test_plus(&x, x, x);
+ }
+}
+
+namespace N9 {
+ struct A {
+ bool operator==(int value);
+ };
+
+ template<typename T> struct B {
+ bool f(A a) {
+ return a == 1;
+ }
+ };
+
+ template struct B<int>;
+}
+
+namespace N10 {
+ template <typename T>
+ class A {
+ struct X { };
+
+ public:
+ ~A() {
+ f(reinterpret_cast<X *>(0), reinterpret_cast<X *>(0));
+ }
+
+ private:
+ void f(X *);
+ void f(X *, X *);
+ };
+
+ template class A<int>;
+}
+
+namespace N12 {
+ // PR5224
+ template<typename T>
+ struct A { typedef int t0; };
+
+ struct C {
+ C(int);
+
+ template<typename T>
+ static C *f0(T a0) {return new C((typename A<T>::t0) 1); }
+ };
+
+ void f0(int **a) { C::f0(a); }
+}
+
+namespace PR7202 {
+ template<typename U, typename T>
+ struct meta {
+ typedef T type;
+ };
+
+ struct X {
+ struct dummy;
+
+ template<typename T>
+ X(T, typename meta<T, dummy*>::type = 0);
+
+ template<typename T, typename A>
+ X(T, A);
+ };
+
+ template<typename T>
+ struct Z { };
+
+ template<typename T> Z<T> g(T);
+
+ struct Y {
+ template<typename T>
+ void f(T t) {
+ new X(g(*this));
+ }
+ };
+
+ template void Y::f(int);
+}
+
+namespace N13 {
+ class A{
+ A(const A&);
+
+ public:
+ ~A();
+ A(int);
+ template<typename T> A &operator<<(const T&);
+ };
+
+ template<typename T>
+ void f(T t) {
+ A(17) << t;
+ }
+
+ template void f(int);
+
+}
diff --git a/clang/test/SemaTemplate/instantiate-expr-3.cpp b/clang/test/SemaTemplate/instantiate-expr-3.cpp
new file mode 100644
index 0000000..ca88b00
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-expr-3.cpp
@@ -0,0 +1,119 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// ---------------------------------------------------------------------
+// Imaginary literals
+// ---------------------------------------------------------------------
+template<typename T>
+struct ImaginaryLiteral0 {
+ void f(T &x) {
+ x = 3.0I; // expected-error{{incompatible type}}
+ }
+};
+
+template struct ImaginaryLiteral0<_Complex float>;
+template struct ImaginaryLiteral0<int*>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// Compound assignment operator
+// ---------------------------------------------------------------------
+namespace N1 {
+ struct X { };
+
+ int& operator+=(X&, int); // expected-note{{candidate}}
+}
+
+namespace N2 {
+ long& operator+=(N1::X&, long); // expected-note{{candidate}}
+
+ template<typename T, typename U, typename Result>
+ struct PlusEquals0 {
+ void f(T t, U u) {
+ Result r = t += u; // expected-error{{ambiguous}}
+ }
+ };
+}
+
+namespace N3 {
+ struct Y : public N1::X {
+ short& operator+=(long); // expected-note{{candidate}}
+ };
+}
+
+template struct N2::PlusEquals0<N1::X, int, int&>;
+template struct N2::PlusEquals0<N1::X, long, long&>;
+template struct N2::PlusEquals0<N3::Y, long, short&>;
+template struct N2::PlusEquals0<int, int, int&>;
+template struct N2::PlusEquals0<N3::Y, int, short&>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// Conditional operator
+// ---------------------------------------------------------------------
+template<typename T, typename U, typename Result>
+struct Conditional0 {
+ void f(T t, U u) {
+ Result result = t? : u;
+ }
+};
+
+template struct Conditional0<int, int, int>;
+
+// ---------------------------------------------------------------------
+// Statement expressions
+// ---------------------------------------------------------------------
+template<typename T>
+struct StatementExpr0 {
+ void f(T t) {
+ (void)({
+ if (t) // expected-error{{contextually convertible}}
+ t = t + 17;
+ t + 12; // expected-error{{invalid operands}}
+ });
+ }
+};
+
+template struct StatementExpr0<int>;
+template struct StatementExpr0<N1::X>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// __builtin_choose_expr
+// ---------------------------------------------------------------------
+template<bool Cond, typename T, typename U, typename Result>
+struct Choose0 {
+ void f(T t, U u) {
+ Result r = __builtin_choose_expr(Cond, t, u); // expected-error{{lvalue}}
+ }
+};
+
+template struct Choose0<true, int, float, int&>;
+template struct Choose0<false, int, float, float&>;
+template struct Choose0<true, int, float, float&>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// __builtin_va_arg
+// ---------------------------------------------------------------------
+template<typename ArgType>
+struct VaArg0 {
+ void f(int n, ...) {
+ __builtin_va_list va;
+ __builtin_va_start(va, n);
+ for (int i = 0; i != n; ++i)
+ (void)__builtin_va_arg(va, ArgType);
+ __builtin_va_end(va);
+ }
+};
+
+template struct VaArg0<int>;
+
+template<typename VaList, typename ArgType>
+struct VaArg1 {
+ void f(int n, ...) {
+ VaList va;
+ __builtin_va_start(va, n); // expected-error{{int}}
+ for (int i = 0; i != n; ++i)
+ (void)__builtin_va_arg(va, ArgType); // expected-error{{int}}
+ __builtin_va_end(va); // expected-error{{int}}
+ }
+};
+
+template struct VaArg1<__builtin_va_list, int>;
+template struct VaArg1<int, int>; // expected-note{{instantiation}}
diff --git a/clang/test/SemaTemplate/instantiate-expr-4.cpp b/clang/test/SemaTemplate/instantiate-expr-4.cpp
new file mode 100644
index 0000000..d95ccfe
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-expr-4.cpp
@@ -0,0 +1,354 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s
+
+// ---------------------------------------------------------------------
+// C++ Functional Casts
+// ---------------------------------------------------------------------
+template<int N>
+struct ValueInit0 {
+ int f() {
+ return int();
+ }
+};
+
+template struct ValueInit0<5>;
+
+template<int N>
+struct FunctionalCast0 {
+ int f() {
+ return int(N);
+ }
+};
+
+template struct FunctionalCast0<5>;
+
+struct X { // expected-note 3 {{candidate constructor (the implicit copy constructor)}}
+ X(int, int); // expected-note 3 {{candidate constructor}}
+};
+
+template<int N, int M>
+struct BuildTemporary0 {
+ X f() {
+ return X(N, M);
+ }
+};
+
+template struct BuildTemporary0<5, 7>;
+
+template<int N, int M>
+struct Temporaries0 {
+ void f() {
+ (void)X(N, M);
+ }
+};
+
+template struct Temporaries0<5, 7>;
+
+// Ensure that both the constructor and the destructor are instantiated by
+// checking for parse errors from each.
+template<int N> struct BadX {
+ BadX() { int a[-N]; } // expected-error {{array with a negative size}}
+ ~BadX() { int a[-N]; } // expected-error {{array with a negative size}}
+};
+
+template<int N>
+struct PR6671 {
+ void f() { (void)BadX<1>(); } // expected-note 2 {{instantiation}}
+};
+template struct PR6671<1>;
+
+// ---------------------------------------------------------------------
+// new/delete expressions
+// ---------------------------------------------------------------------
+struct Y { };
+
+template<typename T>
+struct New0 {
+ T* f(bool x) {
+ if (x)
+ return new T; // expected-error{{no matching}}
+ else
+ return new T();
+ }
+};
+
+template struct New0<int>;
+template struct New0<Y>;
+template struct New0<X>; // expected-note{{instantiation}}
+
+template<typename T, typename Arg1>
+struct New1 {
+ T* f(bool x, Arg1 a1) {
+ return new T(a1); // expected-error{{no matching}}
+ }
+};
+
+template struct New1<int, float>;
+template struct New1<Y, Y>;
+template struct New1<X, Y>; // expected-note{{instantiation}}
+
+template<typename T, typename Arg1, typename Arg2>
+struct New2 {
+ T* f(bool x, Arg1 a1, Arg2 a2) {
+ return new T(a1, a2); // expected-error{{no matching}}
+ }
+};
+
+template struct New2<X, int, float>;
+template struct New2<X, int, int*>; // expected-note{{instantiation}}
+// FIXME: template struct New2<int, int, float>;
+
+// PR5833
+struct New3 {
+ New3();
+
+ void *operator new[](__SIZE_TYPE__) __attribute__((unavailable)); // expected-note{{explicitly made unavailable}}
+};
+
+template<class C>
+void* object_creator() {
+ return new C(); // expected-error{{call to unavailable function 'operator new[]'}}
+}
+
+template void *object_creator<New3[4]>(); // expected-note{{instantiation}}
+
+template<typename T>
+struct Delete0 {
+ void f(T t) {
+ delete t; // expected-error{{cannot delete}}
+ ::delete [] t; // expected-error{{cannot delete}}
+ }
+};
+
+template struct Delete0<int*>;
+template struct Delete0<X*>;
+template struct Delete0<int>; // expected-note{{instantiation}}
+
+namespace PR5755 {
+ template <class T>
+ void Foo() {
+ char* p = 0;
+ delete[] p;
+ }
+
+ void Test() {
+ Foo<int>();
+ }
+}
+
+namespace PR10480 {
+ template<typename T>
+ struct X {
+ X();
+ ~X() {
+ T *ptr = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+ }
+ };
+
+ template<typename T>
+ void f() {
+ new X<int>[1]; // expected-note{{in instantiation of member function 'PR10480::X<int>::~X' requested here}}
+ }
+
+ template void f<int>();
+}
+
+// ---------------------------------------------------------------------
+// throw expressions
+// ---------------------------------------------------------------------
+template<typename T>
+struct Throw1 {
+ void f(T t) {
+ throw;
+ throw t; // expected-error{{incomplete type}}
+ }
+};
+
+struct Incomplete; // expected-note 2{{forward}}
+
+template struct Throw1<int>;
+template struct Throw1<int*>;
+template struct Throw1<Incomplete*>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// typeid expressions
+// ---------------------------------------------------------------------
+
+namespace std {
+ class type_info;
+}
+
+template<typename T>
+struct TypeId0 {
+ const std::type_info &f(T* ptr) {
+ if (ptr)
+ return typeid(ptr);
+ else
+ return typeid(T); // expected-error{{'typeid' of incomplete type 'Incomplete'}}
+ }
+};
+
+struct Abstract {
+ virtual void f() = 0;
+};
+
+template struct TypeId0<int>;
+template struct TypeId0<Incomplete>; // expected-note{{instantiation of member function}}
+template struct TypeId0<Abstract>;
+
+// ---------------------------------------------------------------------
+// type traits
+// ---------------------------------------------------------------------
+template<typename T>
+struct is_pod {
+ static const bool value = __is_pod(T);
+};
+
+static int is_pod0[is_pod<X>::value? -1 : 1];
+static int is_pod1[is_pod<Y>::value? 1 : -1];
+
+// ---------------------------------------------------------------------
+// initializer lists
+// ---------------------------------------------------------------------
+template<typename T, typename Val1>
+struct InitList1 {
+ void f(Val1 val1) {
+ T x = { val1 };
+ }
+};
+
+struct APair {
+ int *x;
+ const float *y;
+};
+
+template struct InitList1<int[1], float>;
+template struct InitList1<APair, int*>;
+
+template<typename T, typename Val1, typename Val2>
+struct InitList2 {
+ void f(Val1 val1, Val2 val2) {
+ T x = { val1, val2 }; // expected-error{{cannot initialize}}
+ }
+};
+
+template struct InitList2<APair, int*, float*>;
+template struct InitList2<APair, int*, double*>; // expected-note{{instantiation}}
+
+// ---------------------------------------------------------------------
+// member references
+// ---------------------------------------------------------------------
+template<typename T, typename Result>
+struct DotMemRef0 {
+ void f(T t) {
+ Result result = t.m; // expected-error{{non-const lvalue reference to type}}
+ }
+};
+
+struct MemInt {
+ int m;
+};
+
+struct InheritsMemInt : MemInt { };
+
+struct MemIntFunc {
+ static int m(int);
+};
+
+template struct DotMemRef0<MemInt, int&>;
+template struct DotMemRef0<InheritsMemInt, int&>;
+template struct DotMemRef0<MemIntFunc, int (*)(int)>;
+template struct DotMemRef0<MemInt, float&>; // expected-note{{instantiation}}
+
+template<typename T, typename Result>
+struct ArrowMemRef0 {
+ void f(T t) {
+ Result result = t->m; // expected-error 2{{non-const lvalue reference}}
+ }
+};
+
+template<typename T>
+struct ArrowWrapper {
+ T operator->();
+};
+
+template struct ArrowMemRef0<MemInt*, int&>;
+template struct ArrowMemRef0<InheritsMemInt*, int&>;
+template struct ArrowMemRef0<MemIntFunc*, int (*)(int)>;
+template struct ArrowMemRef0<MemInt*, float&>; // expected-note{{instantiation}}
+
+template struct ArrowMemRef0<ArrowWrapper<MemInt*>, int&>;
+template struct ArrowMemRef0<ArrowWrapper<InheritsMemInt*>, int&>;
+template struct ArrowMemRef0<ArrowWrapper<MemIntFunc*>, int (*)(int)>;
+template struct ArrowMemRef0<ArrowWrapper<MemInt*>, float&>; // expected-note{{instantiation}}
+template struct ArrowMemRef0<ArrowWrapper<ArrowWrapper<MemInt*> >, int&>;
+
+struct UnresolvedMemRefArray {
+ int f(int);
+ int f(char);
+};
+UnresolvedMemRefArray Arr[10];
+template<typename U> int UnresolvedMemRefArrayT(U u) {
+ return Arr->f(u);
+}
+template int UnresolvedMemRefArrayT<int>(int);
+
+// FIXME: we should be able to return a MemInt without the reference!
+MemInt &createMemInt(int);
+
+template<int N>
+struct NonDepMemberExpr0 {
+ void f() {
+ createMemInt(N).m = N;
+ }
+};
+
+template struct NonDepMemberExpr0<0>;
+
+template<typename T, typename Result>
+struct MemberFuncCall0 {
+ void f(T t) {
+ Result result = t.f();
+ }
+};
+
+template<typename T>
+struct HasMemFunc0 {
+ T f();
+};
+
+
+template struct MemberFuncCall0<HasMemFunc0<int&>, const int&>;
+
+template<typename Result>
+struct ThisMemberFuncCall0 {
+ Result g();
+
+ void f() {
+ Result r1 = g();
+ Result r2 = this->g();
+ }
+};
+
+template struct ThisMemberFuncCall0<int&>;
+
+template<typename T>
+struct NonDepMemberCall0 {
+ void foo(HasMemFunc0<int&> x) {
+ T result = x.f(); // expected-error{{non-const lvalue reference}}
+ }
+};
+
+template struct NonDepMemberCall0<int&>;
+template struct NonDepMemberCall0<const int&>;
+template struct NonDepMemberCall0<float&>; // expected-note{{instantiation}}
+
+
+template<typename T>
+struct QualifiedDeclRef0 {
+ T f() {
+ return is_pod<X>::value; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'const bool'}}
+ }
+};
+
+template struct QualifiedDeclRef0<bool>;
+template struct QualifiedDeclRef0<int&>; // expected-note{{instantiation}}
diff --git a/clang/test/SemaTemplate/instantiate-expr-5.cpp b/clang/test/SemaTemplate/instantiate-expr-5.cpp
new file mode 100644
index 0000000..13b7eae
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-expr-5.cpp
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <class A> int x(A x) { return x++; }
+int y() { return x<int>(1); }
+
+namespace PR5880 {
+ template<typename T>
+ struct A {
+ static const int a = __builtin_offsetof(T, a.array[5].m); // expected-error{{no member named 'a' in 'HasM'}}
+ };
+ struct HasM {
+ float m;
+ };
+
+ struct ArrayOfHasM {
+ HasM array[10];
+ };
+
+ struct B { ArrayOfHasM a; };
+ A<B> x;
+ A<HasM> x2; // expected-note{{in instantiation of}}
+
+ template<typename T>
+ struct AnonymousUnion {
+ union {
+ int i;
+ float f;
+ };
+ };
+
+ template<typename T>
+ void test_anon_union() {
+ int array1[__builtin_offsetof(AnonymousUnion<T>, f) == 0? 1 : -1];
+ int array2[__builtin_offsetof(AnonymousUnion<int>, f) == 0? 1 : -1];
+ }
+
+ template void test_anon_union<int>();
+}
diff --git a/clang/test/SemaTemplate/instantiate-expr-basic.cpp b/clang/test/SemaTemplate/instantiate-expr-basic.cpp
new file mode 100644
index 0000000..a266a65
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-expr-basic.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -Wno-unused-value -std=c++11 %s
+
+template <typename T>
+struct S {
+ void f() {
+ __func__; // PredefinedExpr
+ 10; // IntegerLiteral
+ 10.5; // FloatingLiteral
+ 'c'; // CharacterLiteral
+ "hello"; // StringLiteral
+ true; // CXXBooleanLiteralExpr
+ nullptr; // CXXNullPtrLiteralExpr
+ __null; // GNUNullExpr
+ }
+};
+
+template struct S<int>;
diff --git a/clang/test/SemaTemplate/instantiate-field.cpp b/clang/test/SemaTemplate/instantiate-field.cpp
new file mode 100644
index 0000000..a148ee4
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-field.cpp
@@ -0,0 +1,104 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X {
+ int x;
+ T y; // expected-error{{data member instantiated with function type}}
+ T* z;
+ T bitfield : 12; // expected-error{{bit-field 'bitfield' has non-integral type 'float'}} \
+ // expected-error{{data member instantiated with function type}}
+
+ mutable T x2; // expected-error{{data member instantiated with function type}}
+};
+
+void test1(const X<int> *xi) {
+ int i1 = xi->x;
+ const int &i2 = xi->y;
+ int* ip1 = xi->z;
+ int i3 = xi->bitfield;
+ xi->x2 = 17;
+}
+
+void test2(const X<float> *xf) {
+ (void)xf->x; // expected-note{{in instantiation of template class 'X<float>' requested here}}
+}
+
+void test3(const X<int(int)> *xf) {
+ (void)xf->x; // expected-note{{in instantiation of template class 'X<int (int)>' requested here}}
+}
+
+namespace PR7123 {
+ template <class > struct requirement_;
+
+ template <void(*)()> struct instantiate
+ { };
+
+ template <class > struct requirement ;
+ struct failed ;
+
+ template <class Model> struct requirement<failed *Model::*>
+ {
+ static void failed()
+ {
+ ((Model*)0)->~Model(); // expected-note{{in instantiation of}}
+ }
+ };
+
+ template <class Model> struct requirement_<void(*)(Model)> : requirement<failed *Model::*>
+ { };
+
+ template <int> struct Requires_
+ { typedef void type; };
+
+ template <class Model> struct usage_requirements
+ {
+ ~usage_requirements()
+ {((Model*)0)->~Model(); } // expected-note{{in instantiation of}}
+ };
+
+ template < typename TT > struct BidirectionalIterator
+ {
+ enum
+ { value = 0 };
+
+ instantiate< requirement_<void(*)(usage_requirements<BidirectionalIterator>)>::failed> int534; // expected-note{{in instantiation of}}
+
+ ~BidirectionalIterator()
+ { i--; } // expected-error{{cannot decrement value of type 'PR7123::X'}}
+
+ TT i;
+ };
+
+ struct X
+ { };
+
+ template<typename RanIter>
+ typename Requires_< BidirectionalIterator<RanIter>::value >::type sort(RanIter,RanIter){}
+
+ void f()
+ {
+ X x;
+ sort(x,x);
+ }
+}
+
+namespace PR7355 {
+ template<typename T1> class A {
+ class D; // expected-note{{declared here}}
+ D d; //expected-error{{implicit instantiation of undefined member 'PR7355::A<int>::D'}}
+ };
+
+ A<int> ai; // expected-note{{in instantiation of}}
+}
+
+namespace PR8712 {
+ template <int dim>
+ class B {
+ public:
+ B(const unsigned char i);
+ unsigned char value : (dim > 0 ? dim : 1);
+ };
+
+ template <int dim>
+ inline B<dim>::B(const unsigned char i) : value(i) {}
+}
diff --git a/clang/test/SemaTemplate/instantiate-friend-class.cpp b/clang/test/SemaTemplate/instantiate-friend-class.cpp
new file mode 100644
index 0000000..c87b8d0
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-friend-class.cpp
@@ -0,0 +1,9 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR4794
+
+template <class T> class X
+{
+ friend class Y;
+};
+X<int> y;
+
diff --git a/clang/test/SemaTemplate/instantiate-function-1.cpp b/clang/test/SemaTemplate/instantiate-function-1.cpp
new file mode 100644
index 0000000..ceef274
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-function-1.cpp
@@ -0,0 +1,249 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -verify %s
+template<typename T, typename U>
+struct X0 {
+ void f(T x, U y) {
+ (void)(x + y); // expected-error{{invalid operands}}
+ }
+};
+
+struct X1 { };
+
+template struct X0<int, float>;
+template struct X0<int*, int>;
+template struct X0<int X1::*, int>; // expected-note{{instantiation of}}
+
+template<typename T>
+struct X2 {
+ void f(T);
+
+ T g(T x, T y) {
+ /* DeclStmt */;
+ T *xp = &x, &yr = y; // expected-error{{pointer to a reference}}
+ /* NullStmt */;
+ }
+};
+
+template struct X2<int>;
+template struct X2<int&>; // expected-note{{instantiation of}}
+
+template<typename T>
+struct X3 {
+ void f(T) {
+ Label:
+ T x;
+ goto Label;
+ }
+};
+
+template struct X3<int>;
+
+template <typename T> struct X4 {
+ T f() const {
+ return; // expected-error{{non-void function 'f' should return a value}}
+ }
+
+ T g() const {
+ return 1; // expected-error{{void function 'g' should not return a value}}
+ }
+};
+
+template struct X4<void>; // expected-note{{in instantiation of}}
+template struct X4<int>; // expected-note{{in instantiation of}}
+
+struct Incomplete; // expected-note 2{{forward declaration}}
+
+template<typename T> struct X5 {
+ T f() { } // expected-error{{incomplete result type}}
+};
+void test_X5(X5<Incomplete> x5); // okay!
+
+template struct X5<Incomplete>; // expected-note{{instantiation}}
+
+template<typename T, typename U, typename V> struct X6 {
+ U f(T t, U u, V v) {
+ // IfStmt
+ if (t > 0)
+ return u;
+ else {
+ if (t < 0)
+ return v; // expected-error{{cannot initialize return object of type}}
+ }
+
+ if (T x = t) {
+ t = x;
+ }
+ return v; // expected-error{{cannot initialize return object of type}}
+ }
+};
+
+struct ConvertibleToInt {
+ operator int() const;
+};
+
+template struct X6<ConvertibleToInt, float, char>;
+template struct X6<bool, int, int*>; // expected-note{{instantiation}}
+
+template <typename T> struct X7 {
+ void f() {
+ void *v = this;
+ }
+};
+
+template struct X7<int>;
+
+template<typename T> struct While0 {
+ void f(T t) {
+ while (t) {
+ }
+
+ while (T t2 = T()) ;
+ }
+};
+
+template struct While0<float>;
+
+template<typename T> struct Do0 {
+ void f(T t) {
+ do {
+ } while (t); // expected-error{{not contextually}}
+ }
+};
+
+struct NotConvertibleToBool { };
+template struct Do0<ConvertibleToInt>;
+template struct Do0<NotConvertibleToBool>; // expected-note{{instantiation}}
+
+template<typename T> struct For0 {
+ void f(T f, T l) {
+ for (; f != l; ++f) {
+ if (*f)
+ continue;
+ else if (*f == 17)
+ break;
+ }
+ }
+};
+
+template struct For0<int*>;
+
+template<typename T> struct Member0 {
+ void f(T t) {
+ t;
+ t.f;
+ t->f;
+
+ T* tp;
+ tp.f; // expected-error{{member reference base type 'T *' is not a structure or union}}
+ tp->f;
+
+ this->f;
+ this.f; // expected-error{{member reference base type 'Member0<T> *' is not a structure or union}}
+ }
+};
+
+template<typename T, typename U> struct Switch0 {
+ U f(T value, U v0, U v1, U v2) {
+ switch (value) {
+ case 0: return v0;
+
+ case 1: return v1;
+
+ case 2: // fall through
+
+ default:
+ return v2;
+ }
+ }
+};
+
+template struct Switch0<int, float>;
+
+template<typename T, int I1, int I2> struct Switch1 {
+ T f(T x, T y, T z) {
+ switch (x) {
+ case I1: return y; // expected-note{{previous}}
+ case I2: return z; // expected-error{{duplicate}}
+ default: return x;
+ }
+ }
+};
+
+template struct Switch1<int, 1, 2>;
+template struct Switch1<int, 2, 2>; // expected-note{{instantiation}}
+
+template<typename T> struct IndirectGoto0 {
+ void f(T x) {
+ // FIXME: crummy error message below
+ goto *x; // expected-error{{incompatible}}
+
+ prior:
+ T prior_label;
+ prior_label = &&prior; // expected-error{{assigning to 'int'}}
+
+ T later_label;
+ later_label = &&later; // expected-error{{assigning to 'int'}}
+
+ later:
+ (void)(1+1);
+ }
+};
+
+template struct IndirectGoto0<void*>;
+template struct IndirectGoto0<int>; // expected-note{{instantiation}}
+
+template<typename T> struct TryCatch0 {
+ void f() {
+ try {
+ } catch (T t) { // expected-error{{incomplete type}} \
+ // expected-error{{abstract class}}
+ } catch (...) {
+ }
+ }
+};
+
+struct Abstract {
+ virtual void foo() = 0; // expected-note{{pure virtual}}
+};
+
+template struct TryCatch0<int>; // okay
+template struct TryCatch0<Incomplete*>; // expected-note{{instantiation}}
+template struct TryCatch0<Abstract>; // expected-note{{instantiation}}
+
+// PR4383
+template<typename T> struct X;
+template<typename T> struct Y : public X<T> {
+ Y& x() { return *this; }
+};
+
+// Make sure our assertions don't get too uppity.
+namespace test0 {
+ template <class T> class A { void foo(T array[10]); };
+ template class A<int>;
+}
+
+namespace PR7016 {
+ template<typename T> void f() { T x = x; }
+ template void f<int>();
+}
+
+namespace PR9880 {
+ struct lua_State;
+ struct no_tag { char a; }; // (A)
+ struct yes_tag { long a; long b; }; // (A)
+
+ template <typename T>
+ struct HasIndexMetamethod {
+ template <typename U>
+ static no_tag check(...);
+ template <typename U>
+ static yes_tag check(char[sizeof(&U::luaIndex)]);
+ enum { value = sizeof(check<T>(0)) == sizeof(yes_tag) };
+ };
+
+ class SomeClass {
+ public:
+ int luaIndex(lua_State* L);
+ };
+
+ int i = HasIndexMetamethod<SomeClass>::value;
+}
diff --git a/clang/test/SemaTemplate/instantiate-function-1.mm b/clang/test/SemaTemplate/instantiate-function-1.mm
new file mode 100644
index 0000000..c67b598
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-function-1.mm
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// XFAIL: *
+
+template<typename T> struct Member0 {
+ void f(T t) {
+ t;
+ t.f;
+ t->f;
+
+ T* tp;
+ tp.f;
+ tp->f;
+
+ this->f;
+ this.f; // expected-error{{member reference base type 'struct Member0 *const' is not a structure or union}}
+ }
+};
diff --git a/clang/test/SemaTemplate/instantiate-function-2.cpp b/clang/test/SemaTemplate/instantiate-function-2.cpp
new file mode 100644
index 0000000..19a8b61
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-function-2.cpp
@@ -0,0 +1,66 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template <typename T> struct S {
+ S() { }
+ S(T t);
+};
+
+template struct S<int>;
+
+void f() {
+ S<int> s1;
+ S<int> s2(10);
+}
+
+namespace PR7184 {
+ template<typename T>
+ void f() {
+ typedef T type;
+ void g(int array[sizeof(type)]);
+ }
+
+ template void f<int>();
+}
+
+namespace UsedAttr {
+ template<typename T>
+ void __attribute__((used)) foo() {
+ T *x = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+ }
+
+ void bar() {
+ foo<int>(); // expected-note{{instantiation of}}
+ }
+}
+
+namespace PR9654 {
+ typedef void ftype(int);
+
+ template<typename T>
+ ftype f;
+
+ void g() {
+ f<int>(0);
+ }
+}
+
+namespace AliasTagDef {
+ template<typename T>
+ T f() {
+ using S = struct { // expected-warning {{C++11}}
+ T g() {
+ return T();
+ }
+ };
+ return S().g();
+ }
+
+ int n = f<int>();
+}
+
+namespace PR10273 {
+ template<typename T> void (f)(T t) {}
+
+ void g() {
+ (f)(17);
+ }
+}
diff --git a/clang/test/SemaTemplate/instantiate-function-params.cpp b/clang/test/SemaTemplate/instantiate-function-params.cpp
new file mode 100644
index 0000000..54847e4
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-function-params.cpp
@@ -0,0 +1,90 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR6619
+template<bool C> struct if_c { };
+template<typename T1> struct if_ {
+ typedef if_c< static_cast<bool>(T1::value)> almost_type_; // expected-note 5{{in instantiation}}
+};
+template <class Model, void (Model::*)()> struct wrap_constraints { };
+template <class Model>
+inline char has_constraints_(Model* , // expected-note 2{{while substituting deduced template arguments into function template 'has_constraints_' [with }} \
+ // expected-note 3{{candidate template ignored}}
+ wrap_constraints<Model,&Model::constraints>* = 0); // expected-note 2{{in instantiation}}
+
+template <class Model> struct not_satisfied {
+ static const bool value = sizeof( has_constraints_((Model*)0) == 1); // expected-error 3{{no matching function}}
+};
+template <class ModelFn> struct requirement_;
+template <void(*)()> struct instantiate {
+};
+template <class Model> struct requirement_<void(*)(Model)> : if_< not_satisfied<Model> >::type { // expected-note 5{{in instantiation}}
+};
+template <class Model> struct usage_requirements {
+};
+template < typename TT > struct InputIterator {
+ typedef instantiate< & requirement_<void(*)(usage_requirements<InputIterator> x)>::failed> boost_concept_check1; // expected-note {{in instantiation}}
+};
+template < typename TT > struct ForwardIterator : InputIterator<TT> { // expected-note {{in instantiation}}
+ typedef instantiate< & requirement_<void(*)(usage_requirements<ForwardIterator> x)>::failed> boost_concept_check2; // expected-note {{in instantiation}}
+
+};
+typedef instantiate< &requirement_<void(*)(ForwardIterator<char*> x)>::failed> boost_concept_checkX;// expected-note 3{{in instantiation}}
+
+template<typename T> struct X0 { };
+template<typename R, typename A1> struct X0<R(A1 param)> { };
+
+template<typename T, typename A1, typename A2>
+void instF0(X0<T(A1)> x0a, X0<T(A2)> x0b) {
+ X0<T(A1)> x0c;
+ X0<T(A2)> x0d;
+}
+
+template void instF0<int, int, float>(X0<int(int)>, X0<int(float)>);
+
+template<typename R, typename A1, R (*ptr)(A1)> struct FuncPtr { };
+template<typename A1, int (*ptr)(A1)> struct FuncPtr<int, A1, ptr> { };
+
+template<typename R, typename A1> R unary_func(A1);
+
+template<typename R, typename A1, typename A2>
+void use_func_ptr() {
+ FuncPtr<R, A1, &unary_func<R, A1> > fp1;
+ FuncPtr<R, A2, &unary_func<R, A2> > fp2;
+};
+
+template void use_func_ptr<int, float, double>();
+
+namespace PR6990 {
+ template < typename , typename = int, typename = int > struct X1;
+ template <typename >
+ struct X2;
+
+ template <typename = int *, typename TokenT = int,
+ typename = int( X2<TokenT> &)>
+ struct X3
+ {
+ };
+
+ template <typename , typename P>
+ struct X3_base : X3< X1<int, P> >
+ {
+ protected: typedef X1< P> type;
+ X3<type> e;
+ };
+
+ struct r : X3_base<int, int>
+ {
+ };
+}
+
+namespace InstantiateFunctionTypedef {
+ template<typename T>
+ struct X {
+ typedef int functype(int, int);
+ functype func;
+ };
+
+ void f(X<int> x) {
+ (void)x.func(1, 2);
+ }
+}
diff --git a/clang/test/SemaTemplate/instantiate-init.cpp b/clang/test/SemaTemplate/instantiate-init.cpp
new file mode 100644
index 0000000..f0ca9a5
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-init.cpp
@@ -0,0 +1,109 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct X0 { // expected-note 4{{candidate}}
+ X0(int*, float*); // expected-note 4{{candidate}}
+};
+
+template<typename T, typename U>
+X0 f0(T t, U u) {
+ X0 x0(t, u); // expected-error{{no matching}}
+ return X0(t, u); // expected-error{{no matching}}
+}
+
+void test_f0(int *ip, float *fp, double *dp) {
+ f0(ip, fp);
+ f0(ip, dp); // expected-note{{instantiation}}
+}
+
+template<typename Ret, typename T, typename U>
+Ret f1(Ret *retty, T t, U u) {
+ Ret r0(t, u); // expected-error{{no matching}}
+ return Ret(t, u); // expected-error{{no matching}}
+}
+
+void test_f1(X0 *x0, int *ip, float *fp, double *dp) {
+ f1(x0, ip, fp);
+ f1(x0, ip, dp); // expected-note{{instantiation}}
+}
+
+namespace PR6457 {
+ template <typename T> struct X { explicit X(T* p = 0) { }; };
+ template <typename T> struct Y { Y(int, const T& x); };
+ struct A { };
+ template <typename T>
+ struct B {
+ B() : y(0, X<A>()) { }
+ Y<X<A> > y;
+ };
+ B<int> b;
+}
+
+namespace PR6657 {
+ struct X
+ {
+ X (int, int) { }
+ };
+
+ template <typename>
+ void f0()
+ {
+ X x = X(0, 0);
+ }
+
+ void f1()
+ {
+ f0<int>();
+ }
+}
+
+// Instantiate out-of-line definitions of static data members which complete
+// types through an initializer even when the only use of the member that would
+// cause instantiation is in an unevaluated context, but one requiring its
+// complete type.
+namespace PR10001 {
+ template <typename T> struct S {
+ static const int arr[];
+ static const int x;
+ static int f();
+ };
+
+ template <typename T> const int S<T>::arr[] = { 1, 2, 3 };
+ template <typename T> const int S<T>::x = sizeof(arr) / sizeof(arr[0]);
+ template <typename T> int S<T>::f() { return x; }
+
+ int x = S<int>::f();
+}
+
+namespace PR7985 {
+ template<int N> struct integral_c { };
+
+ template <typename T, int N>
+ integral_c<N> array_lengthof(T (&x)[N]) { return integral_c<N>(); } // expected-note 2{{candidate template ignored: failed template argument deduction}}
+
+ template<typename T>
+ struct Data {
+ T x;
+ };
+
+ template<typename T>
+ struct Description {
+ static const Data<T> data[];
+ };
+
+ template<typename T>
+ const Data<T> Description<T>::data[] = {{ 1 }}; // expected-error{{cannot initialize a member subobject of type 'int *' with an rvalue of type 'int'}}
+
+ template<>
+ Data<float*> Description<float*>::data[];
+
+ void test() {
+ integral_c<1> ic1 = array_lengthof(Description<int>::data);
+ (void)sizeof(array_lengthof(Description<float>::data));
+
+ sizeof(array_lengthof( // expected-error{{no matching function for call to 'array_lengthof'}}
+ Description<int*>::data // expected-note{{in instantiation of static data member 'PR7985::Description<int *>::data' requested here}}
+ ));
+
+ array_lengthof(Description<float*>::data); // expected-error{{no matching function for call to 'array_lengthof'}}
+ }
+}
diff --git a/clang/test/SemaTemplate/instantiate-invalid.cpp b/clang/test/SemaTemplate/instantiate-invalid.cpp
new file mode 100644
index 0000000..b8a5901
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-invalid.cpp
@@ -0,0 +1,52 @@
+// RUN: not %clang_cc1 -fsyntax-only %s
+namespace PR6375 {
+ template<class Conv> class rasterizer_sl_clip Conv::xi(x2), Conv::yi(y2));
+namespace agg
+{
+ template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa
+ {
+ template<class Scanline> bool sweep_scanline(Scanline& sl)
+ {
+ unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
+ while(num_cells) { }
+ }
+ }
+ class scanline_u8 {}
+ template<class PixelFormat> class renderer_base { }
+}
+ template<class Rasterizer, class Scanline, class BaseRenderer, class ColorT>
+ void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, const ColorT& color)
+ {
+ while(ras.sweep_scanline(sl))
+ {
+ }
+ };
+namespace agg
+{
+ struct rgba8
+ {
+ };
+ template<class Rasterizer, class Scanline, class Renderer, class Ctrl>
+ void render_ctrl(Rasterizer& ras, Scanline& sl, Renderer& r, Ctrl& c)
+ {
+ unsigned i;
+ render_scanlines_aa_solid(ras, sl, r, c.color(i));
+ }
+ template<class ColorT> class rbox_ctrl : public rbox_ctrl_impl
+ {
+ const ColorT& color(unsigned i) const { return *m_colors[i]; }
+ }
+class the_application : public agg::platform_support
+{
+ agg::rbox_ctrl<agg::rgba8> m_polygons;
+ virtual void on_init()
+ {
+ typedef agg::renderer_base<pixfmt_type> base_ren_type;
+ base_ren_type ren_base(pf);
+ agg::scanline_u8 sl;
+ agg::rasterizer_scanline_aa<> ras;
+ agg::render_ctrl(ras, sl, ren_base, m_polygons);
+ }
+};
+}
+}
diff --git a/clang/test/SemaTemplate/instantiate-local-class.cpp b/clang/test/SemaTemplate/instantiate-local-class.cpp
new file mode 100644
index 0000000..20b62c1
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-local-class.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -verify %s
+template<typename T>
+void f0() {
+ struct X;
+ typedef struct Y {
+ T (X::* f1())(int) { return 0; }
+ } Y2;
+
+ Y2 y = Y();
+}
+
+template void f0<int>();
+
+// PR5764
+namespace PR5764 {
+ struct X {
+ template <typename T>
+ void Bar() {
+ typedef T ValueType;
+ struct Y {
+ Y() { V = ValueType(); }
+
+ ValueType V;
+ };
+
+ Y y;
+ }
+ };
+
+ void test(X x) {
+ x.Bar<int>();
+ }
+}
+
+// Instantiation of local classes with virtual functions.
+namespace local_class_with_virtual_functions {
+ template <typename T> struct X { };
+ template <typename T> struct Y { };
+
+ template <typename T>
+ void f() {
+ struct Z : public X<Y<T>*> {
+ virtual void g(Y<T>* y) { }
+ void g2(int x) {(void)x;}
+ };
+ Z z;
+ (void)z;
+ }
+
+ struct S { };
+ void test() { f<S>(); }
+}
+
+namespace PR8801 {
+ template<typename T>
+ void foo() {
+ class X;
+ typedef int (X::*pmf_type)();
+ class X : public T { };
+
+ pmf_type pmf = &T::foo;
+ }
+
+ struct Y { int foo(); };
+
+ template void foo<Y>();
+}
diff --git a/clang/test/SemaTemplate/instantiate-member-class.cpp b/clang/test/SemaTemplate/instantiate-member-class.cpp
new file mode 100644
index 0000000..bb64276
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-member-class.cpp
@@ -0,0 +1,142 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR8965 {
+ template<typename T>
+ struct X {
+ typedef int type;
+
+ T field; // expected-note{{in instantiation of member class}}
+ };
+
+ template<typename T>
+ struct Y {
+ struct Inner;
+
+ typedef typename X<Inner>::type // expected-note{{in instantiation of template class}}
+ type; // expected-note{{not-yet-instantiated member is declared here}}
+
+ struct Inner {
+ typedef type field; // expected-error{{no member 'type' in 'PR8965::Y<int>'; it has not yet been instantiated}}
+ };
+ };
+
+ Y<int> y; // expected-note{{in instantiation of template class}}
+}
+
+template<typename T>
+class X {
+public:
+ struct C { T &foo(); };
+
+ struct D {
+ struct E { T &bar(); }; // expected-error{{cannot form a reference to 'void'}}
+ struct F; // expected-note{{member is declared here}}
+ };
+};
+
+X<int>::C *c1;
+X<float>::C *c2;
+
+X<int>::X *xi; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}}
+X<float>::X *xf; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}}
+
+void test_naming() {
+ c1 = c2; // expected-error{{assigning to 'X<int>::C *' from incompatible type 'X<float>::C *'}}
+ xi = xf; // expected-error{{assigning to 'X<int>::X<int> *' from incompatible type 'X<float>::X<float> *'}}
+ // FIXME: error above doesn't print the type X<int>::X cleanly!
+}
+
+void test_instantiation(X<double>::C *x,
+ X<float>::D::E *e,
+ X<float>::D::F *f) {
+ double &dr = x->foo();
+ float &fr = e->bar();
+ f->foo(); // expected-error{{implicit instantiation of undefined member 'X<float>::D::F'}}
+
+}
+
+
+X<void>::C *c3; // okay
+X<void>::D::E *e1; // okay
+X<void>::D::E e2; // expected-note{{in instantiation of member class 'X<void>::D::E' requested here}}
+
+// Redeclarations.
+namespace test1 {
+ template <typename T> struct Registry {
+ struct node;
+ static node *Head;
+ struct node {
+ node(int v) { Head = this; }
+ };
+ };
+ void test() {
+ Registry<int>::node node(0);
+ }
+}
+
+// Redeclarations during explicit instantiations.
+namespace test2 {
+ template <typename T> class A {
+ class Foo;
+ class Foo {
+ int foo();
+ };
+ };
+ template class A<int>;
+
+ template <typename T> class B {
+ class Foo;
+ class Foo {
+ public:
+ typedef int X;
+ };
+ typename Foo::X x;
+ class Foo;
+ };
+ template class B<int>;
+
+ template <typename T> class C {
+ class Foo;
+ class Foo;
+ };
+ template <typename T> class C<T>::Foo {
+ int x;
+ };
+ template class C<int>;
+}
+
+namespace AliasTagDef {
+ template<typename T>
+ struct F {
+ using S = struct U { // expected-warning {{C++11}}
+ T g() {
+ return T();
+ }
+ };
+ };
+
+ int m = F<int>::S().g();
+ int n = F<int>::U().g();
+}
+
+namespace rdar10397846 {
+ template<int I> struct A
+ {
+ struct B
+ {
+ struct C { C() { int *ptr = I; } }; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+ };
+ };
+
+ template<int N> void foo()
+ {
+ class A<N>::B::C X; // expected-note{{in instantiation of member function}}
+ int A<N+1>::B::C::*member = 0;
+ }
+
+ void bar()
+ {
+ foo<0>();
+ foo<1>(); // expected-note{{in instantiation of function template}}
+ }
+}
diff --git a/clang/test/SemaTemplate/instantiate-member-expr.cpp b/clang/test/SemaTemplate/instantiate-member-expr.cpp
new file mode 100644
index 0000000..a31569a
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-member-expr.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct S {
+ S() { }
+};
+
+template<typename T>
+struct vector {
+ void push_back(const T&) { int a[sizeof(T) ? -1: -1]; } // expected-error {{array with a negative size}}
+};
+
+class ExprEngine {
+public:
+ typedef vector<S<void *> >CheckersOrdered;
+ CheckersOrdered Checkers;
+
+ template <typename CHECKER>
+ void registerCheck(CHECKER *check) {
+ Checkers.push_back(S<void *>()); // expected-note {{in instantiation of member function 'vector<S<void *> >::push_back' requested here}}
+ }
+};
+
+class RetainReleaseChecker { };
+
+void f(ExprEngine& Eng) {
+ Eng.registerCheck(new RetainReleaseChecker); // expected-note {{in instantiation of function template specialization 'ExprEngine::registerCheck<RetainReleaseChecker>' requested here}}
+}
+
+// PR 5838
+namespace test1 {
+ template<typename T> struct A {
+ int a;
+ };
+
+ template<typename T> struct B : A<float>, A<T> {
+ void f() {
+ a = 0; // should not be ambiguous
+ }
+ };
+ template struct B<int>;
+
+ struct O {
+ int a;
+ template<typename T> struct B : A<T> {
+ void f() {
+ a = 0; // expected-error {{'test1::O::a' is not a member of class 'test1::O::B<int>'}}
+ }
+ };
+ };
+ template struct O::B<int>; // expected-note {{in instantiation}}
+}
+
+// PR7248
+namespace test2 {
+ template <class T> struct A {
+ void foo() {
+ T::bar(); // expected-error {{type 'int' cannot}}
+ }
+ };
+
+ template <class T> class B {
+ void foo(A<T> a) {
+ a.test2::template A<T>::foo(); // expected-note {{in instantiation}}
+ }
+ };
+
+ template class B<int>;
+}
diff --git a/clang/test/SemaTemplate/instantiate-member-initializers.cpp b/clang/test/SemaTemplate/instantiate-member-initializers.cpp
new file mode 100644
index 0000000..45503b3
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-member-initializers.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -fsyntax-only -Wall -verify %s
+
+template<typename T> struct A {
+ A() : a(1) { } // expected-error{{cannot initialize a member subobject of type 'void *' with an rvalue of type 'int'}}
+
+ T a;
+};
+
+A<int> a0;
+A<void*> a1; // expected-note{{in instantiation of member function 'A<void *>::A' requested here}}
+
+template<typename T> struct B {
+ B() : b(1), // expected-warning {{field 'b' will be initialized after field 'a'}}
+ a(2) { }
+
+ int a;
+ int b;
+};
+
+B<int> b0; // expected-note {{in instantiation of member function 'B<int>::B' requested here}}
+
+template <class T> struct AA { AA(int); };
+template <class T> class BB : public AA<T> {
+public:
+ BB() : AA<T>(1) {}
+};
+BB<int> x;
diff --git a/clang/test/SemaTemplate/instantiate-member-pointers.cpp b/clang/test/SemaTemplate/instantiate-member-pointers.cpp
new file mode 100644
index 0000000..0db90e3
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-member-pointers.cpp
@@ -0,0 +1,67 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+struct Y {
+ int x;
+};
+
+template<typename T>
+struct X1 {
+ int f(T* ptr, int T::*pm) { // expected-error{{member pointer}}
+ return ptr->*pm;
+ }
+};
+
+template struct X1<Y>;
+template struct X1<int>; // expected-note{{instantiation}}
+
+template<typename T, typename Class>
+struct X2 {
+ T f(Class &obj, T Class::*pm) { // expected-error{{to a reference}} \
+ // expected-error{{member pointer to void}}
+ return obj.*pm;
+ }
+};
+
+template struct X2<int, Y>;
+template struct X2<int&, Y>; // expected-note{{instantiation}}
+template struct X2<const void, Y>; // expected-note{{instantiation}}
+
+template<typename T, typename Class, T Class::*Ptr>
+struct X3 {
+ X3<T, Class, Ptr> &operator=(const T& value) {
+ return *this;
+ }
+};
+
+X3<int, Y, &Y::x> x3;
+
+typedef int Y::*IntMember;
+
+template<IntMember Member>
+struct X4 {
+ X3<int, Y, Member> member;
+
+ int &getMember(Y& y) { return y.*Member; }
+};
+
+int &get_X4(X4<&Y::x> x4, Y& y) {
+ return x4.getMember(y);
+}
+
+template<IntMember Member>
+void accept_X4(X4<Member>);
+
+void test_accept_X4(X4<&Y::x> x4) {
+ accept_X4(x4);
+}
+
+namespace ValueDepMemberPointer {
+ template <void (*)()> struct instantiate_function {};
+ template <typename T> struct S {
+ static void instantiate();
+ typedef instantiate_function<&S::instantiate> x; // expected-note{{instantiation}}
+ };
+ template <typename T> void S<T>::instantiate() {
+ int a[(int)sizeof(T)-42]; // expected-error{{array with a negative size}}
+ }
+ S<int> s;
+}
diff --git a/clang/test/SemaTemplate/instantiate-member-template.cpp b/clang/test/SemaTemplate/instantiate-member-template.cpp
new file mode 100644
index 0000000..4c74f5f
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-member-template.cpp
@@ -0,0 +1,261 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct X0 {
+ template<typename U> T f0(U);
+ template<typename U> U& f1(T*, U); // expected-error{{pointer to a reference}} \
+ // expected-note{{candidate}}
+};
+
+X0<int> x0i;
+X0<void> x0v;
+X0<int&> x0ir; // expected-note{{instantiation}}
+
+void test_X0(int *ip, double *dp) {
+ X0<int> xi;
+ int i1 = xi.f0(ip);
+ double *&dpr = xi.f1(ip, dp);
+ xi.f1(dp, dp); // expected-error{{no matching}}
+
+ X0<void> xv;
+ double *&dpr2 = xv.f1(ip, dp);
+}
+
+template<typename T>
+struct X1 {
+ template<typename U>
+ struct Inner0 {
+ U x;
+ T y; // expected-error{{void}}
+ };
+
+ template<typename U>
+ struct Inner1 {
+ U x; // expected-error{{void}}
+ T y;
+ };
+
+ template<typename U>
+ struct Inner2 {
+ struct SuperInner {
+ U z; // expected-error{{void}}
+ };
+ };
+
+ template<typename U>
+ struct Inner3 {
+ void f0(T t, U u) { // expected-note{{passing argument to parameter 't' here}}
+ (void)(t + u); // expected-error{{invalid operands}}
+ }
+
+ template<typename V>
+ V f1(T t, U u, V) {
+ return t + u; // expected-error{{cannot initialize return object}}
+ }
+ };
+
+ template<typename U>
+ struct Inner4;
+};
+
+template<typename T>
+template<typename U>
+struct X1<T>::Inner4 {
+ template<typename V>
+ V f2(T t, U u, V);
+
+ static U value;
+};
+
+template<typename T>
+template<typename U>
+U X1<T>::Inner4<U>::value; // expected-error{{reference variable}}
+
+template<typename T>
+template<typename U>
+template<typename V>
+V X1<T>::Inner4<U>::f2(T t, U u, V) {
+ return t + u; // expected-error{{cannot initialize return object}}
+}
+
+void test_X1(int *ip, int i, double *dp) {
+ X1<void>::Inner0<int> *xvip; // okay
+ X1<void>::Inner0<int> xvi; // expected-note{{instantiation}}
+
+ X1<int>::Inner1<void> *xivp; // okay
+ X1<int>::Inner1<void> xiv; // expected-note{{instantiation}}
+
+ X1<int>::Inner2<void>::SuperInner *xisivp; // okay
+ X1<int>::Inner2<void>::SuperInner xisiv; // expected-note{{instantiation}}
+
+ X1<int*>::Inner3<int> id3;
+ id3.f0(ip, i);
+ id3.f0(dp, i); // expected-error{{cannot initialize a parameter of type 'int *' with an lvalue of type 'double *'}}
+ id3.f1(ip, i, ip);
+ id3.f1(ip, i, dp); // expected-note{{instantiation}}
+
+ X1<int*>::Inner3<double*> id3b;
+ id3b.f0(ip, dp); // expected-note{{instantiation}}
+
+ X1<int*>::Inner4<int> id4;
+ id4.f2(ip, i, dp); // expected-note{{instantiation}}
+
+ X1<int*>::Inner4<int>::value = 17;
+ i = X1<int*>::Inner4<int&>::value; // expected-note{{instantiation}}
+}
+
+
+template<typename T>
+struct X2 {
+ template<T *Ptr> // expected-error{{pointer to a reference}}
+ struct Inner;
+
+ template<T Value> // expected-error{{cannot have type 'float'}}
+ struct Inner2;
+};
+
+X2<int&> x2a; // expected-note{{instantiation}}
+X2<float> x2b; // expected-note{{instantiation}}
+
+namespace N0 {
+ template<typename T>
+ struct X0 { };
+
+ struct X1 {
+ template<typename T> void f(X0<T>& vals) { g(vals); }
+ template<typename T> void g(X0<T>& vals) { }
+ };
+
+ void test(X1 x1, X0<int> x0i, X0<long> x0l) {
+ x1.f(x0i);
+ x1.f(x0l);
+ }
+}
+
+namespace PR6239 {
+ template <typename T>
+ struct X0 {
+ class type {
+ typedef T E;
+ template <E e> // subsitute T for E and bug goes away
+ struct sfinae { };
+
+ template <class U>
+ typename sfinae<&U::operator=>::type test(int);
+ };
+ };
+
+ template <typename T>
+ struct X1 {
+ typedef T E;
+ template <E e> // subsitute T for E and bug goes away
+ struct sfinae { };
+
+ template <class U>
+ typename sfinae<&U::operator=>::type test(int);
+ };
+
+}
+
+namespace PR7587 {
+ template<typename> class X0;
+ template<typename> struct X1;
+ template<typename> class X2;
+
+ template<typename T> class X3
+ {
+ template<
+ template<typename> class TT,
+ typename U = typename X1<T>::type
+ >
+ struct Inner {
+ typedef X2<TT<typename X1<T>::type> > Type;
+ };
+
+ const typename Inner<X0>::Type minCoeff() const;
+ };
+
+ template<typename T> class X3<T*>
+ {
+ template<
+ template<typename> class TT,
+ typename U = typename X1<T>::type
+ >
+ struct Inner {
+ typedef X2<TT<typename X1<T>::type> > Type;
+ };
+
+ const typename Inner<X0>::Type minCoeff() const;
+ };
+
+}
+
+namespace PR7669 {
+ template<class> struct X {
+ template<class> struct Y {
+ template<int,class> struct Z;
+ template<int Dummy> struct Z<Dummy,int> {};
+ };
+ };
+
+ void a()
+ {
+ X<int>::Y<int>::Z<0,int>();
+ }
+}
+
+namespace PR8489 {
+ template <typename CT>
+ class C {
+ template<typename FT>
+ void F() {} // expected-note{{FT}}
+ };
+ void f() {
+ C<int> c;
+ c.F(); // expected-error{{no matching member function}}
+ }
+}
+
+namespace rdar8986308 {
+ template <bool> struct __static_assert_test;
+ template <> struct __static_assert_test<true> {};
+ template <unsigned> struct __static_assert_check {};
+
+ namespace std {
+
+ template <class _Tp, class _Up>
+ struct __has_rebind
+ {
+ private:
+ struct __two {char _; char __;};
+ template <class _Xp> static __two __test(...);
+ template <class _Xp> static char __test(typename _Xp::template rebind<_Up>* = 0);
+ public:
+ static const bool value = sizeof(__test<_Tp>(0)) == 1;
+ };
+
+ }
+
+ template <class T> struct B1 {};
+
+ template <class T>
+ struct B
+ {
+ template <class U> struct rebind {typedef B1<U> other;};
+ };
+
+ template <class T, class U> struct D1 {};
+
+ template <class T, class U>
+ struct D
+ {
+ template <class V> struct rebind {typedef D1<V, U> other;};
+ };
+
+ int main()
+ {
+ typedef __static_assert_check<sizeof(__static_assert_test<((std::__has_rebind<B<int>, double>::value))>)> __t64;
+ typedef __static_assert_check<sizeof(__static_assert_test<((std::__has_rebind<D<char, int>, double>::value))>)> __t64;
+ }
+
+}
diff --git a/clang/test/SemaTemplate/instantiate-method.cpp b/clang/test/SemaTemplate/instantiate-method.cpp
new file mode 100644
index 0000000..363115d
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-method.cpp
@@ -0,0 +1,177 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+class X {
+public:
+ void f(T x); // expected-error{{argument may not have 'void' type}}
+ void g(T*);
+
+ static int h(T, T); // expected-error {{argument may not have 'void' type}}
+};
+
+int identity(int x) { return x; }
+
+void test(X<int> *xi, int *ip, X<int(int)> *xf) {
+ xi->f(17);
+ xi->g(ip);
+ xf->f(&identity);
+ xf->g(identity);
+ X<int>::h(17, 25);
+ X<int(int)>::h(identity, &identity);
+}
+
+void test_bad() {
+ X<void> xv; // expected-note{{in instantiation of template class 'X<void>' requested here}}
+}
+
+template<typename T, typename U>
+class Overloading {
+public:
+ int& f(T, T); // expected-note{{previous declaration is here}}
+ float& f(T, U); // expected-error{{functions that differ only in their return type cannot be overloaded}}
+};
+
+void test_ovl(Overloading<int, long> *oil, int i, long l) {
+ int &ir = oil->f(i, i);
+ float &fr = oil->f(i, l);
+}
+
+void test_ovl_bad() {
+ Overloading<float, float> off; // expected-note{{in instantiation of template class 'Overloading<float, float>' requested here}}
+}
+
+template<typename T>
+class HasDestructor {
+public:
+ virtual ~HasDestructor() = 0;
+};
+
+int i = sizeof(HasDestructor<int>); // FIXME: forces instantiation, but
+ // the code below should probably instantiate by itself.
+int abstract_destructor[__is_abstract(HasDestructor<int>)? 1 : -1];
+
+
+template<typename T>
+class Constructors {
+public:
+ Constructors(const T&);
+ Constructors(const Constructors &other);
+};
+
+void test_constructors() {
+ Constructors<int> ci1(17);
+ Constructors<int> ci2 = ci1;
+}
+
+
+template<typename T>
+struct ConvertsTo {
+ operator T();
+};
+
+void test_converts_to(ConvertsTo<int> ci, ConvertsTo<int *> cip) {
+ int i = ci;
+ int *ip = cip;
+}
+
+// PR4660
+template<class T> struct A0 { operator T*(); };
+template<class T> struct A1;
+
+int *a(A0<int> &x0, A1<int> &x1) {
+ int *y0 = x0;
+ int *y1 = x1; // expected-error{{no viable conversion}}
+}
+
+struct X0Base {
+ int &f();
+ int& g(int);
+ static double &g(double);
+};
+
+template<typename T>
+struct X0 : X0Base {
+};
+
+template<typename U>
+struct X1 : X0<U> {
+ int &f2() {
+ return X0Base::f();
+ }
+};
+
+void test_X1(X1<int> x1i) {
+ int &ir = x1i.f2();
+}
+
+template<typename U>
+struct X2 : X0Base, U {
+ int &f2() { return X0Base::f(); }
+};
+
+template<typename T>
+struct X3 {
+ void test(T x) {
+ double& d1 = X0Base::g(x);
+ }
+};
+
+
+template struct X3<double>;
+
+// Don't try to instantiate this, it's invalid.
+namespace test1 {
+ template <class T> class A {};
+ template <class T> class B {
+ void foo(A<test1::Undeclared> &a) // expected-error {{no member named 'Undeclared' in namespace 'test1'}}
+ {}
+ };
+ template class B<int>;
+}
+
+namespace PR6947 {
+ template< class T >
+ struct X {
+ int f0( )
+ {
+ typedef void ( X::*impl_fun_ptr )( );
+ impl_fun_ptr pImpl = &X::template
+ f0_impl1<int>;
+ }
+ private:
+ int f1() {
+ }
+ template< class Processor>
+ void f0_impl1( )
+ {
+ }
+ };
+
+ char g0() {
+ X<int> pc;
+ pc.f0();
+ }
+
+}
+
+namespace PR7022 {
+ template <typename >
+ struct X1
+ {
+ typedef int state_t( );
+ state_t g ;
+ };
+
+ template < typename U = X1<int> > struct X2
+ {
+ X2( U = U())
+ {
+ }
+ };
+
+ void m(void)
+ {
+ typedef X2<> X2_type;
+ X2_type c;
+ }
+
+}
diff --git a/clang/test/SemaTemplate/instantiate-non-dependent-types.cpp b/clang/test/SemaTemplate/instantiate-non-dependent-types.cpp
new file mode 100644
index 0000000..a0005c5
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-non-dependent-types.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct X1 {
+ static void member() { T* x = 1; } // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}}
+};
+
+template<void(*)()> struct instantiate { };
+
+template<typename T>
+struct X2 {
+ typedef instantiate<&X1<int>::member> i; // expected-note{{in instantiation of}}
+};
+
+X2<int> x;
diff --git a/clang/test/SemaTemplate/instantiate-non-type-template-parameter.cpp b/clang/test/SemaTemplate/instantiate-non-type-template-parameter.cpp
new file mode 100644
index 0000000..027c1e8
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-non-type-template-parameter.cpp
@@ -0,0 +1,55 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5311
+template<typename T>
+class StringSwitch {
+public:
+ template<unsigned N>
+ void Case(const char (&S)[N], const int & Value) {
+ }
+};
+
+void test_stringswitch(int argc, char *argv[]) {
+ (void)StringSwitch<int>();
+}
+
+namespace PR6986 {
+ template<class Class,typename Type,Type Class::*>
+ struct non_const_member_base
+ {
+ };
+
+ template<class Class,typename Type,Type Class::*PtrToMember>
+ struct member: non_const_member_base<Class,Type,PtrToMember>
+ {
+ };
+
+ struct test_class
+ {
+ int int_member;
+ };
+ typedef member< test_class,const int,&test_class::int_member > ckey_m;
+ void test()
+ {
+ ckey_m m;
+ }
+}
+
+namespace rdar8980215 {
+ enum E { E1, E2, E3 };
+
+ template<typename T, E e = E2>
+ struct X0 {
+ X0() {}
+ template<typename U> X0(const X0<U, e> &);
+ };
+
+ template<typename T>
+ struct X1 : X0<T> {
+ X1() {}
+ template<typename U> X1(const X1<U> &x) : X0<T>(x) { }
+ };
+
+ X1<int> x1i;
+ X1<float> x1f(x1i);
+}
diff --git a/clang/test/SemaTemplate/instantiate-objc-1.mm b/clang/test/SemaTemplate/instantiate-objc-1.mm
new file mode 100644
index 0000000..2780f8e
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-objc-1.mm
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Obj-C string literal expressions
+template <typename T> struct StringTest {
+ void f() {
+ (void)@"Hello";
+ }
+};
+
+template struct StringTest<int>;
+template struct StringTest<double>;
+
+// @selector expressions
+template <typename T> struct SelectorTest {
+ SEL f() {
+ return @selector(multiple:arguments:);
+ }
+ SEL f2() {
+ return @selector(multiple:arguments:);
+ }
+};
+
+template struct SelectorTest<int>;
+template struct SelectorTest<double>;
+
+// @protocol expressions
+@protocol P
+@end
+
+template <typename T> struct ProtocolTest {
+ void f() {
+ (void)@protocol(P);
+ }
+};
+
+template struct ProtocolTest<int>;
+template struct ProtocolTest<double>;
+
+// @encode expressions
+template <typename T> struct EncodeTest {
+ static const char *encode(T t) {
+ return @encode(T);
+ }
+};
+
+template struct EncodeTest<int>;
+template struct EncodeTest<double>;
+template struct EncodeTest<wchar_t>;
diff --git a/clang/test/SemaTemplate/instantiate-overload-candidates.cpp b/clang/test/SemaTemplate/instantiate-overload-candidates.cpp
new file mode 100644
index 0000000..5b7e60d
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-overload-candidates.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// This is the function actually selected during overload resolution, and the
+// only one defined.
+template <typename T> void f(T*, int) {}
+
+template <typename T> struct S;
+template <typename T> struct S_ : S<T> { typedef int type; }; // expected-note{{in instantiation}}
+template <typename T> struct S {
+ // Force T to have a complete type here so we can observe instantiations with
+ // incomplete types.
+ T t; // expected-error{{field has incomplete type}}
+};
+
+// Provide a bad class and an overload that instantiates templates with it.
+class NoDefinition; // expected-note{{forward declaration}}
+template <typename T> S_<NoDefinition>::type f(T*, NoDefinition*); // expected-note{{in instantiation}}
+
+void test(int x) {
+ f(&x, 0);
+}
diff --git a/clang/test/SemaTemplate/instantiate-overloaded-arrow.cpp b/clang/test/SemaTemplate/instantiate-overloaded-arrow.cpp
new file mode 100644
index 0000000..ee36427
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-overloaded-arrow.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR5488
+
+struct X {
+ int x;
+};
+
+struct Iter {
+ X* operator->();
+};
+
+template <typename T>
+void Foo() {
+ (void)Iter()->x;
+}
+
+void Func() {
+ Foo<int>();
+}
+
diff --git a/clang/test/SemaTemplate/instantiate-self.cpp b/clang/test/SemaTemplate/instantiate-self.cpp
new file mode 100644
index 0000000..cfe9025
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-self.cpp
@@ -0,0 +1,89 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// Check that we deal with cases where the instantiation of a class template
+// recursively requires the instantiation of the same template.
+namespace test1 {
+ template<typename T> struct A {
+ struct B { // expected-note {{not complete until the closing '}'}}
+ B b; // expected-error {{has incomplete type 'test1::A<int>::B'}}
+ };
+ B b; // expected-note {{in instantiation of}}
+ };
+ A<int> a; // expected-note {{in instantiation of}}
+}
+
+namespace test2 {
+ template<typename T> struct A {
+ struct B {
+ struct C {};
+ char c[1 + C()]; // expected-error {{invalid operands to binary expression}}
+ friend constexpr int operator+(int, C) { return 4; }
+ };
+ B b; // expected-note {{in instantiation of}}
+ };
+ A<int> a; // expected-note {{in instantiation of}}
+}
+
+namespace test3 {
+ // PR12317
+ template<typename T> struct A {
+ struct B {
+ enum { Val = 1 };
+ char c[1 + Val]; // ok
+ };
+ B b;
+ };
+ A<int> a;
+}
+
+namespace test4 {
+ template<typename T> struct M { typedef int type; };
+ template<typename T> struct A {
+ struct B { // expected-note {{not complete until the closing '}'}}
+ int k[typename A<typename M<T>::type>::B().k[0] + 1]; // expected-error {{incomplete type}}
+ };
+ B b; // expected-note {{in instantiation of}}
+ };
+ A<int> a; // expected-note {{in instantiation of}}
+}
+
+// FIXME: PR12298: Recursive constexpr function template instantiation leads to
+// stack overflow.
+#if 0
+namespace test5 {
+ template<typename T> struct A {
+ constexpr T f(T k) { return g(k); }
+ constexpr T g(T k) {
+ return k ? f(k-1)+1 : 0;
+ }
+ };
+ // This should be accepted.
+ constexpr int x = A<int>().f(5);
+}
+
+namespace test6 {
+ template<typename T> constexpr T f(T);
+ template<typename T> constexpr T g(T t) {
+ typedef int arr[f(T())];
+ return t;
+ }
+ template<typename T> constexpr T f(T t) {
+ typedef int arr[g(T())];
+ return t;
+ }
+ // This should be ill-formed.
+ int n = f(0);
+}
+
+namespace test7 {
+ template<typename T> constexpr T g(T t) {
+ return t;
+ }
+ template<typename T> constexpr T f(T t) {
+ typedef int arr[g(T())];
+ return t;
+ }
+ // This should be accepted.
+ int n = f(0);
+}
+#endif
diff --git a/clang/test/SemaTemplate/instantiate-sizeof.cpp b/clang/test/SemaTemplate/instantiate-sizeof.cpp
new file mode 100644
index 0000000..00d63d0
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-sizeof.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// Make sure we handle contexts correctly with sizeof
+template<typename T> void f(T n) {
+ int buffer[n];
+ [] { int x = sizeof(sizeof(buffer)); }();
+}
+int main() {
+ f<int>(1);
+}
diff --git a/clang/test/SemaTemplate/instantiate-static-var.cpp b/clang/test/SemaTemplate/instantiate-static-var.cpp
new file mode 100644
index 0000000..f309f29
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-static-var.cpp
@@ -0,0 +1,116 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, T Divisor>
+class X {
+public:
+ static const T value = 10 / Divisor; // expected-error{{in-class initializer for static data member is not a constant expression}}
+};
+
+int array1[X<int, 2>::value == 5? 1 : -1];
+X<int, 0> xi0; // expected-note{{in instantiation of template class 'X<int, 0>' requested here}}
+
+
+template<typename T>
+class Y {
+ static const T value = 0; // expected-warning{{in-class initializer for static data member of type 'const float' is a GNU extension}}
+};
+
+Y<float> fy; // expected-note{{in instantiation of template class 'Y<float>' requested here}}
+
+
+// out-of-line static member variables
+
+template<typename T>
+struct Z {
+ static T value;
+};
+
+template<typename T>
+T Z<T>::value; // expected-error{{no matching constructor}}
+
+struct DefCon {};
+
+struct NoDefCon {
+ NoDefCon(const NoDefCon&); // expected-note{{candidate constructor}}
+};
+
+void test() {
+ DefCon &DC = Z<DefCon>::value;
+ NoDefCon &NDC = Z<NoDefCon>::value; // expected-note{{instantiation}}
+}
+
+// PR5609
+struct X1 {
+ ~X1(); // The errors won't be triggered without this dtor.
+};
+
+template <typename T>
+struct Y1 {
+ static char Helper(T);
+ static const int value = sizeof(Helper(T()));
+};
+
+struct X2 {
+ virtual ~X2();
+};
+
+namespace std {
+ class type_info { };
+}
+
+template <typename T>
+struct Y2 {
+ static T &Helper();
+ static const int value = sizeof(typeid(Helper()));
+};
+
+template <int>
+struct Z1 {};
+
+void Test() {
+ Z1<Y1<X1>::value> x;
+ int y[Y1<X1>::value];
+ Z1<Y2<X2>::value> x2;
+ int y2[Y2<X2>::value];
+}
+
+// PR5672
+template <int n>
+struct X3 {};
+
+class Y3 {
+ public:
+ ~Y3(); // The error isn't triggered without this dtor.
+
+ void Foo(X3<1>);
+};
+
+template <typename T>
+struct SizeOf {
+ static const int value = sizeof(T);
+};
+
+void MyTest3() {
+ Y3().Foo(X3<SizeOf<char>::value>());
+}
+
+namespace PR6449 {
+ template<typename T>
+ struct X0 {
+ static const bool var = false;
+ };
+
+ template<typename T>
+ const bool X0<T>::var;
+
+ template<typename T>
+ struct X1 : public X0<T> {
+ static const bool var = false;
+ };
+
+ template<typename T>
+ const bool X1<T>::var;
+
+ template class X0<char>;
+ template class X1<char>;
+
+}
diff --git a/clang/test/SemaTemplate/instantiate-subscript.cpp b/clang/test/SemaTemplate/instantiate-subscript.cpp
new file mode 100644
index 0000000..8c119ec
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-subscript.cpp
@@ -0,0 +1,41 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+
+struct Sub0 {
+ int &operator[](int);
+};
+
+struct Sub1 {
+ long &operator[](long); // expected-note{{candidate function}}
+};
+
+struct ConvertibleToInt {
+ operator int();
+};
+
+template<typename T, typename U, typename Result>
+struct Subscript0 {
+ void test(T t, U u) {
+ Result &result = t[u]; // expected-error{{no viable overloaded operator[] for type}}
+ }
+};
+
+template struct Subscript0<int*, int, int&>;
+template struct Subscript0<Sub0, int, int&>;
+template struct Subscript0<Sub1, ConvertibleToInt, long&>;
+template struct Subscript0<Sub1, Sub0, long&>; // expected-note{{instantiation}}
+
+// PR5345
+template <typename T>
+struct S {
+ bool operator[](int n) const { return true; }
+};
+
+template <typename T>
+void Foo(const S<int>& s, T x) {
+ if (s[0]) {}
+}
+
+void Bar() {
+ Foo(S<int>(), 0);
+}
diff --git a/clang/test/SemaTemplate/instantiate-template-template-parm.cpp b/clang/test/SemaTemplate/instantiate-template-template-parm.cpp
new file mode 100644
index 0000000..a70c7e8
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-template-template-parm.cpp
@@ -0,0 +1,97 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<template<typename T> class MetaFun, typename Value>
+struct apply {
+ typedef typename MetaFun<Value>::type type;
+};
+
+template<class T>
+struct add_pointer {
+ typedef T* type;
+};
+
+template<class T>
+struct add_reference {
+ typedef T& type;
+};
+
+int i;
+apply<add_pointer, int>::type ip = &i;
+apply<add_reference, int>::type ir = i;
+apply<add_reference, float>::type fr = i; // expected-error{{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'int'}}
+
+// Template template parameters
+template<int> struct B; // expected-note{{has a different type 'int'}}
+
+template<typename T,
+ template<T Value> class X> // expected-error{{cannot have type 'float'}} \
+ // expected-note{{with type 'long'}}
+struct X0 { };
+
+X0<int, B> x0b1;
+X0<float, B> x0b2; // expected-note{{while substituting}}
+X0<long, B> x0b3; // expected-error{{template template argument has different template parameters}}
+
+template<template<int V> class TT> // expected-note{{parameter with type 'int'}}
+struct X1 { };
+
+template<typename T, template<T V> class TT>
+struct X2 {
+ X1<TT> x1; // expected-error{{has different template parameters}}
+};
+
+template<int V> struct X3i { };
+template<long V> struct X3l { }; // expected-note{{different type 'long'}}
+
+X2<int, X3i> x2okay;
+X2<long, X3l> x2bad; // expected-note{{instantiation}}
+
+template <typename T, template <T, T> class TT, class R = TT<1, 2> >
+struct Comp {
+ typedef R r1;
+ template <T x, T y> struct gt {
+ static const bool result = x > y;
+ };
+ typedef gt<2, 1> r2;
+};
+
+template <int x, int y> struct lt {
+ static const bool result = x < y;
+};
+
+Comp<int, lt> c0;
+
+namespace PR8629 {
+ template<template<int> class TT> struct X0
+ {
+ static void apply();
+ };
+ template<int> struct Type { };
+
+ template<class T> struct X1
+ {
+ template<class U> struct Inner;
+
+ template<class U> void g()
+ {
+ typedef Inner<U> Init;
+ X0<Init::template VeryInner>::apply();
+ }
+ template<int N> void f ()
+ {
+ g<Type<N> >();
+ }
+ };
+ template<class T> template<class U> struct X1<T>::Inner
+ {
+ template<int> struct VeryInner {
+ };
+ };
+ struct X1Container
+ {
+ X1Container()
+ {
+ simplex_.f<0>();
+ }
+ X1<double> simplex_;
+ };
+}
diff --git a/clang/test/SemaTemplate/instantiate-try-catch.cpp b/clang/test/SemaTemplate/instantiate-try-catch.cpp
new file mode 100644
index 0000000..89cae03
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-try-catch.cpp
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -fcxx-exceptions -fexceptions -fsyntax-only -std=c++11 -verify %s
+
+template<typename T> struct TryCatch0 {
+ void f() {
+ try {
+ } catch (T&&) { // expected-error 2{{cannot catch exceptions by rvalue reference}}
+ }
+ }
+};
+
+template struct TryCatch0<int&>; // okay
+template struct TryCatch0<int&&>; // expected-note{{instantiation}}
+template struct TryCatch0<int>; // expected-note{{instantiation}}
+
+
+namespace PR10232 {
+ template <typename T>
+ class Templated {
+ struct Exception {
+ private:
+ Exception(const Exception&); // expected-note{{declared private here}}
+ };
+ void exception() {
+ try {
+ } catch(Exception e) { // expected-error{{calling a private constructor of class 'PR10232::Templated<int>::Exception'}}
+ }
+ }
+ };
+
+ template class Templated<int>; // expected-note{{in instantiation of member function 'PR10232::Templated<int>::exception' requested here}}
+}
diff --git a/clang/test/SemaTemplate/instantiate-type.cpp b/clang/test/SemaTemplate/instantiate-type.cpp
new file mode 100644
index 0000000..f5d0270
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-type.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+int* f(int);
+float *f(...);
+
+template<typename T>
+struct X {
+ typedef typeof(T*) typeof_type;
+ typedef typeof(f(T())) typeof_expr;
+};
+
+int *iptr0;
+float *fptr0;
+X<int>::typeof_type &iptr1 = iptr0;
+
+X<int>::typeof_expr &iptr2 = iptr0;
+X<float*>::typeof_expr &fptr1 = fptr0;
diff --git a/clang/test/SemaTemplate/instantiate-typedef.cpp b/clang/test/SemaTemplate/instantiate-typedef.cpp
new file mode 100644
index 0000000..4e6cd24
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-typedef.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct add_pointer {
+ typedef T* type; // expected-error{{'type' declared as a pointer to a reference}}
+};
+
+add_pointer<int>::type test1(int * ptr) { return ptr; }
+
+add_pointer<float>::type test2(int * ptr) {
+ return ptr; // expected-error{{cannot initialize return object of type 'add_pointer<float>::type' (aka 'float *') with an lvalue of type 'int *'}}
+}
+
+add_pointer<int&>::type // expected-note{{in instantiation of template class 'add_pointer<int &>' requested here}}
+test3();
diff --git a/clang/test/SemaTemplate/instantiate-typeof.cpp b/clang/test/SemaTemplate/instantiate-typeof.cpp
new file mode 100644
index 0000000..92873cb
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-typeof.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+// Make sure we correctly treat __typeof as potentially-evaluated when appropriate
+template<typename T> void f(T n) {
+ int buffer[n]; // expected-note {{declared here}}
+ [] { __typeof(buffer) x; }(); // expected-error {{variable 'buffer' with variably modified type cannot be captured in a lambda expression}}
+}
+int main() {
+ f<int>(1); // expected-note {{in instantiation}}
+}
diff --git a/clang/test/SemaTemplate/instantiate-using-decl.cpp b/clang/test/SemaTemplate/instantiate-using-decl.cpp
new file mode 100644
index 0000000..1bfcb7a
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiate-using-decl.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace test0 {
+ namespace N { }
+
+ template<typename T>
+ struct A {
+ void f();
+ };
+
+ template<typename T>
+ struct B : A<T> {
+ using A<T>::f;
+
+ void g() {
+ using namespace N;
+ f();
+ }
+ };
+
+ template struct B<int>;
+}
+
+namespace test1 {
+ template <class Derived> struct Visitor1 {
+ void Visit(struct Object1*);
+ };
+ template <class Derived> struct Visitor2 {
+ void Visit(struct Object2*); // expected-note {{candidate function}}
+ };
+
+ template <class Derived> struct JoinVisitor
+ : Visitor1<Derived>, Visitor2<Derived> {
+ typedef Visitor1<Derived> Base1;
+ typedef Visitor2<Derived> Base2;
+
+ void Visit(struct Object1*); // expected-note {{candidate function}}
+ using Base2::Visit;
+ };
+
+ class Knot : public JoinVisitor<Knot> {
+ };
+
+ void test() {
+ Knot().Visit((struct Object1*) 0);
+ Knot().Visit((struct Object2*) 0);
+ Knot().Visit((struct Object3*) 0); // expected-error {{no matching member function for call}}
+ }
+}
+
+// PR5847
+namespace test2 {
+ namespace ns {
+ void foo();
+ }
+
+ template <class T> void bar(T* ptr) {
+ using ns::foo;
+ foo();
+ }
+
+ template void bar(char *);
+}
+
+namespace test3 {
+ template <typename T> struct t {
+ struct s1 {
+ T f1() const;
+ };
+ struct s2 : s1 {
+ using s1::f1;
+ T f1() const;
+ };
+ };
+
+ void f2()
+ {
+ t<int>::s2 a;
+ t<int>::s2 const & b = a;
+ b.f1();
+ }
+}
diff --git a/clang/test/SemaTemplate/instantiation-backtrace.cpp b/clang/test/SemaTemplate/instantiation-backtrace.cpp
new file mode 100644
index 0000000..21456e9
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiation-backtrace.cpp
@@ -0,0 +1,32 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T> struct A; // expected-note 4{{template is declared here}}
+
+template<typename T> struct B : A<T*> { }; // expected-error{{implicit instantiation of undefined template}} \
+// expected-error{{implicit instantiation of undefined template 'A<X *>'}}
+
+template<typename T> struct C : B<T> { } ; // expected-note{{instantiation of template class}}
+
+template<typename T> struct D : C<T> { }; // expected-note{{instantiation of template class}}
+
+template<typename T> struct E : D<T> { }; // expected-note{{instantiation of template class}}
+
+template<typename T> struct F : E<T(T)> { }; // expected-note{{instantiation of template class}}
+
+void f() {
+ (void)sizeof(F<int>); // expected-note{{instantiation of template class}}
+}
+
+typedef struct { } X;
+
+void g() {
+ (void)sizeof(B<X>); // expected-note{{in instantiation of template class 'B<X>' requested here}}
+}
+
+template<typename T>
+struct G : A<T>, // expected-error{{implicit instantiation of undefined template 'A<int>'}}
+ A<T*> // expected-error{{implicit instantiation of undefined template 'A<int *>'}}
+ { };
+
+void h() {
+ (void)sizeof(G<int>); // expected-note{{in instantiation of template class 'G<int>' requested here}}
+}
diff --git a/clang/test/SemaTemplate/instantiation-default-1.cpp b/clang/test/SemaTemplate/instantiation-default-1.cpp
new file mode 100644
index 0000000..99154a5
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiation-default-1.cpp
@@ -0,0 +1,102 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U = const T> struct Def1;
+
+template<> struct Def1<int> {
+ void foo();
+};
+
+template<> struct Def1<const int> { // expected-note{{previous definition is here}}
+ void bar();
+};
+
+template<> struct Def1<int&> {
+ void wibble();
+};
+
+void test_Def1(Def1<int, const int> *d1, Def1<const int, const int> *d2,
+ Def1<int&, int&> *d3) {
+ d1->foo();
+ d2->bar();
+ d3->wibble();
+}
+
+template<typename T, // FIXME: bad error message below, needs better location info
+ typename T2 = const T*> // expected-error{{'T2' declared as a pointer to a reference}}
+ struct Def2;
+
+template<> struct Def2<int> {
+ void foo();
+};
+
+void test_Def2(Def2<int, int const*> *d2) {
+ d2->foo();
+}
+
+typedef int& int_ref_t;
+Def2<int_ref_t> *d2; // expected-note{{in instantiation of default argument for 'Def2<int &>' required here}}
+
+
+template<> struct Def1<const int, const int> { }; // expected-error{{redefinition of 'Def1<const int>'}}
+
+template<typename T, typename T2 = T&> struct Def3;
+
+template<> struct Def3<int> {
+ void foo();
+};
+
+template<> struct Def3<int&> {
+ void bar();
+};
+
+void test_Def3(Def3<int, int&> *d3a, Def3<int&, int&> *d3b) {
+ d3a->foo();
+ d3b->bar();
+}
+
+
+template<typename T, typename T2 = T[]> struct Def4;
+
+template<> struct Def4<int> {
+ void foo();
+};
+
+void test_Def4(Def4<int, int[]> *d4a) {
+ d4a->foo();
+}
+
+template<typename T, typename T2 = T const[12]> struct Def5;
+
+template<> struct Def5<int> {
+ void foo();
+};
+
+template<> struct Def5<int, int const[13]> {
+ void bar();
+};
+
+void test_Def5(Def5<int, const int[12]> *d5a, Def5<int, const int[13]> *d5b) {
+ d5a->foo();
+ d5b->bar();
+}
+
+template<typename R, typename Arg1, typename Arg2 = Arg1,
+ typename FuncType = R (*)(Arg1, Arg2)>
+ struct Def6;
+
+template<> struct Def6<int, float> {
+ void foo();
+};
+
+template<> struct Def6<bool, int[5], float(double, double)> {
+ void bar();
+};
+
+bool test_Def6(Def6<int, float, float> *d6a,
+ Def6<int, float, float, int (*)(float, float)> *d6b,
+ Def6<bool, int[5], float(double, double),
+ bool(*)(int*, float(*)(double, double))> *d6c) {
+ d6a->foo();
+ d6b->foo();
+ d6c->bar();
+ return d6a == d6b;
+}
diff --git a/clang/test/SemaTemplate/instantiation-default-2.cpp b/clang/test/SemaTemplate/instantiation-default-2.cpp
new file mode 100644
index 0000000..5a744a0
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiation-default-2.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T, T Value> struct Constant; // expected-note{{template parameter is declared here}} \
+// FIXME: bad location expected-error{{a non-type template parameter cannot have type 'float'}}
+
+Constant<int, 5> *c1;
+
+int x;
+float f(int, double);
+
+Constant<int&, x> *c2;
+Constant<int*, &x> *c3;
+Constant<float (*)(int, double), f> *c4;
+Constant<float (*)(int, double), &f> *c5;
+
+Constant<float (*)(int, int), f> *c6; // expected-error{{non-type template argument of type 'float (int, double)' cannot be converted to a value of type 'float (*)(int, int)'}}
+
+Constant<float, 0> *c7; // expected-note{{while substituting}}
diff --git a/clang/test/SemaTemplate/instantiation-default-3.cpp b/clang/test/SemaTemplate/instantiation-default-3.cpp
new file mode 100644
index 0000000..dae6b18
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiation-default-3.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> struct A { };
+
+template<typename T, typename U = A<T*> >
+ struct B : U { };
+
+template<>
+struct A<int*> {
+ void foo();
+};
+
+template<>
+struct A<float*> {
+ void bar();
+};
+
+void test(B<int> *b1, B<float> *b2) {
+ b1->foo();
+ b2->bar();
+}
diff --git a/clang/test/SemaTemplate/instantiation-depth.cpp b/clang/test/SemaTemplate/instantiation-depth.cpp
new file mode 100644
index 0000000..8e1b803
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiation-depth.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -ftemplate-depth 5 -ftemplate-backtrace-limit 4 %s
+// RUN: %clang -fsyntax-only -Xclang -verify -ftemplate-depth-5 -ftemplate-backtrace-limit=4 %s
+// RUN: %clang -fsyntax-only -Xclang -verify -ftemplate-depth=5 -ftemplate-backtrace-limit=4 %s
+
+template<typename T> struct X : X<T*> { }; \
+// expected-error{{recursive template instantiation exceeded maximum depth of 5}} \
+// expected-note 3 {{instantiation of template class}} \
+// expected-note {{skipping 2 contexts in backtrace}} \
+// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
+
+void test() {
+ (void)sizeof(X<int>); // expected-note {{instantiation of template class}}
+}
diff --git a/clang/test/SemaTemplate/instantiation-order.cpp b/clang/test/SemaTemplate/instantiation-order.cpp
new file mode 100644
index 0000000..e058a5b
--- /dev/null
+++ b/clang/test/SemaTemplate/instantiation-order.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c++11 -verify %s
+
+// From core issue 1227.
+
+template <class T> struct A { using X = typename T::X; }; // expected-error {{no members}}
+template <class T> typename T::X f(typename A<T>::X);
+template <class T> void f(...) {}
+template <class T> auto g(typename A<T>::X) -> typename T::X; // expected-note {{here}} expected-note {{substituting}}
+template <class T> void g(...) {}
+
+void h()
+{
+ f<int>(0); // ok, SFINAE in return type
+ g<int>(0); // not ok, substitution inside A<int> is a hard error
+}
diff --git a/clang/test/SemaTemplate/issue150.cpp b/clang/test/SemaTemplate/issue150.cpp
new file mode 100644
index 0000000..af3b93c
--- /dev/null
+++ b/clang/test/SemaTemplate/issue150.cpp
@@ -0,0 +1,107 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Core issue 150: Template template parameters and default arguments
+
+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 PR9353 {
+ template<class _T, class Traits> class IM;
+
+ template <class T, class Trt,
+ template<class _T, class Traits = int> class IntervalMap>
+ void foo(IntervalMap<T,Trt>* m) { typedef IntervalMap<int> type; }
+
+ void f(IM<int, int>* m) { foo(m); }
+}
+
+namespace PR9400 {
+ template<template <typename T, typename = T > class U> struct A
+ {
+ template<int> U<int> foo();
+ };
+
+ template <typename T, typename = T>
+ struct s {
+ };
+
+ void f() {
+ A<s> x;
+ x.foo<2>();
+ }
+}
+
+namespace MultiReplace {
+ template<typename Z,
+ template<typename T, typename U = T *, typename V = U const> class TT>
+ struct X {
+ typedef TT<Z> type;
+ };
+
+ template<typename T, typename = int, typename = float>
+ struct Y { };
+
+ int check0[is_same<X<int, Y>::type, Y<int, int*, int* const> >::value? 1 : -1];
+}
+
+namespace MultiReplacePartial {
+ template<typename First, typename Z,
+ template<typename T, typename U = T *, typename V = U const> class TT>
+ struct X {
+ typedef TT<Z> type;
+ };
+
+ template<typename Z,
+ template<typename T, typename U = T *, typename V = U const> class TT>
+ struct X<int, Z, TT> {
+ typedef TT<Z> type;
+ };
+
+ template<typename T, typename = int, typename = float>
+ struct Y { };
+
+ int check0[is_same<X<int, int, Y>::type, Y<int, int*, int* const> >::value? 1 : -1];
+}
+
+namespace PR9016 {
+ template<typename > struct allocator ;
+ template<typename > struct less ;
+
+ template<class T, template<class> class Compare, class Default,
+ template<class> class Alloc>
+ struct interval_set { };
+
+ template <class X, template<class> class = less> struct interval_type_default {
+ typedef X type;
+ };
+
+ template <class T,
+ template<class _T, template<class> class Compare = PR9016::less,
+ class = typename interval_type_default<_T,Compare>::type,
+ template<class> class = allocator> class IntervalSet>
+ struct ZZZ
+ {
+ IntervalSet<T> IntervalSetT;
+ };
+
+ template <class T,
+ template<class _T, template<class> class Compare = PR9016::less,
+ class = typename interval_type_default<_T,Compare>::type,
+ template<class> class = allocator> class IntervalSet>
+ void int40()
+ {
+ IntervalSet<T> IntervalSetT;
+ }
+
+ void test() {
+ ZZZ<int, interval_set> zzz;
+ int40<int, interval_set>();
+ }
+}
diff --git a/clang/test/SemaTemplate/lookup-dependent-bases.cpp b/clang/test/SemaTemplate/lookup-dependent-bases.cpp
new file mode 100644
index 0000000..2710caf
--- /dev/null
+++ b/clang/test/SemaTemplate/lookup-dependent-bases.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+
+class C {
+public:
+ static void foo2() { }
+};
+template <class T>
+class A {
+public:
+ typedef C D;
+};
+
+template <class T>
+class B : public A<T> {
+public:
+ void foo() {
+ D::foo2();
+ }
+};
diff --git a/clang/test/SemaTemplate/member-access-ambig.cpp b/clang/test/SemaTemplate/member-access-ambig.cpp
new file mode 100644
index 0000000..f8a01d5
--- /dev/null
+++ b/clang/test/SemaTemplate/member-access-ambig.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR8439
+class A
+{
+};
+
+class B
+{
+public:
+ A & m;
+};
+
+class Base
+{
+public:
+ B &f();
+};
+
+class Derived1 : public Base { };
+
+class Derived2 : public Base { };
+
+class X : public B, public Derived2, public Derived1
+{
+public:
+ virtual void g();
+};
+
+void X::g()
+{
+ m.f<int>(); // expected-error{{no member named 'f' in 'A'}} \
+ // expected-error{{expected '(' for function-style cast}} \
+ // expected-error{{expected expression}}
+}
+
+namespace PR11134 {
+ template<typename Derived> class A;
+ template<typename Derived> class B : A<Derived> {
+ typedef A<Derived> Base;
+ using Base::member;
+ int member;
+ };
+}
+
diff --git a/clang/test/SemaTemplate/member-access-expr.cpp b/clang/test/SemaTemplate/member-access-expr.cpp
new file mode 100644
index 0000000..f1aa30e
--- /dev/null
+++ b/clang/test/SemaTemplate/member-access-expr.cpp
@@ -0,0 +1,149 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+void call_f0(T x) {
+ x.Base::f0();
+}
+
+struct Base {
+ void f0();
+};
+
+struct X0 : Base {
+ typedef Base CrazyBase;
+};
+
+void test_f0(X0 x0) {
+ call_f0(x0);
+}
+
+template<typename TheBase, typename T>
+void call_f0_through_typedef(T x) {
+ typedef TheBase Base2;
+ x.Base2::f0();
+}
+
+void test_f0_through_typedef(X0 x0) {
+ call_f0_through_typedef<Base>(x0);
+}
+
+template<typename TheBase, typename T>
+void call_f0_through_typedef2(T x) {
+ typedef TheBase CrazyBase; // expected-note{{current scope}}
+ x.CrazyBase::f0(); // expected-error{{ambiguous}} \
+ // expected-error 2{{no member named}}
+}
+
+struct OtherBase { };
+
+struct X1 : Base, OtherBase {
+ typedef OtherBase CrazyBase; // expected-note{{object type}}
+};
+
+void test_f0_through_typedef2(X0 x0, X1 x1) {
+ call_f0_through_typedef2<Base>(x0);
+ call_f0_through_typedef2<OtherBase>(x1); // expected-note{{instantiation}}
+ call_f0_through_typedef2<Base>(x1); // expected-note{{instantiation}}
+}
+
+
+struct X2 {
+ operator int() const;
+};
+
+template<typename T, typename U>
+T convert(const U& value) {
+ return value.operator T(); // expected-error{{operator long}}
+}
+
+void test_convert(X2 x2) {
+ convert<int>(x2);
+ convert<long>(x2); // expected-note{{instantiation}}
+}
+
+template<typename T>
+void destruct(T* ptr) {
+ ptr->~T();
+ ptr->T::~T();
+}
+
+template<typename T>
+void destruct_intptr(int *ip) {
+ ip->~T();
+ ip->T::~T();
+}
+
+void test_destruct(X2 *x2p, int *ip) {
+ destruct(x2p);
+ destruct(ip);
+ destruct_intptr<int>(ip);
+}
+
+// PR5220
+class X3 {
+protected:
+ template <int> float* &f0();
+ template <int> const float* &f0() const;
+ void f1() {
+ (void)static_cast<float*>(f0<0>());
+ }
+ void f1() const{
+ (void)f0<0>();
+ }
+};
+
+// Fun with template instantiation and conversions
+struct X4 {
+ int& member();
+ float& member() const;
+};
+
+template<typename T>
+struct X5 {
+ void f(T* ptr) { int& ir = ptr->member(); }
+ void g(T* ptr) { float& fr = ptr->member(); }
+};
+
+void test_X5(X5<X4> x5, X5<const X4> x5c, X4 *xp, const X4 *cxp) {
+ x5.f(xp);
+ x5c.g(cxp);
+}
+
+// In theory we can do overload resolution at template-definition time on this.
+// We should at least not assert.
+namespace test4 {
+ struct Base {
+ template <class T> void foo() {}
+ };
+
+ template <class T> struct Foo : Base {
+ void test() {
+ foo<int>();
+ }
+ };
+}
+
+namespace test5 {
+ template<typename T>
+ struct X {
+ using T::value;
+
+ T &getValue() {
+ return &value;
+ }
+ };
+}
+
+// PR8739
+namespace test6 {
+ struct A {};
+ struct B {};
+ template <class T> class Base;
+ template <class T> class Derived : public Base<T> {
+ A *field;
+ void get(B **ptr) {
+ // It's okay if at some point we figure out how to diagnose this
+ // at instantiation time.
+ *ptr = field;
+ }
+ };
+}
diff --git a/clang/test/SemaTemplate/member-function-template.cpp b/clang/test/SemaTemplate/member-function-template.cpp
new file mode 100644
index 0000000..44954ed
--- /dev/null
+++ b/clang/test/SemaTemplate/member-function-template.cpp
@@ -0,0 +1,103 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct X {
+ template<typename T> T& f0(T);
+
+ void g0(int i, double d) {
+ int &ir = f0(i);
+ double &dr = f0(d);
+ }
+
+ template<typename T> T& f1(T);
+ template<typename T, typename U> U& f1(T, U);
+
+ void g1(int i, double d) {
+ int &ir1 = f1(i);
+ int &ir2 = f1(d, i);
+ int &ir3 = f1(i, i);
+ }
+};
+
+void test_X_f0(X x, int i, float f) {
+ int &ir = x.f0(i);
+ float &fr = x.f0(f);
+}
+
+void test_X_f1(X x, int i, float f) {
+ int &ir1 = x.f1(i);
+ int &ir2 = x.f1(f, i);
+ int &ir3 = x.f1(i, i);
+}
+
+void test_X_f0_address() {
+ int& (X::*pm1)(int) = &X::f0;
+ float& (X::*pm2)(float) = &X::f0;
+}
+
+void test_X_f1_address() {
+ int& (X::*pm1)(int) = &X::f1;
+ float& (X::*pm2)(float) = &X::f1;
+ int& (X::*pm3)(float, int) = &X::f1;
+}
+
+void test_X_f0_explicit(X x, int i, long l) {
+ int &ir1 = x.f0<int>(i);
+ int &ir2 = x.f0<>(i);
+ long &il1 = x.f0<long>(i);
+}
+
+// PR4608
+class A { template <class x> x a(x z) { return z+y; } int y; };
+
+// PR5419
+struct Functor {
+ template <typename T>
+ bool operator()(const T& v) const {
+ return true;
+ }
+};
+
+void test_Functor(Functor f) {
+ f(1);
+}
+
+// Instantiation on ->
+template<typename T>
+struct X1 {
+ template<typename U> U& get();
+};
+
+template<typename T> struct X2; // expected-note{{here}}
+
+void test_incomplete_access(X1<int> *x1, X2<int> *x2) {
+ float &fr = x1->get<float>();
+ (void)x2->get<float>(); // expected-error{{implicit instantiation of undefined template}}
+}
+
+// Instantiation of template template parameters in a member function
+// template.
+namespace TTP {
+ template<int Dim> struct X {
+ template<template<class> class M, class T> void f(const M<T>&);
+ };
+
+ template<typename T> struct Y { };
+
+ void test_f(X<3> x, Y<int> y) { x.f(y); }
+}
+
+namespace PR7387 {
+ template <typename T> struct X {};
+
+ template <typename T1> struct S {
+ template <template <typename> class TC> void foo(const TC<T1>& arg);
+ };
+
+ template <typename T1> template <template <typename> class TC>
+ void S<T1>::foo(const TC<T1>& arg) {}
+
+ void test(const X<int>& x) {
+ S<int> s;
+ s.foo(x);
+ }
+}
diff --git a/clang/test/SemaTemplate/member-inclass-init-value-dependent.cpp b/clang/test/SemaTemplate/member-inclass-init-value-dependent.cpp
new file mode 100644
index 0000000..5bff7f2
--- /dev/null
+++ b/clang/test/SemaTemplate/member-inclass-init-value-dependent.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -emit-llvm-only %s
+// PR10290
+
+template<int Flags> struct foo {
+ int value = Flags && 0;
+};
+
+void test() {
+ foo<4> bar;
+}
+
+struct S {
+ S(int n);
+};
+template<typename> struct T {
+ S s = 0;
+};
+T<int> t;
diff --git a/clang/test/SemaTemplate/member-initializers.cpp b/clang/test/SemaTemplate/member-initializers.cpp
new file mode 100644
index 0000000..40f56b3
--- /dev/null
+++ b/clang/test/SemaTemplate/member-initializers.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> struct A {
+ A() : j(10), i(10) { }
+
+ int i;
+ int j;
+};
+
+template<typename T> struct B : A<T> {
+ B() : A<T>() { }
+};
+
diff --git a/clang/test/SemaTemplate/member-template-access-expr.cpp b/clang/test/SemaTemplate/member-template-access-expr.cpp
new file mode 100644
index 0000000..c95b57d
--- /dev/null
+++ b/clang/test/SemaTemplate/member-template-access-expr.cpp
@@ -0,0 +1,144 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename U, typename T>
+U f0(T t) {
+ return t.template get<U>();
+}
+
+template<typename U, typename T>
+int &f1(T t) {
+ // FIXME: When we pretty-print this, we lose the "template" keyword.
+ return t.U::template get<int&>();
+}
+
+struct X {
+ template<typename T> T get();
+};
+
+void test_f0(X x) {
+ int i = f0<int>(x);
+ int &ir = f0<int&>(x);
+}
+
+struct XDerived : public X {
+};
+
+void test_f1(XDerived xd) {
+ int &ir = f1<X>(xd);
+}
+
+// PR5213
+template <class T>
+struct A {};
+
+template<class T>
+class B
+{
+ A<T> a_;
+
+public:
+ void destroy();
+};
+
+template<class T>
+void
+B<T>::destroy()
+{
+ a_.~A<T>();
+}
+
+void do_destroy_B(B<int> b) {
+ b.destroy();
+}
+
+struct X1 {
+ int* f1(int);
+ template<typename T> float* f1(T);
+
+ static int* f2(int);
+ template<typename T> static float* f2(T);
+};
+
+void test_X1(X1 x1) {
+ float *fp1 = x1.f1<>(17);
+ float *fp2 = x1.f1<int>(3.14); // expected-warning {{implicit conversion turns literal floating-point number into integer}}
+ int *ip1 = x1.f1(17);
+ float *ip2 = x1.f1(3.14);
+
+ float* (X1::*mf1)(int) = &X1::f1;
+ float* (X1::*mf2)(int) = &X1::f1<>;
+ float* (X1::*mf3)(float) = &X1::f1<float>;
+
+ float* (*fp3)(int) = &X1::f2;
+ float* (*fp4)(int) = &X1::f2<>;
+ float* (*fp5)(float) = &X1::f2<float>;
+ float* (*fp6)(int) = X1::f2;
+ float* (*fp7)(int) = X1::f2<>;
+ float* (*fp8)(float) = X1::f2<float>;
+}
+
+template<int A> struct X2 {
+ int m;
+};
+
+template<typename T>
+struct X3 : T { };
+
+template<typename T>
+struct X4 {
+ template<typename U>
+ void f(X2<sizeof(X3<U>().U::m)>);
+};
+
+void f(X4<X3<int> > x4i) {
+ X2<sizeof(int)> x2;
+ x4i.f<X2<sizeof(int)> >(x2);
+}
+
+template<typename T>
+struct X5 {
+ template<typename U>
+ void f();
+
+ void g() {
+ this->f<T*>();
+ }
+};
+
+namespace PR6021 {
+ template< class T1, class T2 >
+ class Outer
+ {
+ public: // Range operations
+ template< class X > X tmpl( const X* = 0 ) const;
+
+ struct Inner
+ {
+ const Outer& o;
+
+ template< class X >
+ operator X() const
+ {
+ return o.tmpl<X>();
+ }
+ };
+ };
+}
+
+namespace rdar8198511 {
+ template<int, typename U>
+ struct Base {
+ void f();
+ };
+
+ template<typename T>
+ struct X0 : Base<1, T> { };
+
+ template<typename T>
+ struct X1 {
+ X0<int> x0;
+
+ void f() {
+ this->x0.Base<1, int>::f();
+ }
+ };
+}
diff --git a/clang/test/SemaTemplate/metafun-apply.cpp b/clang/test/SemaTemplate/metafun-apply.cpp
new file mode 100644
index 0000000..3a7408e
--- /dev/null
+++ b/clang/test/SemaTemplate/metafun-apply.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+struct add_pointer {
+ template<typename T>
+ struct apply {
+ typedef T* type;
+ };
+};
+
+struct add_reference {
+ template<typename T>
+ struct apply {
+ typedef T& type; // expected-error{{cannot form a reference to 'void'}}
+ };
+};
+
+struct bogus {
+ struct apply {
+ typedef int type;
+ };
+};
+
+template<typename MetaFun, typename T>
+struct apply1 {
+ typedef typename MetaFun::template apply<T>::type type; // expected-note{{in instantiation of template class 'add_reference::apply<void>' requested here}} \
+ // expected-error{{'apply' following the 'template' keyword does not refer to a template}}
+};
+
+int i;
+apply1<add_pointer, int>::type ip = &i;
+apply1<add_reference, int>::type ir = i;
+apply1<add_reference, float>::type fr = i; // expected-error{{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'int'}}
+
+void test() {
+ apply1<add_reference, void>::type t; // expected-note{{in instantiation of template class 'apply1<add_reference, void>' requested here}}
+
+ apply1<bogus, int>::type t2; // expected-note{{in instantiation of template class 'apply1<bogus, int>' requested here}}
+}
+
+
diff --git a/clang/test/SemaTemplate/missing-class-keyword-crash.cpp b/clang/test/SemaTemplate/missing-class-keyword-crash.cpp
new file mode 100644
index 0000000..f0eee2b
--- /dev/null
+++ b/clang/test/SemaTemplate/missing-class-keyword-crash.cpp
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class G {};
+template <Foo> // expected-error{{unknown type name 'Foo'}} \
+ // expected-note{{template parameter is declared here}}
+class Bar {};
+
+class Bar<G> blah_test; // expected-error{{template argument for non-type template parameter must be an expression}}
diff --git a/clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp b/clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp
new file mode 100644
index 0000000..bda87f9
--- /dev/null
+++ b/clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+
+
+class A {
+public:
+ template <class U>
+ A(U p) {
+ }
+ template <>
+ A(int p) { // expected-warning{{explicit specialization of 'A' within class scope is a Microsoft extension}}
+ }
+
+ template <class U>
+ void f(U p) {
+ }
+
+ template <>
+ void f(int p) { // expected-warning{{explicit specialization of 'f' within class scope is a Microsoft extension}}
+ }
+
+ void f(int p) {
+ }
+};
+
+void test1()
+{
+ A a(3);
+ char* b ;
+ a.f(b);
+ a.f<int>(99);
+ a.f(100);
+}
+
+
+
+
+template <class T>
+class B {
+public:
+ template <class U>
+ B(U p) {
+ }
+ template <>
+ B(int p) { // expected-warning{{explicit specialization of 'B<T>' within class scope is a Microsoft extension}}
+ }
+
+ template <class U>
+ void f(U p) {
+ T y = 9;
+ }
+
+
+ template <>
+ void f(int p) { // expected-warning{{explicit specialization of 'f' within class scope is a Microsoft extension}}
+ T a = 3;
+ }
+
+ void f(int p) {
+ T a = 3;
+ }
+};
+
+void test2()
+{
+ B<char> b(3);
+ char* ptr;
+ b.f(ptr);
+ b.f<int>(99);
+ b.f(100);
+}
+
diff --git a/clang/test/SemaTemplate/ms-if-exists.cpp b/clang/test/SemaTemplate/ms-if-exists.cpp
new file mode 100644
index 0000000..04f4a63
--- /dev/null
+++ b/clang/test/SemaTemplate/ms-if-exists.cpp
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -fms-extensions -std=c++11 %s -verify
+
+struct Nontemplate {
+ typedef int type;
+};
+
+template<typename T>
+struct X {
+ __if_exists(Nontemplate::type) {
+ typedef Nontemplate::type type;
+ }
+
+ __if_exists(Nontemplate::value) {
+ typedef Nontemplate::value type2;
+ }
+
+ __if_not_exists(Nontemplate::value) {
+ typedef int type3;
+ }
+
+ __if_exists(T::X) { // expected-warning{{dependent __if_exists declarations are ignored}}
+ typedef T::X type4;
+ }
+};
+
+X<int>::type i1;
+X<int>::type2 i2; // expected-error{{no type named 'type2' in 'X<int>'}}
+X<int>::type3 i3;
+X<int>::type4 i4; // expected-error{{no type named 'type4' in 'X<int>'}}
+
+struct HasFoo {
+ void foo();
+};
+struct HasBar {
+ void bar(int);
+ void bar(float);
+};
+
+template<typename T>
+void f(T t) {
+ __if_exists(T::foo) {
+ { }
+ t.foo();
+ }
+
+ __if_not_exists(T::bar) {
+ int *i = t; // expected-error{{no viable conversion from 'HasFoo' to 'int *'}}
+ { }
+ }
+
+ int array2[] = {
+ 0,
+ __if_exists(T::bar) {2, }// expected-warning{{dependent __if_exists declarations are ignored}}
+ 3
+ };
+}
+
+template void f(HasFoo); // expected-note{{in instantiation of function template specialization 'f<HasFoo>' requested here}}
+template void f(HasBar);
+
+template<typename T, typename ...Ts>
+void g(T, Ts...) {
+ __if_exists(T::operator Ts) { // expected-error{{__if_exists name contains unexpanded parameter pack 'Ts'}}
+ }
+
+ __if_not_exists(Ts::operator T) { // expected-error{{__if_not_exists name contains unexpanded parameter pack 'Ts'}}
+ }
+}
diff --git a/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
new file mode 100644
index 0000000..2c422dc
--- /dev/null
+++ b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -0,0 +1,145 @@
+// RUN: %clang_cc1 -fms-compatibility -fsyntax-only -verify %s
+
+
+template <class T>
+class A {
+public:
+ void f(T a) { }// expected-note {{must qualify identifier to find this declaration in dependent base class}}
+ void g();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
+};
+
+
+template <class T>
+class B : public A<T> {
+public:
+ void z(T a)
+ {
+ f(a); // expected-warning {{use of identifier 'f' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+ g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+ }
+};
+
+template class B<int>; // expected-note {{requested here}}
+template class B<char>;
+
+void test()
+{
+ B<int> b;
+ b.z(3);
+}
+
+namespace lookup_dependent_bases_id_expr {
+
+template<class T> class A {
+public:
+ int var;
+};
+
+
+template<class T>
+class B : public A<T> {
+public:
+ void f() {
+ var = 3;
+ }
+};
+
+template class B<int>;
+
+}
+
+
+
+namespace lookup_dependent_base_class_static_function {
+
+template <class T>
+class A {
+public:
+ static void static_func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
+ void func();// expected-note {{must qualify identifier to find this declaration in dependent base class}}
+};
+
+
+template <class T>
+class B : public A<T> {
+public:
+ static void z2(){
+ static_func(); // expected-warning {{use of identifier 'static_func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+ func(); // expected-warning {{use of identifier 'func' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
+ }
+};
+template class B<int>; // expected-note {{requested here}}
+
+}
+
+
+
+namespace lookup_dependent_base_class_default_argument {
+
+template<class T>
+class A {
+public:
+ static int f1(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
+ int f2(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
+};
+
+template<class T>
+class B : public A<T> {
+public:
+ void g1(int p = f1());// expected-warning {{use of identifier 'f1' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+ void g2(int p = f2());// expected-warning {{use of identifier 'f2' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}} expected-error {{call to non-static member function without an object argument}}
+};
+
+void foo()
+{
+ B<int> b;
+ b.g1(); // expected-note {{required here}}
+ b.g2(); // expected-note {{required here}}
+}
+
+}
+
+
+namespace lookup_dependent_base_class_friend {
+
+template <class T>
+class B {
+public:
+ static void g(); // expected-note {{must qualify identifier to find this declaration in dependent base class}}
+};
+
+template <class T>
+class A : public B<T> {
+public:
+ friend void foo(A<T> p){
+ g(); // expected-warning {{use of identifier 'g' found via unqualified lookup into dependent bases of class templates is a Microsoft extension}}
+ }
+};
+
+int main2()
+{
+ A<int> a;
+ foo(a); // expected-note {{requested here}}
+}
+
+}
+
+
+namespace lookup_dependent_base_no_typo_correction {
+
+class C {
+public:
+ int m_hWnd;
+};
+
+template <class T>
+class A : public T {
+public:
+ void f(int hWnd) {
+ m_hWnd = 1;
+ }
+};
+
+template class A<C>;
+
+}
diff --git a/clang/test/SemaTemplate/nested-incomplete-class.cpp b/clang/test/SemaTemplate/nested-incomplete-class.cpp
new file mode 100644
index 0000000..a4bfccb
--- /dev/null
+++ b/clang/test/SemaTemplate/nested-incomplete-class.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template <typename T>
+struct foo {
+ struct bar;
+
+ bar fn() {
+ // Should not get errors about bar being incomplete here.
+ bar b = bar(1, 2);
+ return b;
+ }
+};
+
+template <typename T>
+struct foo<T>::bar {
+ bar(int, int);
+};
+
+void fn() {
+ foo<int>().fn();
+}
diff --git a/clang/test/SemaTemplate/nested-linkage.cpp b/clang/test/SemaTemplate/nested-linkage.cpp
new file mode 100644
index 0000000..6c0791c
--- /dev/null
+++ b/clang/test/SemaTemplate/nested-linkage.cpp
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+extern "C" { extern "C++" { template<class C> C x(); } }
diff --git a/clang/test/SemaTemplate/nested-name-spec-template.cpp b/clang/test/SemaTemplate/nested-name-spec-template.cpp
new file mode 100644
index 0000000..635687d
--- /dev/null
+++ b/clang/test/SemaTemplate/nested-name-spec-template.cpp
@@ -0,0 +1,142 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace N {
+ namespace M {
+ template<typename T> struct Promote;
+
+ template<> struct Promote<short> {
+ typedef int type;
+ };
+
+ template<> struct Promote<int> {
+ typedef int type;
+ };
+
+ template<> struct Promote<float> {
+ typedef double type;
+ };
+
+ Promote<short>::type *ret_intptr(int* ip) { return ip; }
+ Promote<int>::type *ret_intptr2(int* ip) { return ip; }
+ }
+
+ M::Promote<int>::type *ret_intptr3(int* ip) { return ip; }
+ M::template Promote<int>::type *ret_intptr4(int* ip) { return ip; } // expected-warning{{'template' keyword outside of a template}}
+ M::template Promote<int> pi; // expected-warning{{'template' keyword outside of a template}}
+}
+
+N::M::Promote<int>::type *ret_intptr5(int* ip) { return ip; }
+::N::M::Promote<int>::type *ret_intptr6(int* ip) { return ip; }
+
+
+N::M::template; // expected-error{{expected unqualified-id}}
+N::M::template Promote; // expected-error{{expected unqualified-id}}
+
+namespace N {
+ template<typename T> struct A;
+
+ template<>
+ struct A<int> {
+ struct X;
+ };
+
+ struct B;
+}
+
+struct ::N::A<int>::X {
+ int foo;
+};
+
+template<typename T>
+struct TestA {
+ typedef typename N::template B<T>::type type; // expected-error{{'B' following the 'template' keyword does not refer to a template}} \
+ // expected-error{{expected member name}}
+};
+
+// Reduced from a Boost failure.
+namespace test1 {
+ template <class T> struct pair {
+ T x;
+ T y;
+
+ static T pair<T>::* const mem_array[2];
+ };
+
+ template <class T>
+ T pair<T>::* const pair<T>::mem_array[2] = { &pair<T>::x, &pair<T>::y };
+}
+
+typedef int T;
+namespace N1 {
+ template<typename T> T f0();
+}
+
+template<typename T> T N1::f0() { }
+
+namespace PR7385 {
+ template< typename > struct has_xxx0
+ {
+ template< typename > struct has_xxx0_introspect
+ {
+ template< typename > struct has_xxx0_substitute ;
+ template< typename V >
+ int int00( has_xxx0_substitute < typename V::template xxx< > > = 0 );
+ };
+ static const int value = has_xxx0_introspect<int>::value; // expected-error{{no member named 'value'}}
+ typedef int type;
+ };
+
+ has_xxx0<int>::type t; // expected-note{{instantiation of}}
+}
+
+namespace PR7725 {
+ template<class ignored> struct TypedefProvider;
+ template<typename T>
+ struct TemplateClass : public TypedefProvider<T>
+ {
+ void PrintSelf() {
+ TemplateClass::Test::PrintSelf();
+ }
+ };
+}
+
+namespace PR9226 {
+ template<typename a>
+ void nt() // expected-note{{function template 'nt' declared here}}
+ { nt<>:: } // expected-error{{qualified name refers into a specialization of function template 'nt'}} \
+ // expected-error{{expected unqualified-id}}
+
+ template<typename T>
+ void f(T*); // expected-note{{function template 'f' declared here}}
+
+ template<typename T>
+ void f(T*, T*); // expected-note{{function template 'f' declared here}}
+
+ void g() {
+ f<int>:: // expected-error{{qualified name refers into a specialization of function template 'f'}}
+ } // expected-error{{expected unqualified-id}}
+
+ struct X {
+ template<typename T> void f(); // expected-note{{function template 'f' declared here}}
+ };
+
+ template<typename T, typename U>
+ struct Y {
+ typedef typename T::template f<U> type; // expected-error{{template name refers to non-type template 'X::f'}}
+ };
+
+ Y<X, int> yxi; // expected-note{{in instantiation of template class 'PR9226::Y<PR9226::X, int>' requested here}}
+}
+
+namespace PR9449 {
+ template <typename T>
+ struct s; // expected-note{{template is declared here}}
+
+ template <typename T>
+ void f() {
+ int s<T>::template n<T>::* f; // expected-error{{implicit instantiation of undefined template 'PR9449::s<int>'}} \
+ // expected-error{{following the 'template' keyword}}
+ }
+
+ template void f<int>(); // expected-note{{in instantiation of}}
+}
diff --git a/clang/test/SemaTemplate/nested-template.cpp b/clang/test/SemaTemplate/nested-template.cpp
new file mode 100644
index 0000000..7849bae
--- /dev/null
+++ b/clang/test/SemaTemplate/nested-template.cpp
@@ -0,0 +1,157 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+class A;
+
+class S {
+public:
+ template<typename T> struct A {
+ struct Nested {
+ typedef T type;
+ };
+ };
+};
+
+int i;
+S::A<int>::Nested::type *ip = &i;
+
+template<typename T>
+struct Outer {
+ template<typename U>
+ class Inner0;
+
+ template<typename U>
+ class Inner1 {
+ struct ReallyInner;
+
+ T foo(U);
+ template<typename V> T bar(V);
+ template<typename V> T* bar(V);
+
+ static T value1;
+ static U value2;
+ };
+};
+
+template<typename X>
+template<typename Y>
+class Outer<X>::Inner0 {
+public:
+ void f(X, Y);
+};
+
+template<typename X>
+template<typename Y>
+void Outer<X>::Inner0<Y>::f(X, Y) {
+}
+
+template<typename X>
+template<typename Y>
+struct Outer<X>::Inner1<Y>::ReallyInner {
+ static Y value3;
+
+ void g(X, Y);
+};
+
+template<typename X>
+template<typename Y>
+void Outer<X>::Inner1<Y>::ReallyInner::g(X, Y) {
+}
+
+template<typename X>
+template<typename Y>
+X Outer<X>::Inner1<Y>::foo(Y) {
+ return X();
+}
+
+template<typename X>
+template<typename Y>
+template<typename Z>
+X Outer<X>::Inner1<Y>::bar(Z) {
+ return X();
+}
+
+template<typename X>
+template<typename Y>
+template<typename Z>
+X* Outer<X>::Inner1<Y>::bar(Z) {
+ return 0;
+}
+
+template<typename X>
+template<typename Y>
+X Outer<X>::Inner1<Y>::value1 = 0;
+
+template<typename X>
+template<typename Y>
+Y Outer<X>::Inner1<Y>::value2 = Y();
+
+template<typename X>
+template<typename Y>
+Y Outer<X>::Inner1<Y>::ReallyInner::value3 = Y();
+
+template<typename X>
+template<typename Y>
+Y Outer<X>::Inner1<Y*>::ReallyInner::value4; // expected-error{{Outer<X>::Inner1<Y *>::ReallyInner::}}
+
+
+template<typename T>
+struct X0 { };
+
+template<typename T>
+struct X0<T*> {
+ template<typename U>
+ void f(U u = T()) { }
+};
+
+// PR5103
+template<typename>
+struct X1 {
+ template<typename, bool = false> struct B { };
+};
+template struct X1<int>::B<bool>;
+
+// Template template parameters
+template<typename T>
+struct X2 {
+ template<template<class U, T Value> class> // expected-error{{cannot have type 'float'}} \
+ // expected-note{{previous non-type template}}
+ struct Inner { };
+};
+
+template<typename T,
+ int Value> // expected-note{{template non-type parameter}}
+ struct X2_arg;
+
+X2<int>::Inner<X2_arg> x2i1;
+X2<float> x2a; // expected-note{{instantiation}}
+X2<long>::Inner<X2_arg> x2i3; // expected-error{{template template argument has different}}
+
+namespace PR10896 {
+ template<typename TN>
+ class Foo {
+
+ public:
+ void foo() {}
+ private:
+
+ template<typename T>
+ T SomeField; // expected-error {{member 'SomeField' declared as a template}}
+ };
+
+ void g() {
+ Foo<int> f;
+ f.foo();
+ }
+}
+
+namespace PR10924 {
+ template< class Topology, class ctype >
+ struct ReferenceElement
+ {
+ };
+
+ template< class Topology, class ctype >
+ template< int codim >
+ class ReferenceElement< Topology, ctype > :: BaryCenterArray // expected-error{{out-of-line definition of 'BaryCenterArray' does not match any declaration in 'ReferenceElement<Topology, ctype>'}}
+ {
+ };
+}
diff --git a/clang/test/SemaTemplate/operator-function-id-template.cpp b/clang/test/SemaTemplate/operator-function-id-template.cpp
new file mode 100644
index 0000000..9a0884e
--- /dev/null
+++ b/clang/test/SemaTemplate/operator-function-id-template.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct A {
+ template<typename U> A<T> operator+(U);
+};
+
+template<int Value, typename T> bool operator==(A<T>, A<T>);
+
+template<> bool operator==<0>(A<int>, A<int>);
+
+bool test_qualified_id(A<int> ai) {
+ return ::operator==<0, int>(ai, ai);
+}
+
+void test_op(A<int> a, int i) {
+ const A<int> &air = a.operator+<int>(i);
+}
+
+template<typename T>
+void test_op_template(A<T> at, T x) {
+ const A<T> &atr = at.template operator+<T>(x);
+ const A<T> &atr2 = at.A::template operator+<T>(x);
+ // FIXME: unrelated template-name instantiation issue
+ // const A<T> &atr3 = at.template A<T>::template operator+<T>(x);
+}
+
+template void test_op_template<float>(A<float>, float);
diff --git a/clang/test/SemaTemplate/operator-template.cpp b/clang/test/SemaTemplate/operator-template.cpp
new file mode 100644
index 0000000..777b0f5
--- /dev/null
+++ b/clang/test/SemaTemplate/operator-template.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// Make sure we accept this
+template<class X>struct A{typedef X Y;};
+template<class X>bool operator==(A<X>,typename A<X>::Y); // expected-note{{candidate template ignored: failed template argument deduction}}
+
+int a(A<int> x) { return operator==(x,1); }
+
+int a0(A<int> x) { return x == 1; }
+
+// FIXME: the location information for the note isn't very good
+template<class X>struct B{typedef X Y;};
+template<class X>bool operator==(B<X>*,typename B<X>::Y); // \
+// expected-error{{overloaded 'operator==' must have at least one parameter of class or enumeration type}} \
+// expected-note{{in instantiation of function template specialization}} \
+// expected-note{{candidate template ignored: substitution failure [with X = int]}}
+int a(B<int> x) { return operator==(&x,1); } // expected-error{{no matching function for call to 'operator=='}}
+
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp
new file mode 100644
index 0000000..8762cc8
--- /dev/null
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -0,0 +1,40 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+const T& min(const T&, const T&); // expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'long')}}
+
+void test_min() {
+ (void)min(1, 2l); // expected-error{{no matching function for call to 'min'}}
+}
+
+template<typename R, typename T>
+R *dyn_cast(const T&); // expected-note{{candidate template ignored: couldn't infer template argument 'R'}}
+
+void test_dyn_cast(int* ptr) {
+ (void)dyn_cast(ptr); // expected-error{{no matching function for call to 'dyn_cast'}}
+}
+
+template<int I, typename T>
+ void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I'}}
+template<template<class T> class, typename T>
+ void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
+
+void test_get(void *ptr) {
+ get<int>(ptr); // expected-error{{no matching function for call to 'get'}}
+}
+
+template<typename T>
+ typename T::type get_type(const T&); // expected-note{{candidate template ignored: substitution failure [with T = int *]}}
+
+void test_get_type(int *ptr) {
+ (void)get_type(ptr); // expected-error{{no matching function for call to 'get_type'}}
+}
+
+struct X {
+ template<typename T>
+ const T& min(const T&, const T&); // expected-note{{candidate template ignored: deduced conflicting types for parameter 'T' ('int' vs. 'long')}}
+};
+
+void test_X_min(X x) {
+ (void)x.min(1, 2l); // expected-error{{no matching member function for call to 'min'}}
+}
diff --git a/clang/test/SemaTemplate/overload-uneval.cpp b/clang/test/SemaTemplate/overload-uneval.cpp
new file mode 100644
index 0000000..8d8a2f4
--- /dev/null
+++ b/clang/test/SemaTemplate/overload-uneval.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-unused %s
+
+// Tests that overload resolution is treated as an unevaluated context.
+// PR5541
+struct Foo
+{
+ Foo *next;
+};
+
+template <typename>
+struct Bar
+{
+};
+
+
+template <typename T>
+class Wibble
+{
+ typedef Bar<T> B;
+
+ static inline B *concrete(Foo *node) {
+ int a[sizeof(T) ? -1 : -1];
+ return reinterpret_cast<B *>(node);
+ }
+
+public:
+ class It
+ {
+ Foo *i;
+
+ public:
+ inline operator B *() const { return concrete(i); }
+ inline bool operator!=(const It &o) const { return i !=
+o.i; }
+ };
+};
+
+void f() {
+ Wibble<void*>::It a, b;
+
+ a != b;
+}
diff --git a/clang/test/SemaTemplate/partial-spec-instantiate.cpp b/clang/test/SemaTemplate/partial-spec-instantiate.cpp
new file mode 100644
index 0000000..a93af50
--- /dev/null
+++ b/clang/test/SemaTemplate/partial-spec-instantiate.cpp
@@ -0,0 +1,50 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+// PR4607
+template <class T> struct X {};
+
+template <> struct X<char>
+{
+ static char* g();
+};
+
+template <class T> struct X2 {};
+
+template <class U>
+struct X2<U*> {
+ static void f() {
+ X<U>::g();
+ }
+};
+
+void a(char *a, char *b) {X2<char*>::f();}
+
+namespace WonkyAccess {
+ template<typename T>
+ struct X {
+ int m;
+ };
+
+ template<typename U>
+ class Y;
+
+ template<typename U>
+ struct Y<U*> : X<U> { };
+
+ template<>
+ struct Y<float*> : X<float> { };
+
+ int f(Y<int*> y, Y<float*> y2) {
+ return y.m + y2.m;
+ }
+}
+
+// <rdar://problem/9169404>
+namespace rdar9169404 {
+ template<typename T, T N> struct X { };
+ template<bool C> struct X<bool, C> {
+ typedef int type;
+ };
+
+ X<bool, -1>::type value;
+}
diff --git a/clang/test/SemaTemplate/pragma-ms_struct.cpp b/clang/test/SemaTemplate/pragma-ms_struct.cpp
new file mode 100644
index 0000000..f04dc5c
--- /dev/null
+++ b/clang/test/SemaTemplate/pragma-ms_struct.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -triple i686-apple-osx10.7.0 %s
+
+#pragma ms_struct on
+
+// <rdar://problem/10791194>
+template<int x> struct foo {
+ long long a;
+ int b;
+};
+extern int arr[sizeof(foo<0>) == 16 ? 1 : -1];
diff --git a/clang/test/SemaTemplate/qualified-id.cpp b/clang/test/SemaTemplate/qualified-id.cpp
new file mode 100644
index 0000000..64dff1c
--- /dev/null
+++ b/clang/test/SemaTemplate/qualified-id.cpp
@@ -0,0 +1,56 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR5061
+namespace a {
+ template <typename T> class C {};
+}
+namespace b {
+ template<typename T> void f0(a::C<T> &a0) { }
+}
+
+
+namespace test1 {
+ int a = 0;
+ template <class T> class Base { };
+ template <class T> class Derived : public Base<T> {
+ int foo() {
+ return test1::a;
+ }
+ };
+}
+
+namespace test2 {
+ class Impl {
+ public:
+ int foo();
+ };
+ template <class T> class Magic : public Impl {
+ int foo() {
+ return Impl::foo();
+ }
+ };
+}
+
+namespace PR6063 {
+ template <typename T> void f(T, T);
+
+ namespace detail
+ {
+ using PR6063::f;
+ }
+
+ template <typename T>
+ void g(T a, T b)
+ {
+ detail::f(a, b);
+ }
+}
+
+namespace PR12291 {
+ template <typename T>
+ class Outer2 {
+ template <typename V>
+ template <typename W>
+ class Outer2<V>::Inner; // expected-error{{nested name specifier 'Outer2<V>::' for declaration does not refer into a class, class template or class template partial specialization}}
+ };
+}
diff --git a/clang/test/SemaTemplate/qualified-names-diag.cpp b/clang/test/SemaTemplate/qualified-names-diag.cpp
new file mode 100644
index 0000000..b2df47b
--- /dev/null
+++ b/clang/test/SemaTemplate/qualified-names-diag.cpp
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace std {
+ template<typename T> class vector { }; // expected-note{{candidate}}
+}
+
+typedef int INT;
+typedef float Real;
+
+void test() {
+ using namespace std;
+
+ std::vector<INT> v1;
+ vector<Real> v2;
+ v1 = v2; // expected-error{{no viable overloaded '='}}
+}
diff --git a/clang/test/SemaTemplate/rdar9173693.cpp b/clang/test/SemaTemplate/rdar9173693.cpp
new file mode 100644
index 0000000..86b4954
--- /dev/null
+++ b/clang/test/SemaTemplate/rdar9173693.cpp
@@ -0,0 +1,6 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// <rdar://problem/9173693>
+template< bool C > struct assert { };
+template< bool > struct assert_arg_pred_impl { }; // expected-note 3 {{declared here}}
+template< typename Pred > assert<false> assert_not_arg( void (*)(Pred), typename assert_arg_pred<Pred>::type ); // expected-error 5 {{}}
diff --git a/clang/test/SemaTemplate/recovery-crash.cpp b/clang/test/SemaTemplate/recovery-crash.cpp
new file mode 100644
index 0000000..0ed3258
--- /dev/null
+++ b/clang/test/SemaTemplate/recovery-crash.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// We don't expect a fix-it to be applied in this case. Clang used to crash
+// trying to recover while adding 'this->' before Work(x);
+
+template <typename> struct A {
+ static void Work(int); // expected-note{{must qualify identifier}}
+};
+
+template <typename T> struct B : public A<T> {
+ template <typename T2> B(T2 x) {
+ Work(x); // expected-error{{use of undeclared identifier}}
+ }
+};
+
+void Test() {
+ B<int> b(0); // expected-note{{in instantiation of function template}}
+}
+
diff --git a/clang/test/SemaTemplate/recursive-template-instantiation.cpp b/clang/test/SemaTemplate/recursive-template-instantiation.cpp
new file mode 100644
index 0000000..d6a0b24
--- /dev/null
+++ b/clang/test/SemaTemplate/recursive-template-instantiation.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> void f(T* t) { // expected-note{{failed template argument deduction}}
+ f(*t); // expected-error{{no matching function}}\
+ // expected-note 3{{requested here}}
+}
+
+void test_f(int ****p) {
+ f(p); // expected-note{{requested here}}
+}
diff --git a/clang/test/SemaTemplate/resolve-single-template-id.cpp b/clang/test/SemaTemplate/resolve-single-template-id.cpp
new file mode 100644
index 0000000..0c9bacc
--- /dev/null
+++ b/clang/test/SemaTemplate/resolve-single-template-id.cpp
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
+
+namespace std {
+ class type_info {};
+}
+
+void one() { }
+void two() { } // expected-note 4{{possible target for call}}
+void two(int) { } // expected-note 4{{possible target for call}}
+
+template<class T> void twoT() { } // expected-note 5{{possible target for call}}
+template<class T> void twoT(int) { } // expected-note 5{{possible target for call}}
+
+template<class T> void oneT() { }
+template<class T, class U> void oneT(U) { }
+/*
+The target can be
+ an object or reference being initialized (8.5, 8.5.3),
+ the left side of an assignment (5.17),
+ a parameter of a function (5.2.2),
+ a parameter of a user-defined operator (13.5),
+ the return value of a function, operator function, or conversion (6.6.3),
+ an explicit type conversion (5.2.3, 5.2.9, 5.4), or
+ a non-type template-parameter (14.3.2)
+*/
+//#include <typeinfo>
+template<void (*p)(int)> struct test { };
+
+int main()
+{
+ one; // expected-warning {{expression result unused}}
+ two; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}}
+ oneT<int>; // expected-warning {{expression result unused}}
+ twoT<int>; // expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
+ typeid(oneT<int>); // expected-warning{{expression result unused}}
+ sizeof(oneT<int>); // expected-warning {{expression result unused}}
+ sizeof(twoT<int>); //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
+ decltype(oneT<int>)* fun = 0;
+
+ *one; // expected-warning {{expression result unused}}
+ *oneT<int>; // expected-warning {{expression result unused}}
+ *two; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} expected-error {{indirection requires pointer operand}}
+ *twoT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}}
+ !oneT<int>; // expected-warning {{expression result unused}} expected-warning {{address of function 'oneT<int>' will always evaluate to 'true'}} expected-note {{prefix with the address-of operator to silence this warning}}
+ +oneT<int>; // expected-warning {{expression result unused}}
+ -oneT<int>; //expected-error {{invalid argument type}}
+ oneT<int> == 0; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+ 0 == oneT<int>; // expected-warning {{equality comparison result unused}}
+ 0 != oneT<int>; // expected-warning {{inequality comparison result unused}}
+ (false ? one : oneT<int>); // expected-warning {{expression result unused}}
+ void (*p1)(int); p1 = oneT<int>;
+
+ int i = (int) (false ? (void (*)(int))twoT<int> : oneT<int>); //expected-error {{incompatible operand}}
+ (twoT<int>) == oneT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} {{cannot resolve overloaded function 'twoT' from context}}
+ bool b = oneT<int>; // expected-warning {{address of function 'oneT<int>' will always evaluate to 'true'}} expected-note {{prefix with the address-of operator to silence this warning}}
+ void (*p)() = oneT<int>;
+ test<oneT<int> > ti;
+ void (*u)(int) = oneT<int>;
+
+ b = (void (*)()) twoT<int>;
+
+ one < one; //expected-warning {{self-comparison always evaluates to false}} \
+ //expected-warning {{expression result unused}}
+
+ oneT<int> < oneT<int>; //expected-warning {{self-comparison always evaluates to false}} \
+ //expected-warning {{expression result unused}}
+
+ two < two; //expected-error 2 {{reference to overloaded function could not be resolved; did you mean to call it with no arguments?}} expected-error {{invalid operands to binary expression ('void' and 'void')}}
+ twoT<int> < twoT<int>; //expected-error {{reference to overloaded function could not be resolved; did you mean to call it?}} {{cannot resolve overloaded function 'twoT' from context}}
+ oneT<int> == 0; // expected-warning {{equality comparison result unused}} \
+ // expected-note {{use '=' to turn this equality comparison into an assignment}}
+
+}
+
+struct rdar9108698 {
+ template<typename> void f();
+};
+
+void test_rdar9108698(rdar9108698 x) {
+ x.f<int>; // expected-error{{reference to non-static member function must be called}}
+}
diff --git a/clang/test/SemaTemplate/self-comparison.cpp b/clang/test/SemaTemplate/self-comparison.cpp
new file mode 100644
index 0000000..50ab660
--- /dev/null
+++ b/clang/test/SemaTemplate/self-comparison.cpp
@@ -0,0 +1,48 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template <int A, int B> void foo() {
+ (void)(A == A); // expected-warning {{self-comparison always evaluates to true}}
+ (void)(A == B);
+}
+template <int A, int B> struct S1 {
+ void foo() {
+ (void)(A == A); // expected-warning {{self-comparison always evaluates to true}}
+ (void)(A == B);
+ }
+};
+
+template <int A, int B> struct S2 {
+ template <typename T> T foo() {
+ (void)(A == A); // expected-warning {{self-comparison always evaluates to true}}
+ (void)(A == B);
+ }
+};
+
+struct S3 {
+ template <int A, int B> void foo() {
+ (void)(A == A); // expected-warning {{self-comparison always evaluates to true}}
+ (void)(A == B);
+ }
+};
+
+template <int A> struct S4 {
+ template <int B> void foo() {
+ (void)(A == A); // expected-warning {{self-comparison always evaluates to true}}
+ (void)(A == B);
+ }
+};
+
+const int N = 42;
+template <int X> void foo2() {
+ (void)(X == N);
+ (void)(N == X);
+}
+
+void test() {
+ foo<1, 1>();
+ S1<1, 1> s1; s1.foo();
+ S2<1, 1> s2; s2.foo<void>();
+ S3 s3; s3.foo<1, 1>();
+ S4<1> s4; s4.foo<1>();
+ foo2<N>();
+}
diff --git a/clang/test/SemaTemplate/temp.cpp b/clang/test/SemaTemplate/temp.cpp
new file mode 100644
index 0000000..e037f0f
--- /dev/null
+++ b/clang/test/SemaTemplate/temp.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+
+namespace test0 {
+ // p3
+ template<typename T> int foo(T), bar(T, T); // expected-error{{single entity}}
+}
+
+// PR7252
+namespace test1 {
+ namespace A { template<typename T> struct Base { typedef T t; }; } // expected-note {{member found}}
+ namespace B { template<typename T> struct Base { typedef T t; }; } // expected-note {{member found}}
+
+ template<typename T> struct Derived : A::Base<char>, B::Base<int> {
+ // FIXME: the syntax error here is unfortunate
+ typename Derived::Base<float>::t x; // expected-error {{found in multiple base classes of different types}} \
+ // expected-error {{expected member name or ';'}}
+ };
+}
diff --git a/clang/test/SemaTemplate/temp_arg.cpp b/clang/test/SemaTemplate/temp_arg.cpp
new file mode 100644
index 0000000..5a4c8fc
--- /dev/null
+++ b/clang/test/SemaTemplate/temp_arg.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T,
+ int I,
+ template<typename> class TT>
+ class A; // expected-note 3 {{template is declared here}}
+
+template<typename> class X;
+
+A<int, 0, X> * a1;
+
+A<float, 1, X, double> *a2; // expected-error{{too many template arguments for class template 'A'}}
+A<float, 1> *a3; // expected-error{{too few template arguments for class template 'A'}}
+A a3; // expected-error{{use of class template A requires template arguments}}
+
+namespace test0 {
+ template <class t> class foo {};
+ template <class t> class bar {
+ bar(::test0::foo<tee> *ptr) {} // FIXME(redundant): expected-error 2 {{use of undeclared identifier 'tee'}}
+ };
+}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp b/clang/test/SemaTemplate/temp_arg_nontype.cpp
new file mode 100644
index 0000000..747ddcc
--- /dev/null
+++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -0,0 +1,325 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wconversion -verify %s
+template<int N> struct A; // expected-note 5{{template parameter is declared here}}
+
+A<0> *a0;
+
+A<int()> *a1; // expected-error{{template argument for non-type template parameter is treated as type 'int ()'}}
+
+A<int> *a2; // expected-error{{template argument for non-type template parameter must be an expression}}
+
+A<1 >> 2> *a3; // expected-warning{{use of right-shift operator ('>>') in template argument will require parentheses in C++11}}
+
+// C++ [temp.arg.nontype]p5:
+A<A> *a4; // expected-error{{must be an expression}}
+
+enum E { Enumerator = 17 };
+A<E> *a5; // expected-error{{template argument for non-type template parameter must be an expression}}
+template<E Value> struct A1; // expected-note{{template parameter is declared here}}
+A1<Enumerator> *a6; // okay
+A1<17> *a7; // expected-error{{non-type template argument of type 'int' cannot be converted to a value of type 'E'}}
+
+const long LongValue = 12345678;
+A<LongValue> *a8;
+const short ShortValue = 17;
+A<ShortValue> *a9;
+
+int f(int);
+A<f(17)> *a10; // expected-error{{non-type template argument of type 'int' is not an integral constant expression}}
+
+class X {
+public:
+ X();
+ X(int, int);
+ operator int() const;
+};
+A<X(17, 42)> *a11; // expected-error{{non-type template argument of type 'X' must have an integral or enumeration type}}
+
+float f(float);
+
+float g(float); // expected-note 2{{candidate function}}
+double g(double); // expected-note 2{{candidate function}}
+
+int h(int);
+float h2(float);
+
+template<int fp(int)> struct A3; // expected-note 1{{template parameter is declared here}}
+A3<h> *a14_1;
+A3<&h> *a14_2;
+A3<f> *a14_3;
+A3<&f> *a14_4;
+A3<h2> *a14_6; // expected-error{{non-type template argument of type 'float (float)' cannot be converted to a value of type 'int (*)(int)'}}
+A3<g> *a14_7; // expected-error{{address of overloaded function 'g' does not match required type 'int (int)'}}
+
+
+struct Y { } y;
+
+volatile X * X_volatile_ptr;
+template<X const &AnX> struct A4; // expected-note 2{{template parameter is declared here}}
+X an_X;
+A4<an_X> *a15_1; // okay
+A4<*X_volatile_ptr> *a15_2; // expected-error{{non-type template argument does not refer to any declaration}}
+A4<y> *15_3; // expected-error{{non-type template parameter of reference type 'const X &' cannot bind to template argument of type 'struct Y'}} \
+ // FIXME: expected-error{{expected unqualified-id}}
+
+template<int (&fr)(int)> struct A5; // expected-note{{template parameter is declared here}}
+A5<h> *a16_1;
+A5<f> *a16_3;
+A5<h2> *a16_6; // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'float (float)'}}
+A5<g> *a14_7; // expected-error{{address of overloaded function 'g' does not match required type 'int (int)'}}
+
+struct Z {
+ int foo(int);
+ float bar(float);
+ int bar(int);
+ double baz(double);
+
+ int int_member;
+ float float_member;
+};
+template<int (Z::*pmf)(int)> struct A6; // expected-note{{template parameter is declared here}}
+A6<&Z::foo> *a17_1;
+A6<&Z::bar> *a17_2;
+A6<&Z::baz> *a17_3; // expected-error{{non-type template argument of type 'double (Z::*)(double)' cannot be converted to a value of type 'int (Z::*)(int)'}}
+
+
+template<int Z::*pm> struct A7; // expected-note{{template parameter is declared here}}
+template<int Z::*pm> struct A7c;
+A7<&Z::int_member> *a18_1;
+A7c<&Z::int_member> *a18_2;
+A7<&Z::float_member> *a18_3; // expected-error{{non-type template argument of type 'float Z::*' cannot be converted to a value of type 'int Z::*'}}
+A7c<(&Z::int_member)> *a18_4; // expected-warning{{address non-type template argument cannot be surrounded by parentheses}}
+
+template<unsigned char C> struct Overflow; // expected-note{{template parameter is declared here}}
+
+Overflow<5> *overflow1; // okay
+Overflow<255> *overflow2; // okay
+Overflow<256> *overflow3; // expected-warning{{non-type template argument value '256' truncated to '0' for template parameter of type 'unsigned char'}}
+
+
+template<unsigned> struct Signedness; // expected-note{{template parameter is declared here}}
+Signedness<10> *signedness1; // okay
+Signedness<-10> *signedness2; // expected-warning{{non-type template argument with value '-10' converted to '4294967286' for unsigned template parameter of type 'unsigned int'}}
+
+template<signed char C> struct SignedOverflow; // expected-note 3 {{template parameter is declared here}}
+SignedOverflow<1> *signedoverflow1;
+SignedOverflow<-1> *signedoverflow2;
+SignedOverflow<-128> *signedoverflow3;
+SignedOverflow<-129> *signedoverflow4; // expected-warning{{non-type template argument value '-129' truncated to '127' for template parameter of type 'signed char'}}
+SignedOverflow<127> *signedoverflow5;
+SignedOverflow<128> *signedoverflow6; // expected-warning{{non-type template argument value '128' truncated to '-128' for template parameter of type 'signed char'}}
+SignedOverflow<(unsigned char)128> *signedoverflow7; // expected-warning{{non-type template argument value '128' truncated to '-128' for template parameter of type 'signed char'}}
+
+// Check canonicalization of template arguments.
+template<int (*)(int, int)> struct FuncPtr0;
+int func0(int, int);
+extern FuncPtr0<&func0> *fp0;
+template<int (*)(int, int)> struct FuncPtr0;
+extern FuncPtr0<&func0> *fp0;
+int func0(int, int);
+extern FuncPtr0<&func0> *fp0;
+
+// PR5350
+namespace ns {
+ template <typename T>
+ struct Foo {
+ static const bool value = true;
+ };
+
+ template <bool b>
+ struct Bar {};
+
+ const bool value = false;
+
+ Bar<bool(ns::Foo<int>::value)> x;
+}
+
+// PR5349
+namespace ns {
+ enum E { k };
+
+ template <E e>
+ struct Baz {};
+
+ Baz<k> f1; // This works.
+ Baz<E(0)> f2; // This too.
+ Baz<static_cast<E>(0)> f3; // And this.
+
+ Baz<ns::E(0)> b1; // This doesn't work.
+ Baz<static_cast<ns::E>(0)> b2; // This neither.
+}
+
+// PR5597
+template<int (*)(float)> struct X0 { };
+
+struct X1 {
+ static int pfunc(float);
+};
+void test_X0_X1() {
+ X0<X1::pfunc> x01;
+}
+
+// PR6249
+namespace pr6249 {
+ template<typename T, T (*func)()> T f() {
+ return func();
+ }
+
+ int h();
+ template int f<int, h>();
+}
+
+namespace PR6723 {
+ template<unsigned char C> void f(int (&a)[C]); // expected-note {{candidate template ignored}} \
+ // expected-note{{substitution failure [with C = '\x00']}}
+ void g() {
+ int arr512[512];
+ f(arr512); // expected-error{{no matching function for call}}
+ f<512>(arr512); // expected-error{{no matching function for call}}
+ }
+}
+
+// Check that we instantiate declarations whose addresses are taken
+// for non-type template arguments.
+namespace EntityReferenced {
+ template<typename T, void (*)(T)> struct X { };
+
+ template<typename T>
+ struct Y {
+ static void f(T x) {
+ x = 1; // expected-error{{assigning to 'int *' from incompatible type 'int'}}
+ }
+ };
+
+ void g() {
+ typedef X<int*, Y<int*>::f> x; // expected-note{{in instantiation of}}
+ }
+}
+
+namespace PR6964 {
+ template <typename ,int, int = 9223372036854775807L > // expected-warning 2{{non-type template argument value '9223372036854775807' truncated to '-1' for template parameter of type 'int'}} \
+ // expected-note 2{{template parameter is declared here}}
+ struct as_nview { };
+
+ template <typename Sequence, int I0>
+ struct as_nview<Sequence, I0> // expected-note{{while checking a default template argument used here}}
+ { };
+}
+
+// rdar://problem/8302138
+namespace test8 {
+ template <int* ip> struct A {
+ int* p;
+ A() : p(ip) {}
+ };
+
+ void test0() {
+ extern int i00;
+ A<&i00> a00;
+ }
+
+ extern int i01;
+ void test1() {
+ A<&i01> a01;
+ }
+
+
+ struct C {
+ int x;
+ char y;
+ double z;
+ };
+
+ template <C* cp> struct B {
+ C* p;
+ B() : p(cp) {}
+ };
+
+ void test2() {
+ extern C c02;
+ B<&c02> b02;
+ }
+
+ extern C c03;
+ void test3() {
+ B<&c03> b03;
+ }
+}
+
+namespace PR8372 {
+ template <int I> void foo() { } // expected-note{{template parameter is declared here}}
+ void bar() { foo <0x80000000> (); } // expected-warning{{non-type template argument value '2147483648' truncated to '-2147483648' for template parameter of type 'int'}}
+}
+
+namespace PR9227 {
+ template <bool B> struct enable_if_bool { };
+ template <> struct enable_if_bool<true> { typedef int type; };
+ void test_bool() { enable_if_bool<false>::type i; } // expected-error{{enable_if_bool<false>}}
+
+ template <char C> struct enable_if_char { };
+ template <> struct enable_if_char<'a'> { typedef int type; };
+ void test_char_0() { enable_if_char<0>::type i; } // expected-error{{enable_if_char<'\x00'>}}
+ void test_char_b() { enable_if_char<'b'>::type i; } // expected-error{{enable_if_char<'b'>}}
+ void test_char_possibly_negative() { enable_if_char<'\x02'>::type i; } // expected-error{{enable_if_char<'\x02'>}}
+ void test_char_single_quote() { enable_if_char<'\''>::type i; } // expected-error{{enable_if_char<'\''>}}
+ void test_char_backslash() { enable_if_char<'\\'>::type i; } // expected-error{{enable_if_char<'\\'>}}
+}
+
+namespace PR10579 {
+ namespace fcppt
+ {
+ namespace container
+ {
+ namespace bitfield
+ {
+
+ template<
+ typename Enum,
+ Enum Size
+ >
+ class basic;
+
+ template<
+ typename Enum,
+ Enum Size
+ >
+ class basic
+ {
+ public:
+ basic()
+ {
+ }
+ };
+
+ }
+ }
+ }
+
+ namespace
+ {
+
+ namespace testenum
+ {
+ enum type
+ {
+ foo,
+ bar,
+ size
+ };
+ }
+
+ }
+
+ int main()
+ {
+ typedef fcppt::container::bitfield::basic<
+ testenum::type,
+ testenum::size
+ > bitfield_foo;
+
+ bitfield_foo obj;
+ }
+
+}
+
+template <int& I> struct PR10766 { static int *ip; };
+template <int& I> int* PR10766<I>::ip = &I;
diff --git a/clang/test/SemaTemplate/temp_arg_template.cpp b/clang/test/SemaTemplate/temp_arg_template.cpp
new file mode 100644
index 0000000..c9ce1b6
--- /dev/null
+++ b/clang/test/SemaTemplate/temp_arg_template.cpp
@@ -0,0 +1,62 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<template<typename T> class X> struct A; // expected-note 2{{previous template template parameter is here}}
+
+template<template<typename T, int I> class X> struct B; // expected-note{{previous template template parameter is here}}
+
+template<template<int I> class X> struct C; // expected-note{{previous non-type template parameter with type 'int' is here}}
+
+template<class> struct X; // expected-note{{too few template parameters in template template argument}}
+template<int N> struct Y; // expected-note{{template parameter has a different kind in template argument}}
+template<long N> struct Ylong; // expected-note{{template non-type parameter has a different type 'long' in template argument}}
+
+namespace N {
+ template<class> struct Z;
+}
+template<class, class> struct TooMany; // expected-note{{too many template parameters in template template argument}}
+
+
+A<X> *a1;
+A<N::Z> *a2;
+A< ::N::Z> *a3;
+
+A<Y> *a4; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+A<TooMany> *a5; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+B<X> *a6; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+C<Y> *a7;
+C<Ylong> *a8; // expected-error{{template template argument has different template parameters than its corresponding template template parameter}}
+
+template<typename T> void f(int);
+
+A<f> *a9; // expected-error{{must be a class template}}
+
+// Evil digraph '<:' is parsed as '[', expect error.
+A<::N::Z> *a10; // expected-error{{found '<::' after a template name which forms the digraph '<:' (aka '[') and a ':', did you mean '< ::'?}}
+
+// Do not do a digraph correction here.
+A<: :N::Z> *a11; // expected-error{{expected expression}} \
+ expected-error{{C++ requires a type specifier for all declarations}}
+
+// PR7807
+namespace N {
+ template <typename, typename = int>
+ struct X
+ { };
+
+ template <typename ,int>
+ struct Y
+ { X<int> const_ref(); };
+
+ template <template<typename,int> class TT, typename T, int N>
+ int operator<<(int, TT<T, N> a) { // expected-note{{candidate template ignored}}
+ 0 << a.const_ref(); // expected-error{{invalid operands to binary expression ('int' and 'X<int>')}}
+ }
+
+ void f0( Y<int,1> y){ 1 << y; } // expected-note{{in instantiation of function template specialization 'N::operator<<<Y, int, 1>' requested here}}
+}
+
+// PR12179
+template <typename Primitive, template <Primitive...> class F> // expected-warning {{variadic templates are a C++11 extension}}
+struct unbox_args {
+ typedef typename Primitive::template call<F> x;
+};
diff --git a/clang/test/SemaTemplate/temp_arg_type.cpp b/clang/test/SemaTemplate/temp_arg_type.cpp
new file mode 100644
index 0000000..3970942
--- /dev/null
+++ b/clang/test/SemaTemplate/temp_arg_type.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T> class A; // expected-note 2 {{template parameter is declared here}} expected-note{{template is declared here}}
+
+// [temp.arg.type]p1
+A<0> *a1; // expected-error{{template argument for template type parameter must be a type}}
+
+A<A> *a2; // expected-error{{use of class template A requires template arguments}}
+
+A<int> *a3;
+A<int()> *a4;
+A<int(float)> *a5;
+A<A<int> > *a6;
+
+// Pass an overloaded function template:
+template<typename T> void function_tpl(T);
+A<function_tpl> a7; // expected-error{{template argument for template type parameter must be a type}}
+
+// Pass a qualified name:
+namespace ns {
+template<typename T> class B {}; // expected-note{{template is declared here}}
+}
+A<ns::B> a8; // expected-error{{use of class template ns::B requires template arguments}}
+
+// [temp.arg.type]p2
+void f() {
+ class X { };
+ A<X> * a = 0; // expected-warning{{template argument uses local type 'X'}}
+}
+
+struct { int x; } Unnamed; // expected-note{{unnamed type used in template argument was declared here}}
+A<__typeof__(Unnamed)> *a9; // expected-warning{{template argument uses unnamed type}}
+
+template<typename T, unsigned N>
+struct Array {
+ typedef struct { T x[N]; } type;
+};
+
+template<typename T> struct A1 { };
+A1<Array<int, 17>::type> ax;
+
+// FIXME: [temp.arg.type]p3. The check doesn't really belong here (it
+// belongs somewhere in the template instantiation section).
diff --git a/clang/test/SemaTemplate/temp_class_order.cpp b/clang/test/SemaTemplate/temp_class_order.cpp
new file mode 100644
index 0000000..fcf0325
--- /dev/null
+++ b/clang/test/SemaTemplate/temp_class_order.cpp
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T, typename U>
+struct X1 {
+ static const int value = 0;
+};
+
+template<typename T, typename U>
+struct X1<T*, U*> {
+ static const int value = 1;
+};
+
+template<typename T>
+struct X1<T*, T*> {
+ static const int value = 2;
+};
+
+template<typename T>
+struct X1<const T*, const T*> {
+ static const int value = 3;
+};
+
+int array0[X1<int, int>::value == 0? 1 : -1];
+int array1[X1<int*, float*>::value == 1? 1 : -1];
+int array2[X1<int*, int*>::value == 2? 1 : -1];
+typedef const int* CIP;
+int array3[X1<const int*, CIP>::value == 3? 1 : -1];
+
+template<typename T, typename U>
+struct X2 { };
+
+template<typename T, typename U>
+struct X2<T*, U> { }; // expected-note{{matches}}
+
+template<typename T, typename U>
+struct X2<T, U*> { }; // expected-note{{matches}}
+
+template<typename T, typename U>
+struct X2<const T*, const U*> { };
+
+X2<int*, int*> x2a; // expected-error{{ambiguous}}
+X2<const int*, const int*> x2b;
diff --git a/clang/test/SemaTemplate/temp_class_spec.cpp b/clang/test/SemaTemplate/temp_class_spec.cpp
new file mode 100644
index 0000000..8a07fd7
--- /dev/null
+++ b/clang/test/SemaTemplate/temp_class_spec.cpp
@@ -0,0 +1,363 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+struct is_pointer {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_pointer<T*> {
+ static const bool value = true;
+};
+
+template<typename T>
+struct is_pointer<const T*> {
+ static const bool value = true;
+};
+
+int array0[is_pointer<int>::value? -1 : 1];
+int array1[is_pointer<int*>::value? 1 : -1];
+int array2[is_pointer<const int*>::value? 1 : -1];
+
+template<typename T>
+struct is_lvalue_reference {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_lvalue_reference<T&> {
+ static const bool value = true;
+};
+
+int lvalue_ref0[is_lvalue_reference<int>::value? -1 : 1];
+int lvalue_ref1[is_lvalue_reference<const int&>::value? 1 : -1];
+
+template<typename T>
+struct is_const {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_const<const T> {
+ static const bool value = true;
+};
+
+int is_const0[is_const<int>::value? -1 : 1];
+int is_const1[is_const<const int>::value? 1 : -1];
+int is_const2[is_const<const volatile int>::value? 1 : -1];
+int is_const3[is_const<const int [3]>::value? 1 : -1];
+int is_const4[is_const<const volatile int[3]>::value? 1 : -1];
+int is_const5[is_const<volatile int[3]>::value? -1 : 1];
+
+template<typename T>
+struct is_volatile {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_volatile<volatile T> {
+ static const bool value = true;
+};
+
+int is_volatile0[is_volatile<int>::value? -1 : 1];
+int is_volatile1[is_volatile<volatile int>::value? 1 : -1];
+int is_volatile2[is_volatile<const volatile int>::value? 1 : -1];
+int is_volatile3[is_volatile<volatile char[3]>::value? 1 : -1];
+
+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;
+};
+
+typedef int INT;
+typedef INT* int_ptr;
+
+int is_same0[is_same<int, int>::value? 1 : -1];
+int is_same1[is_same<int, INT>::value? 1 : -1];
+int is_same2[is_same<const int, int>::value? -1 : 1];
+int is_same3[is_same<int_ptr, int>::value? -1 : 1];
+
+template<typename T>
+struct remove_reference {
+ typedef T type;
+};
+
+template<typename T>
+struct remove_reference<T&> {
+ typedef T type;
+};
+
+int remove_ref0[is_same<remove_reference<int>::type, int>::value? 1 : -1];
+int remove_ref1[is_same<remove_reference<int&>::type, int>::value? 1 : -1];
+
+template<typename T>
+struct remove_const {
+ typedef T type;
+};
+
+template<typename T>
+struct remove_const<const T> {
+ typedef T type;
+};
+
+int remove_const0[is_same<remove_const<const int>::type, int>::value? 1 : -1];
+int remove_const1[is_same<remove_const<const int[3]>::type, int[3]>::value? 1 : -1];
+
+template<typename T>
+struct is_incomplete_array {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_incomplete_array<T[]> {
+ static const bool value = true;
+};
+
+int incomplete_array0[is_incomplete_array<int>::value ? -1 : 1];
+int incomplete_array1[is_incomplete_array<int[1]>::value ? -1 : 1];
+int incomplete_array2[is_incomplete_array<bool[]>::value ? 1 : -1];
+int incomplete_array3[is_incomplete_array<int[]>::value ? 1 : -1];
+
+template<typename T>
+struct is_array_with_4_elements {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_array_with_4_elements<T[4]> {
+ static const bool value = true;
+};
+
+int array_with_4_elements0[is_array_with_4_elements<int[]>::value ? -1 : 1];
+int array_with_4_elements1[is_array_with_4_elements<int[1]>::value ? -1 : 1];
+int array_with_4_elements2[is_array_with_4_elements<int[4]>::value ? 1 : -1];
+int array_with_4_elements3[is_array_with_4_elements<int[4][2]>::value ? 1 : -1];
+
+template<typename T>
+struct get_array_size;
+
+template<typename T, unsigned N>
+struct get_array_size<T[N]> {
+ static const unsigned value = N;
+};
+
+int array_size0[get_array_size<int[12]>::value == 12? 1 : -1];
+
+template<typename T>
+struct remove_extent {
+ typedef T type;
+};
+
+template<typename T>
+struct remove_extent<T[]> {
+ typedef T type;
+};
+
+template<typename T, unsigned N>
+struct remove_extent<T[N]> {
+ typedef T type;
+};
+
+int remove_extent0[is_same<remove_extent<int[][5]>::type, int[5]>::value? 1 : -1];
+int remove_extent1[is_same<remove_extent<const int[][5]>::type, const int[5]>::value? 1 : -1];
+
+template<typename T>
+struct is_unary_function {
+ static const bool value = false;
+};
+
+template<typename T, typename U>
+struct is_unary_function<T (*)(U)> {
+ static const bool value = true;
+};
+
+int is_unary_function0[is_unary_function<int>::value ? -1 : 1];
+int is_unary_function1[is_unary_function<int (*)()>::value ? -1 : 1];
+int is_unary_function2[is_unary_function<int (*)(int, bool)>::value ? -1 : 1];
+int is_unary_function3[is_unary_function<int (*)(bool)>::value ? 1 : -1];
+int is_unary_function4[is_unary_function<int (*)(int)>::value ? 1 : -1];
+
+template<typename T>
+struct is_unary_function_with_same_return_type_as_argument_type {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_unary_function_with_same_return_type_as_argument_type<T (*)(T)> {
+ static const bool value = true;
+};
+
+int is_unary_function5[is_unary_function_with_same_return_type_as_argument_type<int>::value ? -1 : 1];
+int is_unary_function6[is_unary_function_with_same_return_type_as_argument_type<int (*)()>::value ? -1 : 1];
+int is_unary_function7[is_unary_function_with_same_return_type_as_argument_type<int (*)(int, bool)>::value ? -1 : 1];
+int is_unary_function8[is_unary_function_with_same_return_type_as_argument_type<int (*)(bool)>::value ? -1 : 1];
+int is_unary_function9[is_unary_function_with_same_return_type_as_argument_type<int (*)(int)>::value ? 1 : -1];
+int is_unary_function10[is_unary_function_with_same_return_type_as_argument_type<int (*)(int, ...)>::value ? -1 : 1];
+int is_unary_function11[is_unary_function_with_same_return_type_as_argument_type<int (* const)(int)>::value ? -1 : 1];
+
+template<typename T>
+struct is_binary_function {
+ static const bool value = false;
+};
+
+template<typename R, typename T1, typename T2>
+struct is_binary_function<R(T1, T2)> {
+ static const bool value = true;
+};
+
+int is_binary_function0[is_binary_function<int(float, double)>::value? 1 : -1];
+
+template<typename T>
+struct is_member_pointer {
+ static const bool value = false;
+};
+
+template<typename T, typename Class>
+struct is_member_pointer<T Class::*> {
+ static const bool value = true;
+};
+
+struct X { };
+
+int is_member_pointer0[is_member_pointer<int X::*>::value? 1 : -1];
+int is_member_pointer1[is_member_pointer<const int X::*>::value? 1 : -1];
+int is_member_pointer2[is_member_pointer<int (X::*)()>::value? 1 : -1];
+int is_member_pointer3[is_member_pointer<int (X::*)(int) const>::value? 1 : -1];
+int is_member_pointer4[is_member_pointer<int (X::**)(int) const>::value? -1 : 1];
+int is_member_pointer5[is_member_pointer<int>::value? -1 : 1];
+
+template<typename T>
+struct is_member_function_pointer {
+ static const bool value = false;
+};
+
+template<typename T, typename Class>
+struct is_member_function_pointer<T (Class::*)()> {
+ static const bool value = true;
+};
+
+template<typename T, typename Class>
+struct is_member_function_pointer<T (Class::*)() const> {
+ static const bool value = true;
+};
+
+template<typename T, typename Class>
+struct is_member_function_pointer<T (Class::*)() volatile> {
+ static const bool value = true;
+};
+
+template<typename T, typename Class>
+struct is_member_function_pointer<T (Class::*)() const volatile> {
+ static const bool value = true;
+};
+
+template<typename T, typename Class, typename A1>
+struct is_member_function_pointer<T (Class::*)(A1)> {
+ static const bool value = true;
+};
+
+template<typename T, typename Class, typename A1>
+struct is_member_function_pointer<T (Class::*)(A1) const> {
+ static const bool value = true;
+};
+
+template<typename T, typename Class, typename A1>
+struct is_member_function_pointer<T (Class::*)(A1) volatile> {
+ static const bool value = true;
+};
+
+template<typename T, typename Class, typename A1>
+struct is_member_function_pointer<T (Class::*)(A1) const volatile> {
+ static const bool value = true;
+};
+
+int is_member_function_pointer0[
+ is_member_function_pointer<int X::*>::value? -1 : 1];
+int is_member_function_pointer1[
+ is_member_function_pointer<int (X::*)()>::value? 1 : -1];
+int is_member_function_pointer2[
+ is_member_function_pointer<X (X::*)(X&)>::value? 1 : -1];
+int is_member_function_pointer3[
+ is_member_function_pointer<int (X::*)() const>::value? 1 : -1];
+int is_member_function_pointer4[
+ is_member_function_pointer<int (X::*)(float) const>::value? 1 : -1];
+
+// Test substitution of non-dependent arguments back into the template
+// argument list of the class template partial specialization.
+template<typename T, typename ValueType = T>
+struct is_nested_value_type_identity {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_nested_value_type_identity<T, typename T::value_type> {
+ static const bool value = true;
+};
+
+template<typename T>
+struct HasValueType {
+ typedef T value_type;
+};
+
+struct HasIdentityValueType {
+ typedef HasIdentityValueType value_type;
+};
+
+struct NoValueType { };
+
+int is_nested_value_type_identity0[
+ is_nested_value_type_identity<HasValueType<int> >::value? -1 : 1];
+int is_nested_value_type_identity1[
+ is_nested_value_type_identity<HasIdentityValueType>::value? 1 : -1];
+int is_nested_value_type_identity2[
+ is_nested_value_type_identity<NoValueType>::value? -1 : 1];
+
+
+// C++ [temp.class.spec]p4:
+template<class T1, class T2, int I> class A { }; //#1
+template<class T, int I> class A<T, T*, I> { }; //#2
+template<class T1, class T2, int I> class A<T1*, T2, I> { }; //#3
+template<class T> class A<int, T*, 5> { }; //#4
+template<class T1, class T2, int I> class A<T1, T2*, I> { }; //#5
+
+// Redefinition of class template partial specializations
+template<typename T, T N, typename U> class A0;
+
+template<typename T, T N> class A0<T, N, int> { }; // expected-note{{here}}
+template<typename T, T N> class A0<T, N, int>;
+template<typename T, T N> class A0<T, N, int> { }; // expected-error{{redef}}
+
+namespace PR6025 {
+ template< int N > struct A;
+
+ namespace N
+ {
+ template< typename F >
+ struct B;
+ }
+
+ template< typename Protect, typename Second >
+ struct C;
+
+ template <class T>
+ struct C< T, A< N::B<T>::value > >
+ {
+ };
+}
+
+namespace PR6181 {
+ template <class T>
+ class a;
+
+ class s;
+
+ template <class U>
+ class a<s> // expected-error{{partial specialization of 'a' does not use any of its template parameters}}
+ {
+ };
+
+}
diff --git a/clang/test/SemaTemplate/temp_class_spec_blocks.cpp b/clang/test/SemaTemplate/temp_class_spec_blocks.cpp
new file mode 100644
index 0000000..b7b96df
--- /dev/null
+++ b/clang/test/SemaTemplate/temp_class_spec_blocks.cpp
@@ -0,0 +1,34 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fblocks
+template<typename T>
+struct is_unary_block {
+ static const bool value = false;
+};
+
+template<typename T, typename U>
+struct is_unary_block<T (^)(U)> {
+ static const bool value = true;
+};
+
+int is_unary_block0[is_unary_block<int>::value ? -1 : 1];
+int is_unary_block1[is_unary_block<int (^)()>::value ? -1 : 1];
+int is_unary_block2[is_unary_block<int (^)(int, bool)>::value ? -1 : 1];
+int is_unary_block3[is_unary_block<int (^)(bool)>::value ? 1 : -1];
+int is_unary_block4[is_unary_block<int (^)(int)>::value ? 1 : -1];
+
+template<typename T>
+struct is_unary_block_with_same_return_type_as_argument_type {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_unary_block_with_same_return_type_as_argument_type<T (^)(T)> {
+ static const bool value = true;
+};
+
+int is_unary_block5[is_unary_block_with_same_return_type_as_argument_type<int>::value ? -1 : 1];
+int is_unary_block6[is_unary_block_with_same_return_type_as_argument_type<int (^)()>::value ? -1 : 1];
+int is_unary_block7[is_unary_block_with_same_return_type_as_argument_type<int (^)(int, bool)>::value ? -1 : 1];
+int is_unary_block8[is_unary_block_with_same_return_type_as_argument_type<int (^)(bool)>::value ? -1 : 1];
+int is_unary_block9[is_unary_block_with_same_return_type_as_argument_type<int (^)(int)>::value ? 1 : -1];
+int is_unary_block10[is_unary_block_with_same_return_type_as_argument_type<int (^)(int, ...)>::value ? -1 : 1];
+int is_unary_block11[is_unary_block_with_same_return_type_as_argument_type<int (^ const)(int)>::value ? -1 : 1];
diff --git a/clang/test/SemaTemplate/temp_class_spec_neg.cpp b/clang/test/SemaTemplate/temp_class_spec_neg.cpp
new file mode 100644
index 0000000..be5fbb1
--- /dev/null
+++ b/clang/test/SemaTemplate/temp_class_spec_neg.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T> struct vector;
+
+// C++ [temp.class.spec]p6:
+namespace N {
+ namespace M {
+ template<typename T> struct A; // expected-note{{here}}
+ }
+}
+
+template<typename T>
+struct N::M::A<T*> { }; // expected-warning{{C++11 extension}}
+
+// C++ [temp.class.spec]p9
+// bullet 1
+template <int I, int J> struct A {};
+template <int I> struct A<I+5, I*2> {}; // expected-error{{depends on}}
+template <int I, int J> struct B {};
+template <int I> struct B<I, I> {}; //OK
+
+// bullet 2
+template <class T, T t> struct C {}; // expected-note{{declared here}}
+template <class T> struct C<T, 1>; // expected-error{{specializes}}
+template <class T, T* t> struct C<T*, t>; // okay
+
+template< int X, int (*array_ptr)[X] > class A2 {}; // expected-note{{here}}
+int array[5];
+template< int X > class A2<X, &array> { }; // expected-error{{specializes}}
+
+template<typename T, int N, template<typename X> class TT>
+struct Test0;
+
+// bullet 3
+template<typename T, int N, template<typename X> class TT>
+struct Test0<T, N, TT>; // expected-error{{does not specialize}}
+
+// C++ [temp.class.spec]p10
+template<typename T = int, // expected-error{{default template argument}}
+ int N = 17, // expected-error{{default template argument}}
+ template<typename X> class TT = ::vector> // expected-error{{default template argument}}
+ struct Test0<T*, N, TT> { };
+
+template<typename T> struct Test1;
+template<typename T, typename U> // expected-note{{non-deducible}}
+ struct Test1<T*> { }; // expected-warning{{never be used}}
diff --git a/clang/test/SemaTemplate/temp_explicit.cpp b/clang/test/SemaTemplate/temp_explicit.cpp
new file mode 100644
index 0000000..80c90d0
--- /dev/null
+++ b/clang/test/SemaTemplate/temp_explicit.cpp
@@ -0,0 +1,151 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -pedantic -Wc++11-compat %s
+//
+// Tests explicit instantiation of templates.
+template<typename T, typename U = T> class X0 { };
+
+namespace N {
+ template<typename T, typename U = T> class X1 { };
+}
+
+// Check the syntax of explicit instantiations.
+template class X0<int, float>;
+template class X0<int>; // expected-note{{previous}}
+
+template class N::X1<int>;
+template class ::N::X1<int, float>;
+
+using namespace N;
+
+// Check for some bogus syntax that probably means that the user
+// wanted to write an explicit specialization, but forgot the '<>'
+// after 'template'.
+template class X0<double> { }; // expected-error{{explicit specialization}}
+
+// Check for explicit instantiations that come after other kinds of
+// instantiations or declarations.
+template class X0<int, int>; // expected-error{{duplicate}}
+
+template<> class X0<char> { }; // expected-note{{previous}}
+template class X0<char>; // expected-warning{{ignored}}
+
+void foo(X0<short>) { }
+template class X0<short>;
+
+// Check that explicit instantiations actually produce definitions. We
+// determine whether this happens by placing semantic errors in the
+// definition of the template we're instantiating.
+template<typename T> struct X2; // expected-note{{declared here}}
+
+template struct X2<float>; // expected-error{{undefined template}}
+
+template<typename T>
+struct X2 {
+ void f0(T*); // expected-error{{pointer to a reference}}
+};
+
+template struct X2<int>; // okay
+template struct X2<int&>; // expected-note{{in instantiation of}}
+
+// Check that explicit instantiations instantiate member classes.
+template<typename T> struct X3 {
+ struct Inner {
+ void f(T*); // expected-error{{pointer to a reference}}
+ };
+};
+
+void f1(X3<int&>); // okay, Inner, not instantiated
+
+template struct X3<int&>; // expected-note{{instantiation}}
+
+template<typename T> struct X4 {
+ struct Inner {
+ struct VeryInner {
+ void f(T*); // expected-error 2{{pointer to a reference}}
+ };
+ };
+};
+
+void f2(X4<int&>); // okay, Inner, not instantiated
+void f3(X4<int&>::Inner); // okay, Inner::VeryInner, not instantiated
+
+template struct X4<int&>; // expected-note{{instantiation}}
+template struct X4<float&>; // expected-note{{instantiation}}
+
+// Check explicit instantiation of member classes
+namespace N2 {
+
+template<typename T>
+struct X5 {
+ struct Inner1 {
+ void f(T&);
+ };
+
+ struct Inner2 { // expected-note {{here}}
+ struct VeryInner {
+ void g(T*); // expected-error 2{{pointer to a reference}}
+ };
+ };
+};
+
+}
+
+template struct N2::X5<void>::Inner2;
+
+using namespace N2;
+template struct X5<int&>::Inner2; // expected-note{{instantiation}}
+
+void f4(X5<float&>::Inner2);
+template struct X5<float&>::Inner2; // expected-note{{instantiation}}
+
+namespace N3 {
+ template struct N2::X5<int>::Inner2; // expected-warning {{explicit instantiation of 'Inner2' not in a namespace enclosing 'N2'}}
+}
+
+struct X6 {
+ struct Inner { // expected-note{{here}}
+ void f();
+ };
+};
+
+template struct X6::Inner; // expected-error{{non-templated}}
+
+// PR5559
+template <typename T>
+struct Foo;
+
+template <>
+struct Foo<int> // expected-note{{header not required for explicitly-specialized}}
+{
+ template <typename U>
+ struct Bar
+ {};
+};
+
+template <> // expected-warning{{extraneous template parameter list}}
+template <>
+struct Foo<int>::Bar<void>
+{};
+
+namespace N1 {
+
+ template<typename T> struct X7 { }; // expected-note{{here}}
+
+ namespace Inner {
+ template<typename T> struct X8 { };
+ }
+
+ template struct X7<int>;
+ template struct Inner::X8<int>;
+}
+
+template<typename T> struct X9 { }; // expected-note{{here}}
+
+template struct ::N1::Inner::X8<float>;
+
+namespace N2 {
+ using namespace N1;
+
+ template struct X7<double>; // expected-warning{{must occur in namespace}}
+
+ template struct X9<float>; // expected-warning{{must occur at global scope}}
+}
diff --git a/clang/test/SemaTemplate/temp_explicit_cxx0x.cpp b/clang/test/SemaTemplate/temp_explicit_cxx0x.cpp
new file mode 100644
index 0000000..e37fcd7
--- /dev/null
+++ b/clang/test/SemaTemplate/temp_explicit_cxx0x.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 -verify %s
+namespace N1 {
+
+ template<typename T> struct X0 { }; // expected-note{{here}}
+
+ namespace Inner {
+ template<typename T> struct X1 { };
+ }
+
+ template struct X0<int>;
+ template struct Inner::X1<int>;
+}
+
+template<typename T> struct X2 { }; // expected-note{{here}}
+
+template struct ::N1::Inner::X1<float>;
+
+namespace N2 {
+ using namespace N1;
+
+ template struct X0<double>; // expected-error{{must occur in namespace 'N1'}}
+
+ template struct X2<float>; // expected-error{{at global scope}}
+}
diff --git a/clang/test/SemaTemplate/temp_func_order.cpp b/clang/test/SemaTemplate/temp_func_order.cpp
new file mode 100644
index 0000000..908354b
--- /dev/null
+++ b/clang/test/SemaTemplate/temp_func_order.cpp
@@ -0,0 +1,95 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T>
+int &f0(T);
+
+template<typename T>
+float &f0(T*);
+
+void test_f0(int i, int *ip) {
+ int &ir = f0(i);
+ float &fr = f0(ip);
+}
+
+template<typename T, typename U>
+int &f1(T, U);
+
+template<typename T>
+float &f1(T, T);
+
+void test_f1(int i, float f) {
+ int &ir = f1(i, f);
+ float &fr1 = f1(i, i);
+ float &fr2 = f1(f, f);
+}
+
+template<typename T, typename U>
+struct A { };
+
+template<typename T>
+int &f2(T);
+
+template<typename T, typename U>
+float &f2(A<T, U>);
+
+template<typename T>
+double &f2(A<T, T>);
+
+void test_f2(int i, A<int, float> aif, A<int, int> aii) {
+ int &ir = f2(i);
+ float &fr = f2(aif);
+ double &dr = f2(aii);
+}
+
+template<typename T, typename U>
+int &f3(T*, U); // expected-note{{candidate}}
+
+template<typename T, typename U>
+float &f3(T, U*); // expected-note{{candidate}}
+
+void test_f3(int i, int *ip, float *fp) {
+ int &ir = f3(ip, i);
+ float &fr = f3(i, fp);
+ f3(ip, ip); // expected-error{{ambiguous}}
+}
+
+template<typename T>
+int &f4(T&);
+
+template<typename T>
+float &f4(const T&);
+
+void test_f4(int i, const int ic) {
+ int &ir1 = f4(i);
+ float &fr1 = f4(ic);
+}
+
+template<typename T, typename U>
+int &f5(T&, const U&); // expected-note{{candidate}}
+
+template<typename T, typename U>
+float &f5(const T&, U&); // expected-note{{candidate}}
+
+void test_f5(int i, const int ic) {
+ f5(i, i); // expected-error{{ambiguous}}
+}
+
+template<typename T, typename U>
+int &f6(T&, U&);
+
+template<typename T, typename U>
+float &f6(const T&, U&);
+
+void test_f6(int i, const int ic) {
+ int &ir = f6(i, i);
+ float &fr = f6(ic, ic);
+}
+
+struct CrazyFun {
+ template<typename T, typename U> operator A<T, U>();
+ template<typename T> operator A<T, T>();
+};
+
+void fun(CrazyFun cf) {
+ A<int, float> aif = cf;
+ A<int, int> aii = cf;
+}
diff --git a/clang/test/SemaTemplate/template-class-traits.cpp b/clang/test/SemaTemplate/template-class-traits.cpp
new file mode 100644
index 0000000..4710294
--- /dev/null
+++ b/clang/test/SemaTemplate/template-class-traits.cpp
@@ -0,0 +1,8 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+#define T(b) (b) ? 1 : -1
+#define F(b) (b) ? -1 : 1
+
+struct HasVirt { virtual void a(); };
+template<class T> struct InheritPolymorph : HasVirt {};
+int t01[T(__is_polymorphic(InheritPolymorph<int>))];
+
diff --git a/clang/test/SemaTemplate/template-decl-fail.cpp b/clang/test/SemaTemplate/template-decl-fail.cpp
new file mode 100644
index 0000000..ad134cd
--- /dev/null
+++ b/clang/test/SemaTemplate/template-decl-fail.cpp
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T> typedef T X; // expected-error{{typedef cannot be a template}}
+
+template<typename T>
+enum t0 { A = T::x }; // expected-error{{enumeration cannot be a template}} \
+ // expected-warning{{declaration does not declare anything}}
+
+enum e0 {};
+template<int x> enum e0 f0(int a=x) {}
diff --git a/clang/test/SemaTemplate/template-id-expr.cpp b/clang/test/SemaTemplate/template-id-expr.cpp
new file mode 100644
index 0000000..4416f92
--- /dev/null
+++ b/clang/test/SemaTemplate/template-id-expr.cpp
@@ -0,0 +1,98 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+// PR5336
+template<typename FromCl>
+struct isa_impl_cl {
+ template<class ToCl>
+ static void isa(const FromCl &Val) { }
+};
+
+template<class X, class Y>
+void isa(const Y &Val) { return isa_impl_cl<Y>::template isa<X>(Val); }
+
+class Value;
+void f0(const Value &Val) { isa<Value>(Val); }
+
+// Implicit template-ids.
+template<typename T>
+struct X0 {
+ template<typename U>
+ void f1();
+
+ template<typename U>
+ void f2(U) {
+ f1<U>();
+ }
+};
+
+void test_X0_int(X0<int> xi, float f) {
+ xi.f2(f);
+}
+
+// Not template-id expressions, but they almost look like it.
+template<typename F>
+struct Y {
+ Y(const F&);
+};
+
+template<int I>
+struct X {
+ X(int, int);
+ void f() {
+ Y<X<I> >(X<I>(0, 0));
+ Y<X<I> >(::X<I>(0, 0));
+ }
+};
+
+template struct X<3>;
+
+// 'template' as a disambiguator.
+// PR7030
+struct Y0 {
+ template<typename U>
+ void f1(U);
+
+ template<typename U>
+ static void f2(U);
+
+ void f3(int);
+
+ static int f4(int);
+ template<typename U>
+ static void f4(U);
+
+ template<typename U>
+ void f() {
+ Y0::template f1<U>(0);
+ Y0::template f1(0);
+ this->template f1(0);
+
+ Y0::template f2<U>(0);
+ Y0::template f2(0);
+
+ Y0::template f3(0); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
+ Y0::template f3(); // expected-error {{'f3' following the 'template' keyword does not refer to a template}}
+
+ int x;
+ x = Y0::f4(0);
+ x = Y0::f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+ x = Y0::template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+
+ x = this->f4(0);
+ x = this->f4<int>(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+ x = this->template f4(0); // expected-error {{assigning to 'int' from incompatible type 'void'}}
+ }
+};
+
+struct A {
+ template<int I>
+ struct B {
+ static void b1();
+ };
+};
+
+template<int I>
+void f5() {
+ A::template B<I>::template b1(); // expected-error {{'b1' following the 'template' keyword does not refer to a template}}
+}
+
+template void f5<0>(); // expected-note {{in instantiation of function template specialization 'f5<0>' requested here}}
diff --git a/clang/test/SemaTemplate/template-id-printing.cpp b/clang/test/SemaTemplate/template-id-printing.cpp
new file mode 100644
index 0000000..047589b
--- /dev/null
+++ b/clang/test/SemaTemplate/template-id-printing.cpp
@@ -0,0 +1,141 @@
+// RUN: %clang_cc1 -fsyntax-only -ast-print %s | FileCheck %s
+namespace N {
+ template<typename T, typename U> void f(U);
+ template<int> void f();
+}
+
+void g() {
+ // CHECK: N::f<int>(3.14
+ N::f<int>(3.14);
+
+ // CHECK: N::f<double>
+ void (*fp)(int) = N::f<double>;
+}
+
+
+// (NNS qualified) DeclRefExpr.
+namespace DRE {
+
+template <typename T>
+void foo();
+
+void test() {
+ // CHECK: DRE::foo<int>;
+ DRE::foo<int>;
+ // CHECK: DRE::template foo<int>;
+ DRE::template foo<int>;
+ // CHECK: DRE::foo<int>();
+ DRE::foo<int>();
+ // CHECK: DRE::template foo<int>();
+ DRE::template foo<int>();
+}
+
+} // namespace DRE
+
+
+// MemberExpr.
+namespace ME {
+
+struct S {
+ template <typename T>
+ void mem();
+};
+
+void test() {
+ S s;
+ // CHECK: s.mem<int>();
+ s.mem<int>();
+ // CHECK: s.template mem<int>();
+ s.template mem<int>();
+}
+
+} // namespace ME
+
+
+// UnresolvedLookupExpr.
+namespace ULE {
+
+template <typename T>
+int foo();
+
+template <typename T>
+void test() {
+ // CHECK: ULE::foo<T>;
+ ULE::foo<T>;
+ // CHECK: ULE::template foo<T>;
+ ULE::template foo<T>;
+}
+
+} // namespace ULE
+
+
+// UnresolvedMemberExpr.
+namespace UME {
+
+struct S {
+ template <typename T>
+ void mem();
+};
+
+template <typename U>
+void test() {
+ S s;
+ // CHECK: s.mem<U>();
+ s.mem<U>();
+ // CHECK: s.template mem<U>();
+ s.template mem<U>();
+}
+
+} // namespace UME
+
+
+// DependentScopeDeclRefExpr.
+namespace DSDRE {
+
+template <typename T>
+struct S;
+
+template <typename T>
+void test() {
+ // CHECK: S<T>::foo;
+ S<T>::foo;
+ // CHECK: S<T>::template foo;
+ S<T>::template foo;
+ // CHECK: S<T>::template foo<>;
+ S<T>::template foo<>;
+ // CHECK: S<T>::template foo<T>;
+ S<T>::template foo<T>;
+}
+
+} // namespace DSDRE
+
+
+// DependentScopeMemberExpr.
+namespace DSME {
+
+template <typename T>
+struct S;
+
+template <typename T>
+void test() {
+ S<T> s;
+ // CHECK: s.foo;
+ s.foo;
+ // CHECK: s.template foo;
+ s.template foo;
+ // CHECK: s.template foo<>;
+ s.template foo<>;
+ // CHECK: s.template foo<T>;
+ s.template foo<T>;
+}
+
+} // namespace DSME
+
+namespace DSDRE_withImplicitTemplateArgs {
+
+template <typename T> void foo() {
+ // CHECK: T::template bar();
+ T::template bar();
+}
+
+} // namespace DSDRE_withImplicitTemplateArgs
diff --git a/clang/test/SemaTemplate/typename-specifier-2.cpp b/clang/test/SemaTemplate/typename-specifier-2.cpp
new file mode 100644
index 0000000..551cac3
--- /dev/null
+++ b/clang/test/SemaTemplate/typename-specifier-2.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename MetaFun, typename T>
+struct bind_metafun {
+ typedef typename MetaFun::template apply<T> type;
+};
+
+struct add_pointer {
+ template<typename T>
+ struct apply {
+ typedef T* type;
+ };
+};
+
+int i;
+// FIXME: if we make the declarator below a pointer (e.g., with *ip),
+// the error message isn't so good because we don't get the handy
+// 'aka' telling us that we're dealing with an int**. Should we fix
+// getDesugaredType to dig through pointers and such?
+bind_metafun<add_pointer, int>::type::type ip = &i;
+bind_metafun<add_pointer, float>::type::type fp = &i; // expected-error{{cannot initialize a variable of type 'bind_metafun<add_pointer, float>::type::type' (aka 'float *') with an rvalue of type 'int *'}}
+
+
+template<typename T>
+struct extract_type_type {
+ typedef typename T::type::type t;
+};
+
+double d;
+extract_type_type<bind_metafun<add_pointer, double> >::t dp = &d;
diff --git a/clang/test/SemaTemplate/typename-specifier-3.cpp b/clang/test/SemaTemplate/typename-specifier-3.cpp
new file mode 100644
index 0000000..a463d88
--- /dev/null
+++ b/clang/test/SemaTemplate/typename-specifier-3.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+// PR4364
+template<class T> struct a {
+ T b() {
+ return typename T::x();
+ }
+};
+struct B {
+ typedef B x;
+};
+B c() {
+ a<B> x;
+ return x.b();
+}
+
+// Some extra tests for invalid cases
+template<class T> struct test2 { T b() { return typename T::a; } }; // expected-error{{expected '(' for function-style cast or type construction}}
+template<class T> struct test3 { T b() { return typename a; } }; // expected-error{{expected a qualified name after 'typename'}}
diff --git a/clang/test/SemaTemplate/typename-specifier-4.cpp b/clang/test/SemaTemplate/typename-specifier-4.cpp
new file mode 100644
index 0000000..44cf966
--- /dev/null
+++ b/clang/test/SemaTemplate/typename-specifier-4.cpp
@@ -0,0 +1,164 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+template<typename T, typename U>
+struct is_same {
+ static const bool value = false;
+};
+
+template<typename T>
+struct is_same<T, T> {
+ static const bool value = true;
+};
+
+template<typename MetaFun, typename T1, typename T2>
+struct metafun_apply2 {
+ typedef typename MetaFun::template apply<T1, T2> inner;
+ typedef typename inner::type type;
+};
+
+template<typename T, typename U> struct pair;
+
+struct make_pair {
+ template<typename T1, typename T2>
+ struct apply {
+ typedef pair<T1, T2> type;
+ };
+};
+
+int a0[is_same<metafun_apply2<make_pair, int, float>::type,
+ pair<int, float> >::value? 1 : -1];
+int a1[is_same<
+ typename make_pair::template apply<int, float>, // expected-warning{{'template' keyword outside of a template}} \
+ // expected-warning{{'typename' occurs outside of a template}}
+ make_pair::apply<int, float>
+ >::value? 1 : -1];
+
+template<typename MetaFun>
+struct swap_and_apply2 {
+ template<typename T1, typename T2>
+ struct apply {
+ typedef typename MetaFun::template apply<T2, T1> new_metafun;
+ typedef typename new_metafun::type type;
+ };
+};
+
+int a2[is_same<swap_and_apply2<make_pair>::apply<int, float>::type,
+ pair<float, int> >::value? 1 : -1];
+
+template<typename MetaFun>
+struct swap_and_apply2b {
+ template<typename T1, typename T2>
+ struct apply {
+ typedef typename MetaFun::template apply<T2, T1>::type type;
+ };
+};
+
+int a3[is_same<swap_and_apply2b<make_pair>::apply<int, float>::type,
+ pair<float, int> >::value? 1 : -1];
+
+template<typename T>
+struct X0 {
+ template<typename U, typename V>
+ struct Inner;
+
+ void f0(X0<T>::Inner<T*, T&>); // expected-note{{here}}
+ void f0(typename X0<T>::Inner<T*, T&>); // expected-error{{redecl}}
+
+ void f1(X0<T>::Inner<T*, T&>); // expected-note{{here}}
+ void f1(typename X0<T>::template Inner<T*, T&>); // expected-error{{redecl}}
+
+ void f2(typename X0<T>::Inner<T*, T&>::type); // expected-note{{here}}
+ void f2(typename X0<T>::template Inner<T*, T&>::type); // expected-error{{redecl}}
+};
+
+namespace PR6236 {
+ template<typename T, typename U> struct S { };
+
+ template<typename T> struct S<T, T> {
+ template<typename U> struct K { };
+
+ void f() {
+ typedef typename S<T, T>::template K<T> Foo;
+ }
+ };
+}
+
+namespace PR6268 {
+ template <typename T>
+ struct Outer {
+ template <typename U>
+ struct Inner {};
+
+ template <typename U>
+ typename Outer<T>::template Inner<U>
+ foo(typename Outer<T>::template Inner<U>);
+ };
+
+ template <typename T>
+ template <typename U>
+ typename Outer<T>::template Inner<U>
+ Outer<T>::foo(typename Outer<T>::template Inner<U>) {
+ return Inner<U>();
+ }
+}
+
+namespace PR6463 {
+ struct B { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
+ struct C { typedef int type; }; // expected-note 2{{member found by ambiguous name lookup}}
+
+ template<typename T>
+ struct A : B, C {
+ type& a(); // expected-error{{found in multiple base classes}}
+ int x;
+ };
+
+ // FIXME: Improve source location info here.
+ template<typename T>
+ typename A<T>::type& A<T>::a() { // expected-error{{found in multiple base classes}}
+ return x;
+ }
+}
+
+namespace PR7419 {
+ template <typename T> struct S {
+ typedef typename T::Y T2;
+ typedef typename T2::Z T3;
+ typedef typename T3::W T4;
+ T4 *f();
+
+ typedef typename T::template Y<int> TT2;
+ typedef typename TT2::template Z<float> TT3;
+ typedef typename TT3::template W<double> TT4;
+ TT4 g();
+ };
+
+ template <typename T> typename T::Y::Z::W *S<T>::f() { }
+ template <typename T> typename T::template Y<int>::template Z<float>::template W<double> S<T>::g() { }
+}
+
+namespace rdar8740998 {
+ template<typename T>
+ struct X : public T {
+ using T::iterator; // expected-note{{add 'typename' to treat this using declaration as a type}} \
+ // expected-error{{dependent using declaration resolved to type without 'typename'}}
+
+ void f() {
+ typename X<T>::iterator i; // expected-error{{typename specifier refers to a dependent using declaration for a value 'iterator' in 'X<T>'}}
+ }
+ };
+
+ struct HasIterator {
+ typedef int *iterator; // expected-note{{target of using declaration}}
+ };
+
+ void test_X(X<HasIterator> xi) { // expected-note{{in instantiation of template class}}
+ xi.f();
+ }
+}
+
+namespace rdar9068589 {
+ // From GCC PR c++/13950
+ template <class T> struct Base {};
+ template <class T> struct Derived: public Base<T> {
+ typename Derived::template Base<double>* p1;
+ };
+}
diff --git a/clang/test/SemaTemplate/typename-specifier.cpp b/clang/test/SemaTemplate/typename-specifier.cpp
new file mode 100644
index 0000000..9eb4f33
--- /dev/null
+++ b/clang/test/SemaTemplate/typename-specifier.cpp
@@ -0,0 +1,117 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+namespace N {
+ struct A {
+ typedef int type;
+ };
+
+ struct B {
+ };
+
+ struct C {
+ struct type { };
+ int type; // expected-note 2{{referenced member 'type' is declared here}}
+ };
+}
+
+int i;
+
+typename N::A::type *ip1 = &i; // expected-warning{{'typename' occurs outside of a template}}
+typename N::B::type *ip2 = &i; // expected-error{{no type named 'type' in 'N::B'}} \
+// expected-warning{{'typename' occurs outside of a template}}
+typename N::C::type *ip3 = &i; // expected-error{{typename specifier refers to non-type member 'type'}} \
+// expected-warning{{'typename' occurs outside of a template}}
+
+void test(double d) {
+ typename N::A::type f(typename N::A::type(a)); // expected-warning{{parentheses were disambiguated as a function declarator}} \
+ // expected-warning 2{{'typename' occurs outside of a template}}
+ int five = f(5);
+
+ using namespace N;
+ for (typename A::type i = 0; i < 10; ++i) // expected-warning{{'typename' occurs outside of a template}}
+ five += 1;
+
+ const typename N::A::type f2(d); // expected-warning{{'typename' occurs outside of a template}}
+}
+
+namespace N {
+ template<typename T>
+ struct X {
+ typedef typename T::type type; // expected-error {{no type named 'type' in 'N::B'}} \
+ // expected-error {{no type named 'type' in 'B'}} \
+ // FIXME: location info for error above isn't very good \
+ // expected-error 2{{typename specifier refers to non-type member 'type'}} \
+ // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
+ };
+}
+
+N::X<N::A>::type *ip4 = &i;
+N::X<N::B>::type *ip5 = &i; // expected-note{{in instantiation of template class 'N::X<N::B>' requested here}}
+N::X<N::C>::type *ip6 = &i; // expected-note{{in instantiation of template class 'N::X<N::C>' requested here}}
+
+N::X<int>::type fail1; // expected-note{{in instantiation of template class 'N::X<int>' requested here}}
+
+template<typename T>
+struct Y {
+ typedef typename N::X<T>::type *type; // expected-note{{in instantiation of template class 'N::X<B>' requested here}} \
+ // expected-note{{in instantiation of template class 'N::X<C>' requested here}}
+};
+
+struct A {
+ typedef int type;
+};
+
+struct B {
+};
+
+struct C {
+ struct type { };
+ int type; // expected-note{{referenced member 'type' is declared here}}
+};
+
+::Y<A>::type ip7 = &i;
+::Y<B>::type ip8 = &i; // expected-note{{in instantiation of template class 'Y<B>' requested here}}
+::Y<C>::type ip9 = &i; // expected-note{{in instantiation of template class 'Y<C>' requested here}}
+
+template<typename T> struct D {
+ typedef typename T::foo foo; // expected-error {{type 'long' cannot be used prior to '::' because it has no members}}
+ typedef typename foo::bar bar;
+};
+
+D<long> struct_D; // expected-note {{in instantiation of template class 'D<long>' requested here}}
+
+template<typename T> struct E {
+ typedef typename T::foo foo;
+ typedef typename foo::bar bar; // expected-error {{type 'foo' (aka 'double') cannot be used prior to '::' because it has no members}}
+};
+
+struct F {
+ typedef double foo;
+};
+
+E<F> struct_E; // expected-note {{in instantiation of template class 'E<F>' requested here}}
+
+template<typename T> struct G {
+ typedef typename T::foo foo;
+ typedef typename foo::bar bar;
+};
+
+struct H {
+ struct foo {
+ typedef double bar;
+ };
+};
+
+G<H> struct_G;
+
+namespace PR10925 {
+ template< int mydim, typename Traits >
+ class BasicGeometry
+ {
+ typedef int some_type_t;
+ };
+
+ template<class ctype, int mydim, int coorddim>
+ class MockGeometry : BasicGeometry<mydim, int>{
+ using typename BasicGeometry<mydim, int>::operator[]; // expected-error {{typename is allowed for identifiers only}}
+ };
+}
diff --git a/clang/test/SemaTemplate/typo-dependent-name.cpp b/clang/test/SemaTemplate/typo-dependent-name.cpp
new file mode 100644
index 0000000..96554e9
--- /dev/null
+++ b/clang/test/SemaTemplate/typo-dependent-name.cpp
@@ -0,0 +1,17 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+template<typename T>
+struct Base {
+ T inner;
+};
+
+template<typename T>
+struct X {
+ template<typename U>
+ struct Inner {
+ };
+
+ bool f(T other) {
+ return this->inner < other;
+ }
+};
diff --git a/clang/test/SemaTemplate/unresolved-construct.cpp b/clang/test/SemaTemplate/unresolved-construct.cpp
new file mode 100644
index 0000000..bb9ed8e
--- /dev/null
+++ b/clang/test/SemaTemplate/unresolved-construct.cpp
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+class A
+{
+public:
+ A() {}
+
+ template <class _F>
+ explicit A(_F&& __f);
+
+ A(A&&) {}
+ A& operator=(A&&) {return *this;}
+};
+
+template <class T>
+void f(T t)
+{
+ A a;
+ a = f(t);
+}
diff --git a/clang/test/SemaTemplate/unused-variables.cpp b/clang/test/SemaTemplate/unused-variables.cpp
new file mode 100644
index 0000000..1b9350b
--- /dev/null
+++ b/clang/test/SemaTemplate/unused-variables.cpp
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -fsyntax-only -Wunused -verify %s
+
+struct X0 {
+ ~X0();
+};
+
+struct X1 { };
+
+template<typename T>
+void f() {
+ X0 x0;
+ X1 x1; // expected-warning{{unused variable 'x1'}}
+}
+
+template<typename T, typename U>
+void g() {
+ T t;
+ U u; // expected-warning{{unused variable 'u'}}
+}
+
+template void g<X0, X1>(); // expected-note{{in instantiation of}}
diff --git a/clang/test/SemaTemplate/value-dependent-null-pointer-constant.cpp b/clang/test/SemaTemplate/value-dependent-null-pointer-constant.cpp
new file mode 100644
index 0000000..223500e
--- /dev/null
+++ b/clang/test/SemaTemplate/value-dependent-null-pointer-constant.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang_cc1 -fsyntax-only %s
+
+template<typename T, int N>
+struct X0 {
+ const char *f0(bool Cond) {
+ return Cond? "honk" : N;
+ }
+
+ const char *f1(bool Cond) {
+ return Cond? N : "honk";
+ }
+
+ bool f2(const char *str) {
+ return str == N;
+ }
+};
+
+// PR4996
+template<unsigned I> int f0() {
+ return __builtin_choose_expr(I, 0, 1);
+}
+
+// PR5041
+struct A { };
+
+template <typename T> void f(T *t)
+{
+ (void)static_cast<void*>(static_cast<A*>(t));
+}
diff --git a/clang/test/SemaTemplate/virtual-member-functions.cpp b/clang/test/SemaTemplate/virtual-member-functions.cpp
new file mode 100644
index 0000000..974f664
--- /dev/null
+++ b/clang/test/SemaTemplate/virtual-member-functions.cpp
@@ -0,0 +1,86 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s
+
+namespace PR5557 {
+template <class T> struct A {
+ A();
+ virtual void anchor();
+ virtual int a(T x);
+};
+template<class T> A<T>::A() {}
+template<class T> void A<T>::anchor() { }
+
+template<class T> int A<T>::a(T x) {
+ return *x; // expected-error{{requires pointer operand}}
+}
+
+void f(A<int> x) {
+ x.anchor(); // expected-note{{instantiation}}
+}
+
+template<typename T>
+struct X {
+ virtual void f();
+};
+
+template<>
+void X<int>::f() { }
+}
+
+template<typename T>
+struct Base {
+ virtual ~Base() {
+ int *ptr = 0;
+ T t = ptr; // expected-error{{cannot initialize}}
+ }
+};
+
+template<typename T>
+struct Derived : Base<T> {
+ virtual void foo() { }
+};
+
+template struct Derived<int>; // expected-note {{in instantiation of member function 'Base<int>::~Base' requested here}}
+
+template<typename T>
+struct HasOutOfLineKey {
+ HasOutOfLineKey() { }
+ virtual T *f(float *fp);
+};
+
+template<typename T>
+T *HasOutOfLineKey<T>::f(float *fp) {
+ return fp; // expected-error{{cannot initialize return object of type 'int *' with an lvalue of type 'float *'}}
+}
+
+HasOutOfLineKey<int> out_of_line; // expected-note{{in instantiation of member function 'HasOutOfLineKey<int>::f' requested here}}
+
+namespace std {
+ class type_info;
+}
+
+namespace PR7114 {
+ class A { virtual ~A(); }; // expected-note{{declared private here}}
+
+ template<typename T>
+ class B {
+ public:
+ class Inner : public A { }; // expected-error{{base class 'PR7114::A' has private destructor}}
+ static Inner i;
+ static const unsigned value = sizeof(i) == 4;
+ };
+
+ int f() { return B<int>::value; }
+
+ void test_typeid(B<float>::Inner bfi) {
+ (void)typeid(bfi); // expected-note{{implicit default destructor}}
+ }
+
+ template<typename T>
+ struct X : A {
+ void f() { }
+ };
+
+ void test_X(X<int> xi, X<float> xf) {
+ xi.f();
+ }
+}