From 222e2a7620e6520ffaf4fc4e69d79c18da31542e Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Mon, 24 Sep 2012 09:58:17 +1000 Subject: Add the clang library to the repo (with some of my changes, too). --- clang/test/SemaTemplate/ackermann.cpp | 38 +++ clang/test/SemaTemplate/address-spaces.cpp | 86 +++++ clang/test/SemaTemplate/alias-church-numerals.cpp | 34 ++ clang/test/SemaTemplate/alias-nested-nontag.cpp | 6 + .../SemaTemplate/alias-template-template-param.cpp | 7 + clang/test/SemaTemplate/alias-templates.cpp | 102 ++++++ clang/test/SemaTemplate/ambiguous-ovl-print.cpp | 9 + clang/test/SemaTemplate/anonymous-union.cpp | 40 +++ clang/test/SemaTemplate/array-to-pointer-decay.cpp | 25 ++ clang/test/SemaTemplate/atomics.cpp | 16 + clang/test/SemaTemplate/attributes.cpp | 34 ++ clang/test/SemaTemplate/canonical-expr-type-0x.cpp | 25 ++ clang/test/SemaTemplate/canonical-expr-type.cpp | 53 +++ .../class-template-ctor-initializer.cpp | 55 ++++ clang/test/SemaTemplate/class-template-decl.cpp | 97 ++++++ clang/test/SemaTemplate/class-template-id-2.cpp | 24 ++ clang/test/SemaTemplate/class-template-id.cpp | 47 +++ clang/test/SemaTemplate/class-template-spec.cpp | 121 +++++++ clang/test/SemaTemplate/constexpr-instantiate.cpp | 77 +++++ clang/test/SemaTemplate/constructor-template.cpp | 128 ++++++++ clang/test/SemaTemplate/copy-ctor-assign.cpp | 52 +++ clang/test/SemaTemplate/crash-10438657.cpp | 15 + clang/test/SemaTemplate/crash-8204126.cpp | 6 + clang/test/SemaTemplate/current-instantiation.cpp | 237 ++++++++++++++ clang/test/SemaTemplate/deduction-crash.cpp | 89 +++++ clang/test/SemaTemplate/deduction.cpp | 164 ++++++++++ .../test/SemaTemplate/default-arguments-cxx0x.cpp | 26 ++ clang/test/SemaTemplate/default-arguments.cpp | 138 ++++++++ .../test/SemaTemplate/default-expr-arguments-2.cpp | 19 ++ clang/test/SemaTemplate/default-expr-arguments.cpp | 305 +++++++++++++++++ .../test/SemaTemplate/delegating-constructors.cpp | 31 ++ clang/test/SemaTemplate/dependent-base-classes.cpp | 137 ++++++++ .../SemaTemplate/dependent-base-member-init.cpp | 68 ++++ .../dependent-class-member-operator.cpp | 11 + clang/test/SemaTemplate/dependent-expr.cpp | 73 +++++ clang/test/SemaTemplate/dependent-names-no-std.cpp | 21 ++ clang/test/SemaTemplate/dependent-names.cpp | 326 ++++++++++++++++++ clang/test/SemaTemplate/dependent-sized_array.cpp | 17 + .../SemaTemplate/dependent-template-recover.cpp | 60 ++++ .../test/SemaTemplate/dependent-type-identity.cpp | 100 ++++++ clang/test/SemaTemplate/destructor-template.cpp | 59 ++++ .../SemaTemplate/elaborated-type-specifier.cpp | 40 +++ clang/test/SemaTemplate/enum-argument.cpp | 36 ++ clang/test/SemaTemplate/enum-forward.cpp | 8 + clang/test/SemaTemplate/example-dynarray.cpp | 177 ++++++++++ clang/test/SemaTemplate/example-typelist.cpp | 98 ++++++ clang/test/SemaTemplate/explicit-instantiation.cpp | 107 ++++++ .../explicit-specialization-member.cpp | 21 ++ clang/test/SemaTemplate/ext-vector-type.cpp | 94 ++++++ clang/test/SemaTemplate/extern-templates.cpp | 64 ++++ clang/test/SemaTemplate/fibonacci.cpp | 66 ++++ clang/test/SemaTemplate/friend-template.cpp | 245 ++++++++++++++ clang/test/SemaTemplate/friend.cpp | 33 ++ clang/test/SemaTemplate/fun-template-def.cpp | 48 +++ .../function-template-specialization.cpp | 48 +++ .../test/SemaTemplate/implicit-instantiation-1.cpp | 25 ++ .../SemaTemplate/inject-templated-friend-post.cpp | 72 ++++ .../test/SemaTemplate/inject-templated-friend.cpp | 48 +++ clang/test/SemaTemplate/injected-class-name.cpp | 62 ++++ .../SemaTemplate/instantiate-anonymous-union.cpp | 89 +++++ clang/test/SemaTemplate/instantiate-array.cpp | 28 ++ clang/test/SemaTemplate/instantiate-attr.cpp | 26 ++ clang/test/SemaTemplate/instantiate-c99.cpp | 81 +++++ clang/test/SemaTemplate/instantiate-call.cpp | 51 +++ clang/test/SemaTemplate/instantiate-case.cpp | 21 ++ clang/test/SemaTemplate/instantiate-cast.cpp | 117 +++++++ clang/test/SemaTemplate/instantiate-clang.cpp | 35 ++ clang/test/SemaTemplate/instantiate-complete.cpp | 146 +++++++++ clang/test/SemaTemplate/instantiate-decl-dtor.cpp | 11 + clang/test/SemaTemplate/instantiate-decl-init.cpp | 46 +++ .../test/SemaTemplate/instantiate-declref-ice.cpp | 34 ++ clang/test/SemaTemplate/instantiate-declref.cpp | 117 +++++++ clang/test/SemaTemplate/instantiate-deeply.cpp | 36 ++ .../instantiate-default-assignment-operator.cpp | 17 + .../instantiate-dependent-nested-name.cpp | 7 + .../instantiate-elab-type-specifier.cpp | 13 + clang/test/SemaTemplate/instantiate-enum-2.cpp | 9 + clang/test/SemaTemplate/instantiate-enum.cpp | 27 ++ .../instantiate-exception-spec-cxx11.cpp | 133 ++++++++ .../SemaTemplate/instantiate-exception-spec.cpp | 11 + clang/test/SemaTemplate/instantiate-expr-1.cpp | 192 +++++++++++ clang/test/SemaTemplate/instantiate-expr-2.cpp | 245 ++++++++++++++ clang/test/SemaTemplate/instantiate-expr-3.cpp | 119 +++++++ clang/test/SemaTemplate/instantiate-expr-4.cpp | 354 ++++++++++++++++++++ clang/test/SemaTemplate/instantiate-expr-5.cpp | 38 +++ clang/test/SemaTemplate/instantiate-expr-basic.cpp | 17 + clang/test/SemaTemplate/instantiate-field.cpp | 104 ++++++ .../test/SemaTemplate/instantiate-friend-class.cpp | 9 + clang/test/SemaTemplate/instantiate-function-1.cpp | 249 ++++++++++++++ clang/test/SemaTemplate/instantiate-function-1.mm | 17 + clang/test/SemaTemplate/instantiate-function-2.cpp | 66 ++++ .../SemaTemplate/instantiate-function-params.cpp | 90 +++++ clang/test/SemaTemplate/instantiate-init.cpp | 109 +++++++ clang/test/SemaTemplate/instantiate-invalid.cpp | 52 +++ .../test/SemaTemplate/instantiate-local-class.cpp | 67 ++++ .../test/SemaTemplate/instantiate-member-class.cpp | 142 ++++++++ .../test/SemaTemplate/instantiate-member-expr.cpp | 68 ++++ .../instantiate-member-initializers.cpp | 27 ++ .../SemaTemplate/instantiate-member-pointers.cpp | 67 ++++ .../SemaTemplate/instantiate-member-template.cpp | 261 +++++++++++++++ clang/test/SemaTemplate/instantiate-method.cpp | 177 ++++++++++ .../instantiate-non-dependent-types.cpp | 14 + .../instantiate-non-type-template-parameter.cpp | 55 ++++ clang/test/SemaTemplate/instantiate-objc-1.mm | 48 +++ .../instantiate-overload-candidates.cpp | 21 ++ .../SemaTemplate/instantiate-overloaded-arrow.cpp | 20 ++ clang/test/SemaTemplate/instantiate-self.cpp | 89 +++++ clang/test/SemaTemplate/instantiate-sizeof.cpp | 10 + clang/test/SemaTemplate/instantiate-static-var.cpp | 116 +++++++ clang/test/SemaTemplate/instantiate-subscript.cpp | 41 +++ .../instantiate-template-template-parm.cpp | 97 ++++++ clang/test/SemaTemplate/instantiate-try-catch.cpp | 31 ++ clang/test/SemaTemplate/instantiate-type.cpp | 17 + clang/test/SemaTemplate/instantiate-typedef.cpp | 15 + clang/test/SemaTemplate/instantiate-typeof.cpp | 10 + clang/test/SemaTemplate/instantiate-using-decl.cpp | 82 +++++ .../test/SemaTemplate/instantiation-backtrace.cpp | 32 ++ .../test/SemaTemplate/instantiation-default-1.cpp | 102 ++++++ .../test/SemaTemplate/instantiation-default-2.cpp | 18 + .../test/SemaTemplate/instantiation-default-3.cpp | 21 ++ clang/test/SemaTemplate/instantiation-depth.cpp | 13 + clang/test/SemaTemplate/instantiation-order.cpp | 15 + clang/test/SemaTemplate/issue150.cpp | 107 ++++++ clang/test/SemaTemplate/lookup-dependent-bases.cpp | 19 ++ clang/test/SemaTemplate/member-access-ambig.cpp | 45 +++ clang/test/SemaTemplate/member-access-expr.cpp | 149 +++++++++ .../test/SemaTemplate/member-function-template.cpp | 103 ++++++ .../member-inclass-init-value-dependent.cpp | 18 + clang/test/SemaTemplate/member-initializers.cpp | 13 + .../SemaTemplate/member-template-access-expr.cpp | 144 ++++++++ clang/test/SemaTemplate/metafun-apply.cpp | 40 +++ .../SemaTemplate/missing-class-keyword-crash.cpp | 7 + .../ms-function-specialization-class-scope.cpp | 71 ++++ clang/test/SemaTemplate/ms-if-exists.cpp | 68 ++++ .../ms-lookup-template-base-classes.cpp | 145 ++++++++ .../test/SemaTemplate/nested-incomplete-class.cpp | 21 ++ clang/test/SemaTemplate/nested-linkage.cpp | 3 + .../SemaTemplate/nested-name-spec-template.cpp | 142 ++++++++ clang/test/SemaTemplate/nested-template.cpp | 157 +++++++++ .../SemaTemplate/operator-function-id-template.cpp | 28 ++ clang/test/SemaTemplate/operator-template.cpp | 18 + clang/test/SemaTemplate/overload-candidates.cpp | 40 +++ clang/test/SemaTemplate/overload-uneval.cpp | 42 +++ .../test/SemaTemplate/partial-spec-instantiate.cpp | 50 +++ clang/test/SemaTemplate/pragma-ms_struct.cpp | 10 + clang/test/SemaTemplate/qualified-id.cpp | 56 ++++ clang/test/SemaTemplate/qualified-names-diag.cpp | 16 + clang/test/SemaTemplate/rdar9173693.cpp | 6 + clang/test/SemaTemplate/recovery-crash.cpp | 19 ++ .../recursive-template-instantiation.cpp | 10 + .../SemaTemplate/resolve-single-template-id.cpp | 82 +++++ clang/test/SemaTemplate/self-comparison.cpp | 48 +++ clang/test/SemaTemplate/temp.cpp | 19 ++ clang/test/SemaTemplate/temp_arg.cpp | 20 ++ clang/test/SemaTemplate/temp_arg_nontype.cpp | 325 ++++++++++++++++++ clang/test/SemaTemplate/temp_arg_template.cpp | 62 ++++ clang/test/SemaTemplate/temp_arg_type.cpp | 42 +++ clang/test/SemaTemplate/temp_class_order.cpp | 42 +++ clang/test/SemaTemplate/temp_class_spec.cpp | 363 +++++++++++++++++++++ clang/test/SemaTemplate/temp_class_spec_blocks.cpp | 34 ++ clang/test/SemaTemplate/temp_class_spec_neg.cpp | 45 +++ clang/test/SemaTemplate/temp_explicit.cpp | 151 +++++++++ clang/test/SemaTemplate/temp_explicit_cxx0x.cpp | 24 ++ clang/test/SemaTemplate/temp_func_order.cpp | 95 ++++++ clang/test/SemaTemplate/template-class-traits.cpp | 8 + clang/test/SemaTemplate/template-decl-fail.cpp | 10 + clang/test/SemaTemplate/template-id-expr.cpp | 98 ++++++ clang/test/SemaTemplate/template-id-printing.cpp | 141 ++++++++ clang/test/SemaTemplate/typename-specifier-2.cpp | 30 ++ clang/test/SemaTemplate/typename-specifier-3.cpp | 19 ++ clang/test/SemaTemplate/typename-specifier-4.cpp | 164 ++++++++++ clang/test/SemaTemplate/typename-specifier.cpp | 117 +++++++ clang/test/SemaTemplate/typo-dependent-name.cpp | 17 + clang/test/SemaTemplate/unresolved-construct.cpp | 19 ++ clang/test/SemaTemplate/unused-variables.cpp | 21 ++ .../value-dependent-null-pointer-constant.cpp | 29 ++ .../test/SemaTemplate/virtual-member-functions.cpp | 86 +++++ 177 files changed, 12320 insertions(+) create mode 100644 clang/test/SemaTemplate/ackermann.cpp create mode 100644 clang/test/SemaTemplate/address-spaces.cpp create mode 100644 clang/test/SemaTemplate/alias-church-numerals.cpp create mode 100644 clang/test/SemaTemplate/alias-nested-nontag.cpp create mode 100644 clang/test/SemaTemplate/alias-template-template-param.cpp create mode 100644 clang/test/SemaTemplate/alias-templates.cpp create mode 100644 clang/test/SemaTemplate/ambiguous-ovl-print.cpp create mode 100644 clang/test/SemaTemplate/anonymous-union.cpp create mode 100644 clang/test/SemaTemplate/array-to-pointer-decay.cpp create mode 100644 clang/test/SemaTemplate/atomics.cpp create mode 100644 clang/test/SemaTemplate/attributes.cpp create mode 100644 clang/test/SemaTemplate/canonical-expr-type-0x.cpp create mode 100644 clang/test/SemaTemplate/canonical-expr-type.cpp create mode 100644 clang/test/SemaTemplate/class-template-ctor-initializer.cpp create mode 100644 clang/test/SemaTemplate/class-template-decl.cpp create mode 100644 clang/test/SemaTemplate/class-template-id-2.cpp create mode 100644 clang/test/SemaTemplate/class-template-id.cpp create mode 100644 clang/test/SemaTemplate/class-template-spec.cpp create mode 100644 clang/test/SemaTemplate/constexpr-instantiate.cpp create mode 100644 clang/test/SemaTemplate/constructor-template.cpp create mode 100644 clang/test/SemaTemplate/copy-ctor-assign.cpp create mode 100644 clang/test/SemaTemplate/crash-10438657.cpp create mode 100644 clang/test/SemaTemplate/crash-8204126.cpp create mode 100644 clang/test/SemaTemplate/current-instantiation.cpp create mode 100644 clang/test/SemaTemplate/deduction-crash.cpp create mode 100644 clang/test/SemaTemplate/deduction.cpp create mode 100644 clang/test/SemaTemplate/default-arguments-cxx0x.cpp create mode 100644 clang/test/SemaTemplate/default-arguments.cpp create mode 100644 clang/test/SemaTemplate/default-expr-arguments-2.cpp create mode 100644 clang/test/SemaTemplate/default-expr-arguments.cpp create mode 100644 clang/test/SemaTemplate/delegating-constructors.cpp create mode 100644 clang/test/SemaTemplate/dependent-base-classes.cpp create mode 100644 clang/test/SemaTemplate/dependent-base-member-init.cpp create mode 100644 clang/test/SemaTemplate/dependent-class-member-operator.cpp create mode 100644 clang/test/SemaTemplate/dependent-expr.cpp create mode 100644 clang/test/SemaTemplate/dependent-names-no-std.cpp create mode 100644 clang/test/SemaTemplate/dependent-names.cpp create mode 100644 clang/test/SemaTemplate/dependent-sized_array.cpp create mode 100644 clang/test/SemaTemplate/dependent-template-recover.cpp create mode 100644 clang/test/SemaTemplate/dependent-type-identity.cpp create mode 100644 clang/test/SemaTemplate/destructor-template.cpp create mode 100644 clang/test/SemaTemplate/elaborated-type-specifier.cpp create mode 100644 clang/test/SemaTemplate/enum-argument.cpp create mode 100644 clang/test/SemaTemplate/enum-forward.cpp create mode 100644 clang/test/SemaTemplate/example-dynarray.cpp create mode 100644 clang/test/SemaTemplate/example-typelist.cpp create mode 100644 clang/test/SemaTemplate/explicit-instantiation.cpp create mode 100644 clang/test/SemaTemplate/explicit-specialization-member.cpp create mode 100644 clang/test/SemaTemplate/ext-vector-type.cpp create mode 100644 clang/test/SemaTemplate/extern-templates.cpp create mode 100644 clang/test/SemaTemplate/fibonacci.cpp create mode 100644 clang/test/SemaTemplate/friend-template.cpp create mode 100644 clang/test/SemaTemplate/friend.cpp create mode 100644 clang/test/SemaTemplate/fun-template-def.cpp create mode 100644 clang/test/SemaTemplate/function-template-specialization.cpp create mode 100644 clang/test/SemaTemplate/implicit-instantiation-1.cpp create mode 100644 clang/test/SemaTemplate/inject-templated-friend-post.cpp create mode 100644 clang/test/SemaTemplate/inject-templated-friend.cpp create mode 100644 clang/test/SemaTemplate/injected-class-name.cpp create mode 100644 clang/test/SemaTemplate/instantiate-anonymous-union.cpp create mode 100644 clang/test/SemaTemplate/instantiate-array.cpp create mode 100644 clang/test/SemaTemplate/instantiate-attr.cpp create mode 100644 clang/test/SemaTemplate/instantiate-c99.cpp create mode 100644 clang/test/SemaTemplate/instantiate-call.cpp create mode 100644 clang/test/SemaTemplate/instantiate-case.cpp create mode 100644 clang/test/SemaTemplate/instantiate-cast.cpp create mode 100644 clang/test/SemaTemplate/instantiate-clang.cpp create mode 100644 clang/test/SemaTemplate/instantiate-complete.cpp create mode 100644 clang/test/SemaTemplate/instantiate-decl-dtor.cpp create mode 100644 clang/test/SemaTemplate/instantiate-decl-init.cpp create mode 100644 clang/test/SemaTemplate/instantiate-declref-ice.cpp create mode 100644 clang/test/SemaTemplate/instantiate-declref.cpp create mode 100644 clang/test/SemaTemplate/instantiate-deeply.cpp create mode 100644 clang/test/SemaTemplate/instantiate-default-assignment-operator.cpp create mode 100644 clang/test/SemaTemplate/instantiate-dependent-nested-name.cpp create mode 100644 clang/test/SemaTemplate/instantiate-elab-type-specifier.cpp create mode 100644 clang/test/SemaTemplate/instantiate-enum-2.cpp create mode 100644 clang/test/SemaTemplate/instantiate-enum.cpp create mode 100644 clang/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp create mode 100644 clang/test/SemaTemplate/instantiate-exception-spec.cpp create mode 100644 clang/test/SemaTemplate/instantiate-expr-1.cpp create mode 100644 clang/test/SemaTemplate/instantiate-expr-2.cpp create mode 100644 clang/test/SemaTemplate/instantiate-expr-3.cpp create mode 100644 clang/test/SemaTemplate/instantiate-expr-4.cpp create mode 100644 clang/test/SemaTemplate/instantiate-expr-5.cpp create mode 100644 clang/test/SemaTemplate/instantiate-expr-basic.cpp create mode 100644 clang/test/SemaTemplate/instantiate-field.cpp create mode 100644 clang/test/SemaTemplate/instantiate-friend-class.cpp create mode 100644 clang/test/SemaTemplate/instantiate-function-1.cpp create mode 100644 clang/test/SemaTemplate/instantiate-function-1.mm create mode 100644 clang/test/SemaTemplate/instantiate-function-2.cpp create mode 100644 clang/test/SemaTemplate/instantiate-function-params.cpp create mode 100644 clang/test/SemaTemplate/instantiate-init.cpp create mode 100644 clang/test/SemaTemplate/instantiate-invalid.cpp create mode 100644 clang/test/SemaTemplate/instantiate-local-class.cpp create mode 100644 clang/test/SemaTemplate/instantiate-member-class.cpp create mode 100644 clang/test/SemaTemplate/instantiate-member-expr.cpp create mode 100644 clang/test/SemaTemplate/instantiate-member-initializers.cpp create mode 100644 clang/test/SemaTemplate/instantiate-member-pointers.cpp create mode 100644 clang/test/SemaTemplate/instantiate-member-template.cpp create mode 100644 clang/test/SemaTemplate/instantiate-method.cpp create mode 100644 clang/test/SemaTemplate/instantiate-non-dependent-types.cpp create mode 100644 clang/test/SemaTemplate/instantiate-non-type-template-parameter.cpp create mode 100644 clang/test/SemaTemplate/instantiate-objc-1.mm create mode 100644 clang/test/SemaTemplate/instantiate-overload-candidates.cpp create mode 100644 clang/test/SemaTemplate/instantiate-overloaded-arrow.cpp create mode 100644 clang/test/SemaTemplate/instantiate-self.cpp create mode 100644 clang/test/SemaTemplate/instantiate-sizeof.cpp create mode 100644 clang/test/SemaTemplate/instantiate-static-var.cpp create mode 100644 clang/test/SemaTemplate/instantiate-subscript.cpp create mode 100644 clang/test/SemaTemplate/instantiate-template-template-parm.cpp create mode 100644 clang/test/SemaTemplate/instantiate-try-catch.cpp create mode 100644 clang/test/SemaTemplate/instantiate-type.cpp create mode 100644 clang/test/SemaTemplate/instantiate-typedef.cpp create mode 100644 clang/test/SemaTemplate/instantiate-typeof.cpp create mode 100644 clang/test/SemaTemplate/instantiate-using-decl.cpp create mode 100644 clang/test/SemaTemplate/instantiation-backtrace.cpp create mode 100644 clang/test/SemaTemplate/instantiation-default-1.cpp create mode 100644 clang/test/SemaTemplate/instantiation-default-2.cpp create mode 100644 clang/test/SemaTemplate/instantiation-default-3.cpp create mode 100644 clang/test/SemaTemplate/instantiation-depth.cpp create mode 100644 clang/test/SemaTemplate/instantiation-order.cpp create mode 100644 clang/test/SemaTemplate/issue150.cpp create mode 100644 clang/test/SemaTemplate/lookup-dependent-bases.cpp create mode 100644 clang/test/SemaTemplate/member-access-ambig.cpp create mode 100644 clang/test/SemaTemplate/member-access-expr.cpp create mode 100644 clang/test/SemaTemplate/member-function-template.cpp create mode 100644 clang/test/SemaTemplate/member-inclass-init-value-dependent.cpp create mode 100644 clang/test/SemaTemplate/member-initializers.cpp create mode 100644 clang/test/SemaTemplate/member-template-access-expr.cpp create mode 100644 clang/test/SemaTemplate/metafun-apply.cpp create mode 100644 clang/test/SemaTemplate/missing-class-keyword-crash.cpp create mode 100644 clang/test/SemaTemplate/ms-function-specialization-class-scope.cpp create mode 100644 clang/test/SemaTemplate/ms-if-exists.cpp create mode 100644 clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp create mode 100644 clang/test/SemaTemplate/nested-incomplete-class.cpp create mode 100644 clang/test/SemaTemplate/nested-linkage.cpp create mode 100644 clang/test/SemaTemplate/nested-name-spec-template.cpp create mode 100644 clang/test/SemaTemplate/nested-template.cpp create mode 100644 clang/test/SemaTemplate/operator-function-id-template.cpp create mode 100644 clang/test/SemaTemplate/operator-template.cpp create mode 100644 clang/test/SemaTemplate/overload-candidates.cpp create mode 100644 clang/test/SemaTemplate/overload-uneval.cpp create mode 100644 clang/test/SemaTemplate/partial-spec-instantiate.cpp create mode 100644 clang/test/SemaTemplate/pragma-ms_struct.cpp create mode 100644 clang/test/SemaTemplate/qualified-id.cpp create mode 100644 clang/test/SemaTemplate/qualified-names-diag.cpp create mode 100644 clang/test/SemaTemplate/rdar9173693.cpp create mode 100644 clang/test/SemaTemplate/recovery-crash.cpp create mode 100644 clang/test/SemaTemplate/recursive-template-instantiation.cpp create mode 100644 clang/test/SemaTemplate/resolve-single-template-id.cpp create mode 100644 clang/test/SemaTemplate/self-comparison.cpp create mode 100644 clang/test/SemaTemplate/temp.cpp create mode 100644 clang/test/SemaTemplate/temp_arg.cpp create mode 100644 clang/test/SemaTemplate/temp_arg_nontype.cpp create mode 100644 clang/test/SemaTemplate/temp_arg_template.cpp create mode 100644 clang/test/SemaTemplate/temp_arg_type.cpp create mode 100644 clang/test/SemaTemplate/temp_class_order.cpp create mode 100644 clang/test/SemaTemplate/temp_class_spec.cpp create mode 100644 clang/test/SemaTemplate/temp_class_spec_blocks.cpp create mode 100644 clang/test/SemaTemplate/temp_class_spec_neg.cpp create mode 100644 clang/test/SemaTemplate/temp_explicit.cpp create mode 100644 clang/test/SemaTemplate/temp_explicit_cxx0x.cpp create mode 100644 clang/test/SemaTemplate/temp_func_order.cpp create mode 100644 clang/test/SemaTemplate/template-class-traits.cpp create mode 100644 clang/test/SemaTemplate/template-decl-fail.cpp create mode 100644 clang/test/SemaTemplate/template-id-expr.cpp create mode 100644 clang/test/SemaTemplate/template-id-printing.cpp create mode 100644 clang/test/SemaTemplate/typename-specifier-2.cpp create mode 100644 clang/test/SemaTemplate/typename-specifier-3.cpp create mode 100644 clang/test/SemaTemplate/typename-specifier-4.cpp create mode 100644 clang/test/SemaTemplate/typename-specifier.cpp create mode 100644 clang/test/SemaTemplate/typo-dependent-name.cpp create mode 100644 clang/test/SemaTemplate/unresolved-construct.cpp create mode 100644 clang/test/SemaTemplate/unused-variables.cpp create mode 100644 clang/test/SemaTemplate/value-dependent-null-pointer-constant.cpp create mode 100644 clang/test/SemaTemplate/virtual-member-functions.cpp (limited to 'clang/test/SemaTemplate') 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 +// struct Ackermann { +// enum { +// value = M ? (N ? Ackermann >::value +// : Ackermann::value) +// : N + 1 +// }; +// }; + +template +struct Ackermann { + enum { + value = Ackermann::value >::value + }; +}; + +template struct Ackermann { + enum { + value = Ackermann::value + }; +}; + +template 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 +struct is_same { + static const bool value = false; +}; + +template +struct is_same { + 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 +struct remove_pointer { + typedef T type; +}; + +template +struct remove_pointer { + typedef T type; +}; + +int check_remove0[is_same::type, int_1>::value? 1 : -1]; +int check_remove1[is_same::type, int_2>::value? 1 : -1]; +int check_remove2[is_same::type, int>::value? -1 : 1]; +int check_remove3[is_same::type, int_1>::value? -1 : 1]; + +template +struct is_pointer_in_address_space_1 { + static const bool value = false; +}; + +template +struct is_pointer_in_address_space_1 { + static const bool value = true; +}; + +int check_ptr_in_as1[is_pointer_in_address_space_1::value? 1 : -1]; +int check_ptr_in_as2[is_pointer_in_address_space_1::value? -1 : 1]; +int check_ptr_in_as3[is_pointer_in_address_space_1::value? -1 : 1]; + +// Check that we maintain address spaces through template argument +// deduction for a call. +template +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 struct identity {}; + +template +identity accept_arg_in_address_space_1(__attribute__((address_space(1))) T &ir1); + +template +identity accept_any_arg(T &ir1); + +void test_arg_in_address_space_1() { + static int __attribute__((address_space(1))) int_1; + identity ii = accept_arg_in_address_space_1(int_1); + identity ii2 = accept_any_arg(int_1); +} + +// Partial ordering +template int &order1(__attribute__((address_space(1))) T&); +template 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 class, typename> class T, template class V> struct PartialApply { + template using R = T; +}; + +template using Id = T; +template class, typename X> using Zero = X; +template class, typename> class N, template class F, typename X> using Succ = F>; + +template class F, typename X> using One = Succ; +template class F, typename X> using Two = Succ; + +template class, typename> class A, + template class, typename> class B, + template class F, + typename X> using Add = A>; + +template class, typename> class A, + template class, typename> class B, + template class F, + typename X> using Mul = A::template R, X>; + +template class F, typename X> using Four = Add; +template class F, typename X> using Sixteen = Mul; +template class F, typename X> using TwoHundredAndFiftySix = Mul; + +template struct Const { static const T value = N; }; +template struct IncrementHelper; +template struct IncrementHelper> { using Result = Const; }; +template using Increment = typename IncrementHelper::Result; + +using Arr = int[TwoHundredAndFiftySix>::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 using Id = T; // expected-note {{type alias template 'Id' declared here}} +struct U { static Id V; }; +Id ::U::V; // expected-error {{type 'Id' (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 class D> using C = D; + +// Substitution of the alias template transforms the TemplateSpecializationType +// 'D' into the DependentTemplateSpecializationType 'T::template U'. +template void f(C); 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 +struct A { + typedef S B; + template using C = typename T::B; + template struct D { + template using E = typename A::template C>; + template using F = A>; + template using G = C>; + G g; + }; + typedef decltype(D().g) H; + D h; + template using I = A; + template using J = typename A::template C>; +}; + +A a; +A::D b; + +template T make(); + +namespace X { + template struct traits { + typedef T thing; + typedef decltype(val(make())) inner_ptr; + + template using rebind_thing = typename thing::template rebind; + template using rebind = traits>; + + inner_ptr &&alloc(); + void free(inner_ptr&&); + }; + + template struct ptr_traits { + typedef T *type; + }; + template using ptr = typename ptr_traits::type; + + template struct thing { + typedef T inner; + typedef ptr inner_ptr; + typedef traits> traits_type; + + template using rebind = thing; + + thing(traits_type &traits) : traits(traits), val(traits.alloc()) {} + ~thing() { traits.free(static_cast(val)); } + + traits_type &traits; + inner_ptr val; + + friend inner_ptr val(const thing &t) { return t.val; } + }; + + template<> struct ptr_traits { + typedef bool &type; + }; + template<> bool &traits>::alloc() { static bool b; return b; } + template<> void traits>::free(bool&) {} +} + +typedef X::traits> itt; + +itt::thing::traits_type itr; +itt::thing ith(itr); + +itt::rebind btr; +itt::rebind_thing btt(btr); + +namespace PR11848 { + template using U = int; + + template + void f(U i, U ...is) { // expected-error {{type 'U' (aka 'int') of function parameter pack does not contain any unexpanded parameter packs}} + return i + f(is...); // expected-error {{pack expansion does not contain any unexpanded parameter packs}} + } + + template + struct S { + S(U...ts); // expected-error {{does not contain any unexpanded parameter packs}} + }; + + template + struct Hidden1 { + template + Hidden1(typename T::template U ...ts); // expected-error{{type 'typename Hide::U' (aka 'int') of function parameter pack does not contain any unexpanded parameter packs}} + }; + + template + struct Hidden2 { + Hidden2(typename T::template U ...ts); + }; + + struct Hide { + template using U = int; + }; + + Hidden1 h1; // expected-note{{in instantiation of template class 'PR11848::Hidden1' requested here}} + Hidden2 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 + 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 +struct T1 : public T0, public T { + void f0() { + m0 = 0; // expected-error{{ambiguous conversion}} + } +}; + +struct A : public T0 { }; + +void f1(T1 *S) { S->f0(); } // expected-note{{instantiation of member function}} + +namespace rdar8635664 { + template + struct X { + struct inner; + + struct inner { + union { + int x; + float y; + }; + + typedef T type; + }; + }; + + void test() { + X::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 foo() { + mystruct s[1]; + return s->member; +} + +int main() { + foo<1>(); +} + +// PR7405 +struct hb_sanitize_context_t { + int start; +}; +template static bool sanitize() { + hb_sanitize_context_t c[1]; + return !c->start; +} +bool closure = sanitize(); 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 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 + void g(unsigned *x) { + __sync_bool_compare_and_swap(x, 1, 4); + } + void h() { g(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 + struct X { + char c[1] __attribute__((__aligned__((N)))); // expected-error {{alignment is not a power of 2}} + }; + + template struct check { + int check_failed[X ? 1 : -1]; // expected-error {{array with a negative size}} + }; + + template struct check_alignment { + typedef check)> 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 __attribute__((cf_returns_retained)) + inline T WBCFRetain(T aValue) { return aValue ? (T)CFRetain(aValue) : (T)0; } + + + extern void CFRelease(const void *ref); + + template + 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 +void f0(T x, decltype(f(N, x)) y) { } // expected-note{{previous}} + +template +void f0(T x, decltype((f)(N, x)) y) { } + +template +void f0(U u, decltype(f(M, u))) { } // expected-error{{redefinition}} + +// PR12438: Test sizeof...() canonicalization +template struct N {}; + +template +N f1() {} // expected-note{{previous}} + +template +N f1() {} + +template +N 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 +void f0(T x, __typeof__(f(x)) y) { } // expected-note{{previous}} + +template +void f0(T x, __typeof__((f)(x)) y) { } + +template +void f0(U u, __typeof__(f(u))) { } // expected-error{{redefinition}} + +// Test insane typeof(expr) overload set canonicalization +void f(int); +void f(double); + +template +void f0a(T x, __typeof__(f(N)) y) { } // expected-note{{previous}} + +void f(int); + +template +void f0a(T x, __typeof__(f(N)) y) { } // expected-error{{redefinition}} \ + // expected-note{{previous}} + +void f(float); + +template +void f0a(T x, __typeof__(f(N)) y) { } // expected-error{{redefinition}} + +// Test dependently-sized array canonicalization +template +void f1(T (&array)[N + M]) { } // expected-note{{previous}} + +template +void f1(T (&array)[M + N]) { } + +template +void f1(T (&array)[M + N]) { } // expected-error{{redefinition}} + +// Test dependently-sized extended vector type canonicalization +template +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 struct A {}; + +template struct B : A { + B() : A() {} +}; +B x; + +template struct B1 : A { + typedef A Base; + B1() : Base() {} +}; +B1 x1; + + +template struct Tmpl { }; + +template struct TmplB { }; + +struct TmplC : Tmpl { + TmplC() : + Tmpl(), + TmplB() { } // expected-error {{type 'TmplB' is not a direct or virtual base of 'TmplC'}} +}; + + +struct TmplD : Tmpl, TmplB { + TmplD(): + Tmpl(), // expected-error {{type 'Tmpl' is not a direct or virtual base of 'TmplD'}} + TmplB() {} +}; + +namespace PR7259 { + class Base { + public: + Base() {} + }; + + template + class Derived : public ParentClass { + public: + Derived() : Base() {} + }; + + class Final : public Derived { + }; + + 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 class A; + +extern "C++" { + template class B; +} + +namespace N { + template class C; +} + +extern "C" { + template class D; // expected-error{{templates must have C++ linkage}} +} + +template class A; // expected-note{{previous template declaration is here}} + +template class A; // expected-error{{template parameter has a different kind in template redeclaration}} + +template class NonTypeTemplateParm; + +typedef int INT; + +template class NonTypeTemplateParm; // expected-note{{previous non-type template parameter with type 'INT' (aka 'int') is here}} + +template class NonTypeTemplateParm; // expected-error{{template non-type parameter has a different type 'long' in template redeclaration}} + +template class X> class TemplateTemplateParm; + +template class Y> class TemplateTemplateParm; // expected-note{{previous template declaration is here}} \ + // expected-note{{previous template template parameter is here}} + +template class TemplateTemplateParm; // expected-error{{template parameter has a different kind in template redeclaration}} + +template class X> class TemplateTemplateParm; // expected-error{{too many template parameters in template template parameter redeclaration}} + +template +struct test {}; // expected-note{{previous definition}} + +template +struct test : T {}; // expected-error{{redefinition}} + +class X { +public: + template class C; +}; + +void f() { + template class X; // expected-error{{expression}} +} + +template class X1 var; // expected-error{{declared as a template}} + +namespace M { +} + +template class M::C3 { }; // expected-error{{out-of-line definition of 'C3' does not match any declaration in namespace 'M'}} + +namespace PR8001 { + template + struct Foo { + template class Bar; + typedef Bar Baz; + + template + struct Bar { + Bar() {} + }; + }; + + void pr8001() { + Foo::Baz x; + Foo::Bar y(x); + } +} + +namespace rdar9676205 { + template class tuple_element; + + template class pair; + + template + class tuple_element<0, pair<_T1, _T2> > + { + template + struct X + { + template ::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 class A { }; + + template<> class A { }; + + template<> class A; // expected-note{{forward declaration of 'N::A'}} + + class B : public A { }; +} + +class C1 : public N::A { }; + +class C2 : public N::A { }; // expected-error{{base class has incomplete type}} + +struct D1 { + operator N::A(); +}; + +namespace N { + struct D2 { + operator A(); + }; +} 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 struct A { }; + +typedef A A_int; + +typedef float FLOAT; + +A *foo(A *ptr, A const *ptr2, A *ptr3) { + if (ptr) + return ptr; // okay + else if (ptr2) + return ptr2; // expected-error{{cannot initialize return object of type 'A *' with an lvalue of type 'const A *'}} + else { + return ptr3; // expected-error{{cannot initialize return object of type 'A *' with an lvalue of type 'A *'}} + } +} + +template 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 struct C {}; +} + +N::C c1; +typedef N::C c2; + +// PR5655 +template struct Foo { }; // expected-note{{template is declared here}} + +void f(void) { Foo bar; } // expected-error{{without a template argument list}} + +// rdar://problem/8254267 +template class Party; +template <> class Party { 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 struct A; // expected-note {{template is declared here}} \ + // expected-note{{explicitly specialized}} + +template<> struct A; // expected-note{{forward declaration}} + +template<> struct A { // expected-note{{previous definition}} + int x; +}; + +template<> struct A { // expected-note{{previous definition}} + int y; +}; + +int test_specs(A *a1, A *a2) { + return a1->x + a2->y; +} + +int test_incomplete_specs(A *a1, + A *a2) +{ + (void)a1->x; // expected-error{{member access into incomplete type}} + (void)a2->x; // expected-error{{implicit instantiation of undefined template 'A'}} +} + +typedef float FLOAT; + +template<> struct A; + +template<> struct A { }; // expected-error{{redefinition}} + +template<> struct A { }; // expected-error{{redefinition}} + +template struct X; + +template <> struct X { int foo(); }; // #1 +template <> struct X { int bar(); }; // #2 + +typedef int int_type; +void testme(X *x1, X *x2) { + (void)x1->foo(); // okay: refers to #1 + (void)x2->bar(); // okay: refers to #2 +} + +// Make sure specializations are proper classes. +template<> +struct A { + A(); +}; + +A::A() { } + +// Make sure we can see specializations defined before the primary template. +namespace N{ + template struct A0; +} + +namespace N { + template<> + struct A0 { + typedef void* pointer; + }; +} + +namespace N { + template + struct A0 { + void foo(A0::pointer p = 0); + }; +} + +// Diagnose specialization errors +struct A { }; // expected-error{{template specialization requires 'template<>'}} + +template<> struct ::A; + +namespace N { + template struct B; // expected-note 2{{explicitly specialized}} + + template<> struct ::N::B; // okay + template<> struct ::N::B; // okay + template<> struct ::N::B; // okay + + int f(int); +} + +template<> struct N::B { }; // okay + +template<> struct N::B { }; // expected-warning{{C++11 extension}} + +namespace M { + template<> struct ::N::B { }; // expected-error{{class template specialization of 'B' not in a namespace enclosing 'N'}} + + template<> struct ::A; // expected-error{{originally}} +} + +template<> struct N::B { + int testf(int x) { return f(x); } +}; + +// PR5264 +template class Foo; +Foo* v; +Foo& F() { return *v; } +template class Foo {}; +Foo x; + + +// Template template parameters +template class Wibble> +class Wibble { }; // expected-error{{cannot specialize a template template parameter}} + +namespace rdar9676205 { + template + struct X { + template + struct X { // 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 static constexpr T get() { return T(); } + // ok, not a constant expression. + int n = get(); + }; + + // ok, constant expression. + constexpr int j = A::get(); + + template constexpr int consume(T); + // ok, not a constant expression. + const int k = consume(0); // expected-note {{here}} + + template 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 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 constexpr T f(T n) { return n; } + int f() { + switch (f()) { + case f(4): return 0; + } + return 1; + } +} + +namespace OverloadResolution { + template constexpr T f(T t) { return t; } + + template struct S { }; + + template auto g(T t) -> S &; + char &f(...); + + template auto h(T t[f(sizeof(T))]) -> decltype(&*t) { + return t; + } + + S<4> &k = g(0); + int *p, *q = h(p); +} + +namespace DataMember { + template struct S { static const int k; }; + const int n = S::k; // expected-note {{here}} + template const int S::k = 0; + constexpr int m = S::k; // ok + constexpr int o = n; // expected-error {{constant expression}} expected-note {{initializer of 'n'}} +} + +namespace Reference { + const int k = 5; + template struct S { + static volatile int &r; + }; + template volatile int &S::r = const_cast(k); + constexpr int n = const_cast(S::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 X0(T); // expected-note {{candidate}} + template X0(T*, U*); // expected-note {{candidate}} + + // PR4761 + template 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 +struct X1 { + X1(const X1&); + template X1(const X1&); +}; + +template +struct Outer { + typedef X1 A; + + A alloc; + + explicit Outer(const A& a) : alloc(a) { } +}; + +void test_X1(X1 xi) { + Outer oi(xi); + Outer of(xi); +} + +// PR4655 +template struct A {}; +template <> struct A{A(const A&);}; +struct B { A x; B(B& a) : x(a.x) {} }; + +struct X2 { + X2(); // expected-note{{candidate constructor}} + X2(X2&); // expected-note {{candidate constructor}} + template 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 X3(T); +}; + +template<> X3::X3(X3); // expected-error{{must pass its first argument by reference}} + +struct X4 { + X4(); + ~X4(); + X4(X4&); + template 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 +void default_ctor_inst() { + DefaultCtorHasDefaultArg def; +} + +template void default_ctor_inst(); + +template +struct X5 { + X5(); + X5(const T &); +}; + +struct X6 { + template X6(T); +}; + +void test_X5_X6() { + X5 tf; + X5 tf2(tf); +} + +namespace PR8182 { + struct foo { + foo(); + template 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 +struct X { + template + X(const X& other) + : value(other.value + 1) { } // expected-error{{binary expression}} + + template + X& operator=(const X& other) { + value = other.value + 1; // expected-error{{binary expression}} + return *this; + } + + T value; +}; + +struct Y {}; + +X test0(X x) { return x; } +X test1(X x) { return x; } + + +X test2(X x) { + return x; // expected-note{{instantiation}} +} + +void test3(X &x, X xi, X xl, X xmptr) { + x = xi; + x = xl; + x = xmptr; // expected-note{{instantiation}} +} + +struct X1 { + X1 &operator=(const X1&); +}; + +template +struct X2 : X1 { + template X2 &operator=(const U&); +}; + +struct X3 : X2 { +}; + +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 +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(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 template 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 +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_type&); // expected-error{{redecl}} + + void f2(T&); // expected-note{{previous}} + void f2(typename X0::U_type&); + void f2(typename X0::T_type&); // expected-error{{redecl}} + + void f3(T&); // expected-note{{previous}} + void f3(typename X0::U_type&); + void f3(typename ::X0::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_type&); // expected-error{{redecl}} + + void g2(T&); // expected-note{{previous}} + void g2(typename X0::U_type&); + void g2(typename X0::T_type&); // expected-error{{redecl}} + + void g3(T&); // expected-note{{previous}} + void g3(typename X0::U_type&); + void g3(typename ::X0::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::X1::my_T_type&); // expected-error{{redecl}} + + void g7(T&); // expected-note{{previous}} + void g7(typename X0::U_type&); + void g7(typename ::X0::X1::my_T_type&); // expected-error{{redecl}} + + void g8(T&); // expected-note{{previous}} + void g8(typename X0::T_type&); + void g8(typename ::X0::X1::my_T_type, U_type>::X1::my_T_type&); // expected-error{{redecl}} + }; +}; + + +template +struct X0 { + 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_type&); // expected-error{{redecl}} + + void f2(T&); // expected-note{{previous}} + void f2(typename X0::U_type&); + void f2(typename X0::T_type&); // expected-error{{redecl}} + + void f3(T&); // expected-note{{previous}} + void f3(typename X0::U_type&); + void f3(typename ::X0::T_type&); // expected-error{{redecl}} + + void f4(T&); // expected-note{{previous}} + void f4(typename X0::U_type&); + void f4(typename ::X0::T_type&); // expected-error{{redecl}} + + void f5(X0*); // expected-note{{previous}} + void f5(::X0*); + void f5(::X0*); // 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_type&); // expected-error{{redecl}} + + void g2(T&); // expected-note{{previous}} + void g2(typename X0::U_type&); + void g2(typename X0::T_type&); // expected-error{{redecl}} + + void g3(T&); // expected-note{{previous}} + void g3(typename X0::U_type&); + void g3(typename ::X0::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::X2::my_T_type&); // expected-error{{redecl}} + + void g7(T&); // expected-note{{previous}} + void g7(typename X0::U_type&); + void g7(typename ::X0::X2::my_T_type&); // expected-error{{redecl}} + + void g8(T&); // expected-note{{previous}} + void g8(typename X0::T_type&); + void g8(typename ::X0::X2::my_T_type*, U_type*>::X2::my_T_type&); // expected-error{{redecl}} + }; +}; + +template +struct X1 { + static int *a; + void f(float *b) { + X1::a = b; // expected-error{{incompatible}} + X1::a = b; + } +}; + +namespace ConstantInCurrentInstantiation { + template + struct X { + static const int value = 2; + static int array[value]; + }; + + template const int X::value; + + template + int X::array[X::value] = { 1, 2 }; +} + +namespace Expressions { + template + struct Bool { + enum anonymous_enum { value = b }; + }; + struct True : public Bool {}; + struct False : public Bool {}; + + template + struct Is_Same : public False {}; + template + struct Is_Same : public True {}; + + template + struct Enable_If {}; + template + struct Enable_If { + typedef T type; + }; + + template + class Class { + public: + template + typename Enable_If::value, void>::type + foo(); + }; + + + template + template + typename Enable_If >::value, void>::type + Class::foo() {} +} + +namespace PR9255 { + template + class X0 { + public: + class Inner1; + + class Inner2 { + public: + void f() + { + Inner1::f.g(); + } + }; + }; +} + +namespace rdar10194295 { + template + class X { + public: + enum Enum { Yes, No }; + template void foo(); + template class Inner; + }; + + template + template::Enum> + void X::foo() + { + } + + template + template::Enum> + class X::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 +struct int_; + +template +template +struct ac +{ + typedef T1 ae +}; + +templatestruct aaa +{ + typedef ac<1,int,int>::ae ae +}; + +template +struct state_machine +{ + typedef aaa::ae aaa; + int start() + { + ant(0); + } + + template + struct region_processing_helper + { + template + struct In; + + template + struct In,my>; + + template + int process(Event) + { + In > a; + } + } + template + int ant(Event) + { + region_processing_helper* helper; + helper->process(0) + } +}; + +int a() +{ + state_machine p; + p.ant(0); +} + +// PR9974 +template struct enable_if; +template struct remove_reference ; +template struct remove_reference<_Tp&> ; + +template struct __tuple_like; + +template ::type>::value> +struct __tuple_convertible; + +struct pair +{ +template::value>::type> +pair(_Tuple&& ); +}; + +template struct basic_ostream; + +template +void endl( ) ; + +extern basic_ostream cout; + +int operator<<( basic_ostream , 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 class A> +struct X0 { + static const unsigned value = 0; +}; + +template class A> +struct X0 { + static const unsigned value = 1; +}; + +template struct X0i; +template struct X0l; +int array_x0a[X0::value == 0? 1 : -1]; +int array_x0b[X0::value == 1? 1 : -1]; + +template +struct is_same { + static const bool value = false; +}; + +template +struct is_same { + static const bool value = true; +}; + +template struct allocator { }; +template > struct vector {}; + +// Fun with meta-lambdas! +struct _1 {}; +struct _2 {}; + +// Replaces all occurrences of _1 with Arg1 and _2 with Arg2 in T. +template +struct Replace { + typedef T type; +}; + +// Replacement of the whole type. +template +struct Replace<_1, Arg1, Arg2> { + typedef Arg1 type; +}; + +template +struct Replace<_2, Arg1, Arg2> { + typedef Arg2 type; +}; + +// Replacement through cv-qualifiers +template +struct Replace { + typedef typename Replace::type const type; +}; + +// Replacement of templates +template class TT, typename T1, typename Arg1, typename Arg2> +struct Replace, Arg1, Arg2> { + typedef TT::type> type; +}; + +template class TT, typename T1, typename T2, + typename Arg1, typename Arg2> +struct Replace, Arg1, Arg2> { + typedef TT::type, + typename Replace::type> type; +}; + +// Just for kicks... +template class TT, typename T1, + typename Arg1, typename Arg2> +struct Replace, Arg1, Arg2> { + typedef TT::type, Arg2> type; +}; + +int array0[is_same::type, int>::value? 1 : -1]; +int array1[is_same::type, const int>::value? 1 : -1]; +int array2[is_same, int, float>::type, vector >::value? 1 : -1]; +int array3[is_same, int, float>::type, vector >::value? 1 : -1]; +int array4[is_same, double, float>::type, vector >::value? 1 : -1]; + +// PR5911 +template 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 struct X { + template X(const X& u); + }; + struct A; + void f(A& a); + void f(const X& a); + void test(A& a) { (void)f(a); } +} + +// PR7463 +namespace PR7463 { + const int f (); + template void g (T_&); // expected-note{{T_ = int}} + void h (void) { g(f()); } // expected-error{{no matching function for call}} +} + +namespace test0 { + template 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 void foo(const T a[3][3]); + void test() { + int a[3][3]; + foo(a); + } +} + +// PR7708 +namespace test2 { + template struct Const { typedef void const type; }; + + template void f(T, typename Const::type*); + template void f(T, void const *); + + void test() { + void *p = 0; + f(0, p); + } +} + +// rdar://problem/8537391 +namespace test3 { + struct Foo { + template static inline void foo(); + }; + + class Bar { + template static inline void wobble(T ch); + + public: + static void madness() { + Foo::foo >(); + } + }; +} + +// Verify that we can deduce enum-typed arguments correctly. +namespace test14 { + enum E { E0, E1 }; + template struct A {}; + template void foo(const A &a) {} + + void test() { + A 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 +void f0(); + +template +void f0(); + +void g0() { + f0(); // okay! +} + +template +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 struct X; // expected-note{{template is declared here}} + +X *x1; +X *x2; + +X<> *x3; // expected-error{{too few template arguments for class template 'X'}} + +template struct X; + +X<> *x4; + +template struct Z { }; +template struct Z<>; + +// PR4362 +template struct a { }; +template<> struct a { static const bool v = true; }; + +template::v> struct p { }; // expected-error {{no member named 'v'}} + +template struct p; // expected-note {{in instantiation of default argument for 'p' required here}} +template struct p; + +// PR5187 +template +struct A; + +template +struct A; + +template +struct A { + void f(A); +}; + +template +struct B { }; + +template<> +struct B { + typedef B type; +}; + +// Nested default arguments for template parameters. +template struct X1 { }; + +template +struct X2 { + template::type> // expected-error{{no type named}} + struct Inner1 { }; + + template::value> // expected-error{{no member named 'value'}} + struct NonType1 { }; + + template + struct Inner2 { }; + + template + struct Inner3 { + template + struct VeryInner { }; + + template + struct NonType2 { }; + }; +}; + +X2 x2i; +X2::Inner1 x2iif; + +X2::Inner1<> x2bad; // expected-note{{instantiation of default argument}} + +X2::NonType1<'a'> x2_nontype1; +X2::NonType1<> x2_nontype1_bad; // expected-note{{instantiation of default argument}} + +// Check multi-level substitution into template type arguments +X2::Inner3::VeryInner<> vi; +X2::Inner3::NonType2<> x2_deep_nontype; + +template +struct is_same { static const bool value = false; }; + +template +struct is_same { static const bool value = true; }; + +int array1[is_same<__typeof__(vi), + X2::Inner3::VeryInner >::value? 1 : -1]; + +int array2[is_same<__typeof(x2_deep_nontype), + X2::Inner3::NonType2 >::value? 1 : -1]; + +// Template template parameter defaults +template class X = X2> struct X3 { }; +int array3[is_same, X3 >::value? 1 : -1]; + +struct add_pointer { + template + struct apply { + typedef T* type; + }; +}; + +template class X = T::template apply> + struct X4; +int array4[is_same, + X4 >::value? 1 : -1]; + +template struct X5 {}; // expected-note{{has a different type 'int'}} +template struct X5b {}; +template class B = X5> // expected-error{{template template argument has different}} \ + // expected-note{{previous non-type template parameter}} + struct X6 {}; + +X6 x6a; +X6 x6b; // expected-note{{while checking a default template argument}} +X6 x6c; + + +template class X = B > struct X7; // expected-error{{must be a class template}} + +namespace PR9643 { + template class allocator {}; + template > class vector {}; + + template > class container, + typename DT> + container
initializer(const DT& d) { + return container
(); + } + + void f() { + vector > v = initializer(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 bar { + public: enum { kSomeConst = 128 }; + bar(int x = kSomeConst) {} + }; + + // CHECK: void f() + void f() { + // CHECK: bar tmp = + // CHECK: CXXDefaultArgExpr{{.*}}'int' + bar 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 +class C { C(int a0 = 0); }; + +template<> +C::C(int a0); + +struct S { }; // expected-note 3 {{candidate constructor (the implicit copy constructor)}} + +template void f1(T a, T b = 10) { } // expected-error{{no viable conversion}} \ +// expected-note{{passing argument to parameter 'b' here}} + +template void f2(T a, T b = T()) { } + +template 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' required here}} + + f2(10); + f2(S()); + + f3(10); + f3(S()); // expected-note{{in instantiation of default function argument expression for 'f3' required here}} +} + +template 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 { }; + +void g2() { + F f; + FD fd; +} + +void g3(F f, F s) { + f.f(); + s.f(); // expected-note{{in instantiation of default function argument expression for 'f' required here}} + + F f2; + F s2; // expected-note{{in instantiation of default function argument expression for 'F' required here}} +} + +template struct G { + G(T) {} +}; + +void s(G flags = 10) { } + +// Test default arguments +template +struct X0 { + void f(T = T()); // expected-error{{no matching}} +}; + +template +void X0::f(U) { } + +void test_x0(X0 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 xn) { + xn.f(NotDefaultConstructible(17)); + xn.f(42); + xn.f(); // expected-note{{in instantiation of default function argument}} +} + +template +struct X1 { + typedef T value_type; + X1(const value_type& value = value_type()); +}; + +void test_X1() { + X1 x1; +} + +template +struct X2 { + void operator()(T = T()); // expected-error{{no matching}} +}; + +void test_x2(X2 x2i, X2 x2n) { + x2i(); + x2i(17); + x2n(NotDefaultConstructible(17)); + x2n(); // expected-note{{in instantiation of default function argument}} +} + +// PR5283 +namespace PR5283 { +template 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 { + B(); +}; +B::B() { } // expected-note {{in instantiation of default function argument expression for 'A' required he}} + +struct C : virtual A { + C(); +}; +C::C() { } // expected-note {{in instantiation of default function argument expression for 'A' required he}} + +struct D { + D(); + + A a; +}; +D::D() { } // expected-note {{in instantiation of default function argument expression for 'A' required he}} +} + +// PR5301 +namespace pr5301 { + void f(int, int = 0); + + template + void g(T, T = 0); + + template + void i(int a = I); + + template + void h(T t) { + f(0); + g(1); + g(t); + i<2>(); + } + + void test() { + h(0); + } +} + +// PR5810 +namespace PR5810 { + template + struct allocator { + allocator() { int a[sizeof(T) ? -1 : -1]; } // expected-error2 {{array with a negative size}} + }; + + template + struct vector { + vector(const allocator& = allocator()) {} // expected-note2 {{instantiation of}} + }; + + struct A { }; + struct B { }; + + template + void FilterVTs() { + vector Result; + } + + void f() { + vector Result; + } + + template + struct X { + vector bs; + X() { } + }; + + void f2() { + X x; // expected-note{{member function}} + } +} + +template void f4(T, int = 17); +template<> void f4(int, int); + +void f4_test(int i) { + f4(i); +} + +// Instantiate for initialization +namespace InstForInit { + template + struct Ptr { + typedef T* type; + Ptr(type); + }; + + template + struct Holder { + Holder(int i, Ptr ptr = 0); + }; + + void test_holder(int i) { + Holder h(i); + } +}; + +namespace PR5810b { + template + T broken() { + T t; + double**** not_it = t; + } + + void f(int = broken()); + void g() { f(17); } +} + +namespace PR5810c { + template + 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 { // 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 = 0 ); + }; +} + +namespace rdar8427926 { + template + struct Boom { + ~Boom() { + T t; + double *******ptr = t; // expected-error 2{{cannot initialize}} + } + }; + + Boom *bfp; + + struct X { + void f(Boom = Boom()) { } // 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 + struct A { + A() { T* x = 1; } // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} + }; + + template + struct B { + B(const A& a = A()); // expected-note{{in instantiation of}} + }; + + void f(B b = B()); + + 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 + 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 + 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 +struct X0 : T::template apply { + X0(U u) : T::template apply(u) { } +}; + +template +struct X1 : T::apply { }; // expected-error{{use 'template' keyword to treat 'apply' as a dependent template name}} + +template +struct X2 : vector { }; // expected-error{{unknown template name 'vector'}} + +namespace PR6031 { + template + struct A; + + template + struct C { }; + + template + struct II { + typedef typename A::type type; + }; + + template + struct FI : II + { + C a; + }; + + template + struct FI2 + { + C a; // expected-error{{no type named 'type' in 'FI2'}} \ + // expected-error{{C++ requires a type specifier for all declarations}} + }; + + template + struct Base { + class Nested { }; + template struct MemberTemplate { }; + int a; + }; + + template + struct HasDepBase : Base { + int foo() { + class HasDepBase::Nested nested; + typedef typename HasDepBase::template MemberTemplate::type type; + return HasDepBase::a; + } + }; + + template + struct NoDepBase { + int foo() { + class NoDepBase::Nested nested; // expected-error{{no class named 'Nested' in 'NoDepBase'}} + typedef typename NoDepBase::template MemberTemplate::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'}} + } + }; +} + +namespace Ambig { + template + 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 + struct Derived : Base1, 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 di; // expected-note{{instantiation of}} +} + +namespace PR6081 { + template + struct A { }; + + template + class B : public A + { + public: + template< class X > + void f0(const X & k) + { + this->template f1()(k); + } + }; + + template + class C + { + public: + template< class X > + void f0(const X & k) + { + this->template f1()(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 class Base_A { }; + + class Base_B { }; + + template + class Derived + : public virtual Base_A + , public virtual Base_B + { }; +} + +namespace PR5812 { + template struct Base { + Base* p; + }; + + template struct Derived: public Base { + typename Derived::Base* p; // meaning Derived::Base + }; + + Derived 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 struct X {}; +template struct Y : public X::X { }; + +// PR4621 +class A1 { + A1(int x) {} +}; +template class B1 : public A1 { + B1(C x) : A1(x.x) {} +}; +class A2 { A2(int x, int y); }; +template class B2 { + A2 x; + B2(C x) : x(x.x, x.y) {} +}; +template class B3 { + C x; + B3() : x(1,2) {} +}; + +// PR4627 +template class insert_iterator { + _Container* container; + insert_iterator(_Container& __x) : container(&__x) {} +}; + +// PR4763 +template struct s0 {}; +template struct s0_traits {}; +template struct s1 : s0::t0> { + s1() {} +}; + +// PR6062 +namespace PR6062 { + template + class A : public T::type + { + A() : T::type() + { + } + + template + A(U const& init) + : T::type(init) + { } + + template + A(U& init) : U::other_type(init) { } + }; +} + +template +struct X0 : T::template apply { + X0(int i) : T::template apply(i) { } +}; + +// PR7698 +namespace PR7698 { + template + 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 struct C1 { void operator()(T); }; +template struct C2; // expected-note {{template is declared here}} +template void foo(T); +void wrap() { + foo(&C1::operator()); + foo(&C1::operator+); // expected-error {{no member named 'operator+' in 'C1'}} + foo(&C2::operator+); // expected-error {{implicit instantiation of undefined template 'C2'}} +} 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 +void Test(Iterator it) { + *(it += 1); +} + +namespace PR6045 { + template + class A + { + static const unsigned int member = r; + void f(); + }; + + template + const unsigned int A::member; + + template + void A::f() + { + unsigned k; + (void)(k % member); + } +} + +namespace PR7198 { + struct A + { + ~A() { } + }; + + template + struct B { + struct C : A {}; + void f() + { + C c = C(); + } + }; +} + +namespace PR7724 { + template int myMethod() + { return 2 && sizeof(OT); } +} + +namespace test4 { + template T *addressof(T &v) { + return reinterpret_cast( + &const_cast(reinterpret_cast(v))); + } +} + +namespace test5 { + template class chained_map { + int k; + void lookup() const { + int &v = (int &)k; + } + }; +} + +namespace PR8795 { + template 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 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 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 class B { + typedef int A; +}; + +template struct X : B { + static A a; +}; + +int a0[sizeof(X::a) == sizeof(double) ? 1 : -1]; + +// PR4365. +template class Q; +template class R : Q {T current;}; + + +namespace test0 { + template class Base { + public: + void instance_foo(); + static void static_foo(); + class Inner { + public: + void instance_foo(); + static void static_foo(); + }; + }; + + template class Derived1 : Base { + public: + void test0() { + Base::static_foo(); + Base::instance_foo(); + } + + void test1() { + Base::Inner::static_foo(); + Base::Inner::instance_foo(); // expected-error {{call to non-static member function without an object argument}} + } + + static void test2() { + Base::static_foo(); + Base::instance_foo(); // expected-error {{call to non-static member function without an object argument}} + } + + static void test3() { + Base::Inner::static_foo(); + Base::Inner::instance_foo(); // expected-error {{call to non-static member function without an object argument}} + } + }; + + template class Derived2 : Base::Inner { + public: + void test0() { + Base::static_foo(); + Base::instance_foo(); // expected-error {{call to non-static member function without an object argument}} + } + + void test1() { + Base::Inner::static_foo(); + Base::Inner::instance_foo(); + } + + static void test2() { + Base::static_foo(); + Base::instance_foo(); // expected-error {{call to non-static member function without an object argument}} + } + + static void test3() { + Base::Inner::static_foo(); + Base::Inner::instance_foo(); // expected-error {{call to non-static member function without an object argument}} + } + }; + + void test0() { + Derived1 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 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 struct Base { + void foo(T); // expected-note {{must qualify identifier to find this declaration in dependent base class}} + }; + + template struct Derived : Base { + void doFoo(T v) { + foo(v); // expected-error {{use of undeclared identifier}} + } + }; + + template struct Derived; // expected-note {{requested here}} +} + +namespace PR8966 { + template + class MyClassCore + { + }; + + template + class MyClass : public MyClassCore + { + public: + enum { + N + }; + + // static member declaration + static const char* array [N]; + + void f() { + MyClass::InBase = 17; + } + }; + + // static member definition + template + const char* MyClass::array [MyClass::N] = { "A", "B", "C" }; +} + +namespace std { + inline namespace v1 { + template struct basic_ostream; + } + namespace inner { + template struct vector {}; + } + using inner::vector; + template struct pair {}; + typedef basic_ostream ostream; + extern ostream cout; + std::ostream &operator<<(std::ostream &out, const char *); +} + +namespace PR10053 { + template 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 a; // expected-note {{in instantiation of member function}} + + + namespace N { + namespace M { + template 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(0);; // expected-note {{in instantiation of function}} + + + namespace O { + void f(char&); // expected-note {{candidate function not viable}} + + template struct C { + static const int n = f(T()); // expected-error {{no matching function}} + }; + } + + int f(double); // no note, shadowed by O::f + O::C c; // expected-note {{requested here}} + + + // Example from www/compatibility.html + namespace my_file { + template 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 + 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 + 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); // 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); // 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()); // expected-note {{requested here}} + Dump(std::pair()); // expected-note {{requested here}} + } + } + + namespace unary { + template + 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 + struct S { + void f() { + for (auto &a : e) + __range(a); // expected-error {{undeclared identifier '__range'}} + } + int e[10]; + }; + void g() { + S().f(); // expected-note {{here}} + } + } + + namespace B { + template void g(); // expected-note {{not viable}} + template void f() { + g(T()); // expected-error {{no matching function}} + } + + namespace { + struct S {}; + } + void g(S); + + template void f(); // expected-note {{here}} + } +} + +namespace rdar11242625 { + +template +struct Main { + struct default_names { + typedef int id; + }; + + template + struct TS { + T2 q; + }; +}; + +struct Sub : public Main { + TS<> ff; +}; + +int arr[sizeof(Sub)]; + +} + +namespace PR11421 { +template < unsigned > struct X { + static const unsigned dimension = 3; + template + struct Y: Y { }; // 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 +void f() { + int a[] = { 1, 2, 3, N }; + unsigned numAs = sizeof(a) / sizeof(int); +} + +template void f<17>(); + + +template +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 +struct X { + void f(T* t) { + t->f0(); // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}} + t->f0(); // expected-error{{use 'template' keyword to treat 'f0' as a dependent template name}} + + t->operator+(); // expected-error{{use 'template' keyword to treat 'operator +' as a dependent template name}} + t->f1(); // expected-error{{use 'template' keyword to treat 'f1' as a dependent template name}} + + T::getAs(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}} + t->T::getAs(); // expected-error{{use 'template' keyword to treat 'getAs' as a dependent template name}} + + // FIXME: We can't recover from these yet + (*t).f2(); // expected-error{{expected expression}} + (*t).f2<0>(); // expected-error{{expected expression}} + } +}; + +namespace PR9401 { + // From GCC PR c++/45558 + template + struct C + { + template + struct B + { + template + struct E + { + explicit E(const W &x) : w(x) {} + const W &w; + }; + }; + }; + + struct F; + template + struct D + { + D() {} + }; + + const D g; + template + struct A + { + template + struct B : C::template B + { + typedef typename C::template B V; + static const D > > a; + }; + }; + + template + template + const D::template B::template E > > + A::B::a = typename C::template B::template E >(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 + struct X2 { + template + struct apply { + typedef U* type; + }; + }; +} + +namespace Nalias = N; + +template +struct X0 { }; + +using namespace N; + +template +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*); // expected-note{{previous}} + void f2(X0*); + void f2(X0*); // expected-error{{redeclar}} + + void f3(X0*); // expected-note{{previous}} + void f3(X0*); + void f3(::X0*); // expected-error{{redeclar}} + + void f4(typename T::template apply*); // expected-note{{previous}} + void f4(typename U::template apply*); + void f4(typename type::template apply*); + void f4(typename type::template apply*); // expected-error{{redeclar}} + + void f5(typename T::template apply::type*); // expected-note{{previous}} + void f5(typename U::template apply::type*); + void f5(typename U::template apply::type*); + void f5(typename type::template apply::type*); + void f5(typename type::template apply::type*); // expected-error{{redeclar}} + + void f6(typename N::X2::template apply *); // expected-note{{previous}} + void f6(typename N::X2::template apply *); + void f6(typename N::X2::template apply *); + void f6(typename ::N::X2::template apply *); // expected-error{{redeclar}} + + void f7(typename N::X2::template apply *); // expected-note{{previous}} + void f7(typename N::X2::template apply *); + void f7(typename N::X2::template apply *); + void f7(typename X2::template apply *); // expected-error{{redeclar}} + + void f8(typename N::X2::template apply *); // expected-note{{previous}} + void f8(typename N::X2::template apply *); + void f8(typename N::X2::template apply *); + void f8(typename ::Nalias::X2::template apply *); // expected-error{{redeclar}} +}; + +namespace PR6851 { + template + struct S; + + struct N { + template + S< S::cond && 1 > foo(); + }; + + struct Alien; + bool operator&&(const Alien&, const Alien&); + + template + S< S::cond && 1 > N::foo() { } +} + +namespace PR7460 { + template + struct TemplateClass2 + { + enum { SIZE = 100 }; + static T member[SIZE]; + }; + + template + T TemplateClass2::member[TemplateClass2::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 class s0 { + + template class s1 : public s0 { + ~s1() {} + s0 ms0; + }; + +}; + +struct Incomplete; + +template +void destroy_me(T me) { + me.~T(); +} + +template void destroy_me(Incomplete*); + +namespace PR6152 { + template struct X { void f(); }; + template struct Y { }; + template + void X::f() { + Y *y; + y->template Y::~Y(); + y->template Y::~Y(); + y->~Y(); + } + + template struct X; +} + +namespace cvquals { + template + void f(int *ptr) { + ptr->~T(); + } + + template void f(int *); +} + +namespace PR7239 { + template class A { }; + class B { + void f() { + A* x; + x->A::~A(); + } + }; +} + +namespace PR7904 { + struct Foo { + template ~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 + 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; + template class D; // expected-note{{in instantiation of}} + template class D; // expected-note{{in instantiation of}} +} + +template +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 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 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 struct C { + typedef C Self; +}; +template struct C; + +template +struct get_size { + static const unsigned value = sizeof(T); +}; + +template +struct X0 { + enum { + Val1 = get_size::value, + Val2, + SumOfValues = Val1 + Val2 + }; +}; + +X0 x0i; + +namespace rdar8020920 { + template + 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 +struct X { + enum E *e; +}; + +X 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 +#include +#include + +// Placement new requires 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 +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 +void dynarray::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 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::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 di2 = di; + assert(di2.size() == 5); + assert(di.begin() != di2.begin()); + for (dynarray::iterator I = di2.begin(), IEnd = di2.end(); + I != IEnd; ++I) + assert(*I == I - di2.begin()); + + dynarray di3(di); + assert(di3.size() == 5); + assert(di.begin() != di3.begin()); + for (dynarray::iterator I = di3.begin(), IEnd = di3.end(); + I != IEnd; ++I) + assert(*I == I - di3.begin()); + + dynarray di4; + assert(di4.size() == 0); + di4 = di; + assert(di4.size() == 5); + assert(di.begin() != di4.begin()); + for (dynarray::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 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 +struct cons { + typedef Head head; + typedef Tail tail; +}; + +// is_same trait, for testing +template +struct is_same { + static const bool value = false; +}; + +template +struct is_same { + static const bool value = true; +}; + +// metaprogram that computes the length of a list +template struct length; + +template +struct length > { + static const unsigned value = length::value + 1; +}; + +template<> +struct length { + static const unsigned value = 0; +}; + +typedef cons > > > unsigned_inttypes; +int length0[length::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 +class reverse { + typedef typename reverse::type reversed_tail; + + typedef typename reverse::type most_of_tail; + +public: + typedef cons >::type> type; +}; + +template +class reverse > { +public: + typedef cons type; +}; + +template<> +class reverse { +public: + typedef nil type; +}; + +int reverse0[is_same::type, + cons > > > >::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 +struct find : find { }; + +template +struct find, T> { + typedef cons type; +}; + +template +struct find { + typedef nil type; +}; + +int find0[is_same::type, + cons > >::value? + 1 : -1]; +int find1[is_same::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 +struct X0 { + static T value; + + T f0(T x) { + return x + 1; // expected-error{{invalid operands}} + } + T* f0(T*, T*) { return T(); } + + template + T f0(T, U) { return T(); } +}; + +template +T X0::value; // expected-error{{no matching constructor}} + +template int X0::value; + +struct NotDefaultConstructible { // expected-note{{candidate constructor (the implicit copy constructor)}} + NotDefaultConstructible(int); // expected-note{{candidate constructor}} +}; + +template NotDefaultConstructible X0::value; // expected-note{{instantiation}} + +template int X0::f0(int); +template int* X0::f0(int*, int*); +template int X0::f0(int, float); + +template int X0::f0(int) const; // expected-error{{does not refer}} +template int* X0::f0(int*, float*); // expected-error{{does not refer}} + +struct X1 { }; +typedef int X1::*MemPtr; + +template MemPtr X0::f0(MemPtr); // expected-note{{requested here}} + +struct X2 { + int f0(int); // expected-note{{refers here}} + + template T f1(T) { return T(); } + template T* f1(T*) { return 0; } + + template void f2(T, U*) { } // expected-note{{candidate}} + template 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 void print_type() { } + +template void print_type(); +template void print_type(); + +template void print_type(T*) { } + +template void print_type(int*); +template void print_type(float*); // expected-error{{does not refer}} + +void print_type(double*); +template void print_type(double*); + +// PR5069 +template void foo0 (int (&)[I + 1]) { } +template void foo0<2> (int (&)[3]); + +namespace explicit_instantiation_after_implicit_instantiation { + template struct X0 { static int x; }; + template int X0::x; + void test1() { (void)&X0<1>::x; } + template struct X0<1>; +} + +template struct X3 { }; +inline template struct X3; // expected-warning{{ignoring 'inline' keyword on explicit template instantiation}} +static template struct X3; // expected-warning{{ignoring 'static' keyword on explicit template instantiation}} + +namespace PR7622 { + template + struct basic_streambuf; + + template + struct basic_streambuf{friend bob<>()}; // expected-error{{unknown type name 'bob'}} \ + // expected-error{{expected member name or ';' after declaration specifiers}} + template struct basic_streambuf; +} + +// 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 +struct X0 { + typedef T* type; + + void f0(T); + void f1(type); +}; + +template<> void X0::f0(char); +template<> void X0::f1(type); + +namespace PR6161 { + template + 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::~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 +struct make1 { + typedef T __attribute__((ext_vector_type(Length))) type; +}; + +void test_make1() { + make1::type x; + x.x = 4; +} + +template +struct make2 { + typedef T __attribute__((ext_vector_type(Length))) type; // expected-error{{zero vector size}} +}; + +int test_make2() { + make2 x; // expected-note{{in instantiation of}} +} + +template +struct make3 { + typedef T __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector element type 's'}} +}; + +struct s {}; + +int test_make3() { + make3x; // expected-note{{in instantiation of}} +} + +template +struct make4 { + typedef T __attribute__((ext_vector_type(Length))) type; +}; + +int test_make4() { + make4::type x; + x.w = 7; +} + +typedef int* int_ptr; +template +struct make5 { + typedef int_ptr __attribute__((ext_vector_type(Length))) type; // expected-error{{invalid vector element type}} +}; + +template +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 struct X0; + + template + struct X0 { + static const unsigned value = 0; + }; + + template + struct X0 { + static const unsigned value = 1; + }; + + template + struct X0 { + static const unsigned value = 2; + }; + + template<> + struct X0 { + 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::value == 0? 1 : -1]; + int array1[X0::value == 1? 1 : -1]; + int array2[X0::value == 2? 1 : -1]; + int array3[X0::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 +class X0 { +public: + void f(T t); + + struct Inner { + void g(T t); + }; +}; + +template +void X0::f(T t) { + t = 17; // expected-error{{incompatible}} +} + +extern template class X0; + +extern template class X0; + +template +void X0::Inner::g(T t) { + t = 17; // expected-error{{incompatible}} +} + +void test_intptr(X0 xi, X0::Inner xii) { + xi.f(0); + xii.g(0); +} + +extern template class X0; + +void test_longptr(X0 xl, X0::Inner xli) { + xl.f(0); + xli.g(0); +} + +template class X0; // expected-note 2{{instantiation}} + +template +class X1 { +public: + void f(T t) { t += 2; } + + void g(T t); +}; + +template +void X1::g(T t) { + t += 2; +} + +extern template class X1; + +void g_X1(X1 x1, void *ptr) { + x1.g(ptr); +} + +extern template void X1::g(const void*); + +void g_X1_2(X1 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 +struct FibonacciEval; + +template +struct Fibonacci { + enum { value = FibonacciEval::value + FibonacciEval::value }; +}; + +template +struct FibonacciEval { + enum { value = Fibonacci::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 +struct FibonacciEval2; + +template +struct Fibonacci2 { + static const unsigned value + = FibonacciEval2::value + FibonacciEval2::value; +}; + +template +struct FibonacciEval2 { + static const unsigned value = Fibonacci2::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 +struct Fibonacci3 { + static const unsigned value = Fibonacci3::value + Fibonacci3::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 friend struct Y; + }; + } + + namespace std { + template struct Y {}; + } +} + +namespace test1 { + template void f1(T) { } // expected-note{{here}} + + class X { + template friend void f0(T); + template friend void f1(T); + }; + + template void f0(T) { } + template void f1(T) { } // expected-error{{redefinition}} +} + +// PR4768 +namespace test2 { + template struct X0 { + template friend struct X0; + }; + + template struct X0 { + template friend struct X0; + }; + + template<> struct X0 { + template friend struct X0; + }; + + template struct X1 { + template friend void f2(U); + template friend void f3(U); + }; + + template void f2(U); + + X1 x1i; + X0 x0ip; + + template<> void f2(int); + + // FIXME: Should this declaration of f3 be required for the specialization of + // f3 (further below) to work? GCC and EDG don't require it, we do... + template void f3(U); + + template<> void f3(int); +} + +// PR5332 +namespace test3 { + template class Foo { + template + friend class Foo; + }; + + Foo foo; + + template struct X2a; + + template struct X2b; + + template + class X3 { + template friend struct X2a; + + // FIXME: the redeclaration note ends up here because redeclaration + // lookup ends up finding the friend target from X3. + template 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 x3i; // okay + + X3 x3l; // expected-note {{in instantiation}} +} + +// PR5716 +namespace test4 { + template struct A { + template friend void f(const A&); + }; + + template void f(const A&) { + int a[sizeof(T) ? -1 : -1]; // expected-error {{array with a negative size}} + } + + void f() { + f(A()); // expected-note {{in instantiation of function template specialization}} + } +} + +namespace test5 { + class outer { + class foo; + template friend struct cache; + }; + class outer::foo { + template friend struct cache; + }; +} + +// PR6022 +namespace PR6022 { + template class A; + + namespace inner { + template + A& f0(A&, T); + } + + template + class A { + template + friend A& inner::f0(A&, T); + }; +} + +namespace FriendTemplateDefinition { + template struct int_c { }; + + template + struct X { + template + friend void f(X, int_c) { + int value = N; + }; + }; + + void test_X(X x, int_c<5> i5) { + f(x, i5); + } +} + +namespace PR7013a { + template struct X0 + { + typedef int type; + }; + template struct X1 + { + }; + template struct X2 + { + typename T::type e; + }; + namespace N + { + template > struct X3 + { + template friend void op(X2& , B); + }; + template void op(X2& , B) + { + X2 s; + } + } + int n() + { + X2 > ngs; + N::X3<> b; + op(ngs, b); + return 0; + } +} + +namespace PR7013b { + template struct X0 + { + typedef int type; + }; + template struct X1 + { + }; + template struct X2 + { + typename T::type e; + }; + namespace N + { + template > struct X3 + { + template friend void op(X2& , B); + }; + template void op(X2& , B) + { + X2 s; + } + } + int n() + { + X2 > ngs; + N::X3<> b; + op(ngs, b); + return 0; + } + +} + +namespace PR8649 { + template + struct X { + template friend class X; // expected-error{{partial specialization cannot be declared as a friend}} + }; + + X x; +} + +// Don't crash, and error on invalid friend type template. +namespace friend_type_template_no_tag { + template struct S { + template friend S; // expected-error{{friend type templates must use an elaborated type}} + }; + template struct S; +} + +namespace PR10660 { + struct A { + template <> friend class B; // expected-error{{extraneous 'template<>' in declaration of class 'B'}} + }; +} + +namespace rdar11147355 { + template + struct A { + template class B; + template template friend class A::B; + }; + + template template class A::B { + }; + + A::B 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 struct A { + struct B { }; + + friend struct B; +}; + +void f() { + A::B b; +} + +struct C0 { + friend struct A; +}; + +namespace PR6770 { + namespace N { + int f1(int); + } + using namespace N; + + namespace M { + float f1(float); + } + using M::f1; + + template void f1(T, T); + template + 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 + +// Fake typeid, lacking a typeinfo header. +namespace std { class type_info {}; } + +struct dummy {}; // expected-note 3 {{candidate constructor (the implicit copy constructor)}} + +template +int f0(T x) { + return (sizeof(x) == sizeof(int))? 0 : (sizeof(x) == sizeof(double))? 1 : 2; +} + +template +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(static_cast(reinterpret_cast( + dynamic_cast(const_cast(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 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 void f1(T (&array)[N]); // expected-note{{matches}} +template 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 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 void f2(double (&array)[N]); +template void f2(T (&array)[42]); + +template<> void f2(double (&array)[42]); +template<> void f2<42>(double (&array)[42]); + +void f2<25>(double (&array)[25]); // expected-error{{specialization}} + +// PR5833 +namespace PR5833 { + template bool f0(T &t1); + template <> bool f0(float &t1); +} +template <> bool PR5833::f0(float &t1) {} + +// PR8295 +namespace PR8295 { + template void f(T t) {} + template void f(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 +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 *xii, X *xpi, X *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 +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 +struct Streamer; + +typedef struct Foo {} Foo; + +std_ostream& operator << (std_ostream&, const Streamer&); + +void test(const Streamer& foo) +{ + cout << foo; +} + +template +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&); +#endif + +#ifdef INSTANTIATE +template struct Streamer; +#endif + +#ifdef REDEFINE +std_ostream& operator << (std_ostream& o, const Streamer&) // expected-note{{is here}} +{ + return o; +} +#endif + +#ifndef INSTANTIATE +template <> +void Streamer::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 +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&); +#ifdef REDEFINE +std_ostream& operator << (std_ostream& o, const Streamer&) // expected-note{{is here}} +{ + // Sema should flag this as a redefinition + return o; +} +#endif + +template <> +void Streamer::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 +struct X { + X *ptr; +}; + +X x; + +template<> +struct X { + typedef X *ptr; +}; + +X::X 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 +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&); // expected-error{{redecl}} + + void f1(const X0&); // expected-note{{here}} + void f1(X0&); + void f1(const X0&); // expected-error{{redecl}} + + void f2(const X0&); // expected-note{{here}} + void f2(X0&); + void f2(const ::X0&); // expected-error{{redecl}} +}; + +template +struct X1 { + void f0(const X1&); // expected-note{{here}} + void f0(X1&); + void f0(const X1&); // expected-error{{redecl}} +}; + +namespace pr6326 { + template class A { + friend class A; + }; + template class A; +} + +namespace ForwardDecls { + template + struct X; + + template + struct X { + typedef T foo; + typedef X 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 class A { struct { }; }; + +A a0; + +template struct B { + union { + int a; + void* b; + }; + + void f() { + a = 10; + b = 0; + } +}; + +B b0; + +template struct C { + union { + int a; + void* b; + }; + + C(int a) : a(a) { } + C(void* b) : b(b) { } +}; + +C c0(0); + +namespace PR7088 { + template + void f() { + union { + int a; + union { + float real; + T d; + }; + }; + + a = 17; + d = 3.14; + } + + template void f(); +} + +// 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 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 + int f() { + return this->X0::member + PR9188::global; + } + }; + + template int X1::f(); +} 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 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 class TenElementArray { + int elems[10]; +}; + +static_assert(sizeof(TenElementArray) == sizeof(int) * 10, "Array size mismatch"); + +template class Array { + T elems[N]; +}; + +static_assert(sizeof(Array) == 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 +struct A { + char a __attribute__((aligned(16))); + + struct B { + typedef T __attribute__((aligned(16))) i16; + i16 x; + }; +}; +int a[sizeof(A) == 16 ? 1 : -1]; +int a2[sizeof(A::B) == 16 ? 1 : -1]; + +// rdar://problem/8243419 +namespace test1 { + template struct A { + int a; + T b[0]; + } __attribute__((packed)); + + typedef A 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 +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; + +struct Point3D { + float x, y, z; +}; + +template struct DesigInit0; + +struct Color { + unsigned char red, green, blue; +}; + +struct ColorPoint3D { + Color color; + float x, y, z; +}; + +template struct DesigInit0; +template struct DesigInit0; // expected-note{{instantiation}} + +template +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; +template struct DesigArrayInit0; // expected-note{{instantiation}} + +template +struct DesigArrayRangeInit0 { + void f(Val1 val1) { + T array = { + [Subscript1...Subscript2] = val1 // expected-error{{exceeds}} + }; + } +}; + +template struct DesigArrayRangeInit0; +template struct DesigArrayRangeInit0; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// Compound literals +// --------------------------------------------------------------------- +template +struct CompoundLiteral0 { + T f(Arg1 a1, Arg2 a2) { + return (T){a1, a2}; + } +}; + +template struct CompoundLiteral0; 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 + struct call_f0 { + void test_f0(T t) { + Result result = f0(t); + } + }; +} + +template struct N2::call_f0; +template struct N2::call_f0; + +namespace N3 { + template + 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; // expected-note{{instantiation}} +template struct N3::call_f0; + +short& f0(char); // expected-note {{should be declared prior to the call site}} +namespace N4 { + template + struct call_f0 { + void test_f0(T t) { + Result &result = f0(t); + } + }; +} + +template struct N4::call_f0; +template struct N4::call_f0; +template struct N3::call_f0; // 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 +static int alpha(T c) +{ + return *c; // expected-error{{indirection requires pointer operand}} +} + +template +static void +_shexp_match() +{ + switch(1) { + case 1: + alpha(1); // expected-note{{instantiation of function template}} + } +} +int main() { + _shexp_match(); // 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 +struct CStyleCast0 { + void f(T t) { + (void)((U)t); // expected-error{{cannot convert 'A' to 'int' without a conversion operator}} + } +}; + +template struct CStyleCast0; +template struct CStyleCast0; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// static_cast +// --------------------------------------------------------------------- +template +struct StaticCast0 { + void f(T t) { + (void)static_cast(t); // expected-error{{no matching conversion for static_cast from 'int' to 'A'}} + } +}; + +template struct StaticCast0; +template struct StaticCast0; +template struct StaticCast0; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// dynamic_cast +// --------------------------------------------------------------------- +template +struct DynamicCast0 { + void f(T t) { + (void)dynamic_cast(t); // expected-error{{not a reference or pointer}} + } +}; + +template struct DynamicCast0; +template struct DynamicCast0; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// reinterpret_cast +// --------------------------------------------------------------------- +template +struct ReinterpretCast0 { + void f(T t) { + (void)reinterpret_cast(t); // expected-error{{qualifiers}} + } +}; + +template struct ReinterpretCast0; +template struct ReinterpretCast0; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// const_cast +// --------------------------------------------------------------------- +template +struct ConstCast0 { + void f(T t) { + (void)const_cast(t); // expected-error{{not allowed}} + } +}; + +template struct ConstCast0; +template struct ConstCast0; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// C++ functional cast +// --------------------------------------------------------------------- +template +struct FunctionalCast1 { + void f(T t) { + (void)U(t); // expected-error{{cannot convert 'A' to 'int' without a conversion operator}} + } +}; + +template struct FunctionalCast1; +template struct FunctionalCast1; // expected-note{{instantiation}} + +// Generates temporaries, which we cannot handle yet. +template +struct FunctionalCast2 { + void f() { + (void)Constructible(N, M); + } +}; + +template struct FunctionalCast2<1, 3>; + +// --------------------------------------------------------------------- +// implicit casting +// --------------------------------------------------------------------- +template +struct Derived2 : public Base { }; + +void test_derived_to_base(Base *&bp, Derived2 *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 +struct ExtVectorAccess0 { + void f(T v1, double4 v2) { + v1.xy = v2.yx; + } +}; + +template struct ExtVectorAccess0; +template struct ExtVectorAccess0; + +typedef __attribute__(( ext_vector_type(2) )) double double2; + +template +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; +template struct ShuffleVector0; // 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 +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 f() { return 0; } + +struct XField { + X xf; // expected-note{{in instantiation of template class 'X' requested here}} +}; + +void test_subscript(X *ptr1, X *ptr2, int i) { + (void)ptr1[i]; + (void)ptr2[i]; // expected-note{{in instantiation of template class 'X' requested here}} +} + +void test_arith(X *ptr1, X *ptr2, + X *ptr3, X *ptr4) { + (void)(ptr1 + 5); + (void)(5 + ptr2); + (void)(ptr3 + 5); // expected-note{{in instantiation of template class 'X' requested here}} + (void)(5 + ptr4); // expected-note{{in instantiation of template class 'X' requested here}} +} + +void test_new() { + (void)new X(0); + (void)new X; // expected-note{{in instantiation of template class 'X' requested here}} +} + +void test_memptr(X *p1, long X::*pm1, + X *p2, + long (X::*pm2)(long)) { + (void)(p1->*pm1); +} + +// Reference binding to a base +template +struct X1 { }; + +template +struct X2 : public T { }; + +void refbind_base(X2 > &x2) { + X1 &x1 = x2; +} + +// Enumerate constructors for user-defined conversion. +template +struct X3 { + X3(T); +}; + +void enum_constructors(X1 &x1) { + X3 > x3 = x1; +} + +namespace PR6376 { + template struct W { }; + + template + struct X { + template + struct apply { + typedef W type; + }; + }; + + template + struct Y : public X::template apply::type { }; + + template struct Y; +} + +namespace TemporaryObjectCopy { + // Make sure we instantiate classes when we create a temporary copy. + template + struct X { + X(T); + }; + + template + void f(T t) { + const X &x = X(t); + } + + template void f(int); +} + +namespace PR7080 { + template + 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 rv : public T + { }; + + bool x = X&>::value; +} + +namespace pr7199 { + template class A; // expected-note {{template is declared here}} + template class B { + class A::C field; // expected-error {{implicit instantiation of undefined template 'pr7199::A'}} + }; + + template class B; // expected-note {{in instantiation}} +} + +namespace PR8425 { + template + class BaseT {}; + + template + class DerivedT : public BaseT {}; + + template + class FromT { + public: + operator DerivedT() const { return DerivedT(); } + }; + + void test() { + FromT ft; + BaseT 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 struct A { + T x; + A(int y) { x = y; } + ~A() { *x = 10; } // expected-error {{indirection requires pointer operand}} +}; + +void a() { + A 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 +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 +void f0() { + X1 x1; +} + +template void f0(); +template void f0(); + +struct NonTrivial { + NonTrivial(); + ~NonTrivial(); +}; + +template 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 struct x { + static const int j = i; + x* y; +}; + +template +const int x::j; + +int array0[x<2>::j]; + +template +struct X0 { + static const unsigned value = sizeof(T); +}; + +template +const unsigned X0::value; + +int array1[X0::value == sizeof(int)? 1 : -1]; + +const unsigned& testX0() { return X0::value; } + +int array2[X0::value == sizeof(int)? 1 : -1]; + +template +struct X1 { + static const unsigned value; +}; + +template +const unsigned X1::value = sizeof(T); + +int array3[X1::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 + 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::VeryInner::Kind2 = K2Val; + Kind3 = K3Val; + } + + struct UeberInner { + void bar() { + K1 k1 = K1Val; + Kind1 = K1Val; + Outer::Inner::InnerTemplate::VeryInner::Kind2 = K2Val; + + InnerTemplate t; + InnerTemplate t2; + } + }; + }; + }; + }; + }; +} + +typedef int INT; +template struct N::Outer::Inner::InnerTemplate::VeryInner; +template struct N::Outer::Inner::InnerTemplate::UeberInner; // expected-error{{no struct named 'UeberInner' in 'N::Outer::Inner::InnerTemplate'}} + +namespace N2 { + struct Outer2 { + template + 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 i2; + i2.foo(); + } + }; + }; +} + +template struct N2::Outer2::Inner; +template struct N2::Outer2::Inner; // expected-note{{instantiation}} + +// Test dependent pointer-to-member expressions. +template +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 p) { + if (p) { } +} + +// PR5517 +namespace test0 { + template struct X { + X() { extern void x(); } + }; + void g() { X<2>(); } +} + +// +namespace test1 { + template 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 void f() { + T::error; // expected-error {{no member}} + } + void g() { + // This counts as an odr-use, so should trigger the instantiation of f. + (void)&f; // 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 struct A { + template struct B { + template struct C { + template struct D { + template 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::B::C::D::E global; + +// PR5352 +template +class Foo { +public: + Foo() {} + + struct Bar { + T value; + }; + + Bar u; +}; + +template class Foo; 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 struct PassRefPtr { }; +template struct RefPtr { + RefPtr& operator=(const RefPtr&) { int a[sizeof(T) ? -1 : -1];} // expected-error 2 {{array with a negative size}} + RefPtr& operator=(const PassRefPtr&); +}; + +struct A { RefPtr a; }; // expected-note {{instantiation of member function 'RefPtr::operator=' requested here}} +struct B : RefPtr { }; // expected-note {{in instantiation of member function 'RefPtr::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 struct X { static const T A = 1; }; +template::A> struct Y { typedef T A; }; +template struct Z { typedef typename Y::A A; }; +extern int x; +extern Z::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 struct Base { + struct foo {}; + int foo; +}; + +template struct Derived : Base { + typedef struct Base::foo type; +}; + +template struct Derived; 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 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 +struct adder { + enum { + value = I + J, + value2 + }; +}; + +int array1[adder::value == 7? 1 : -1]; + +namespace PR6375 { + template + void f() { + enum Enum + { + enumerator1 = 0xFFFFFFF, + enumerator2 = enumerator1 - 1 + }; + + int xb1 = enumerator1; + int xe1 = enumerator2; + } + + template void f(); +} 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 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 struct A { + template struct B { + static void f() noexcept(A().n); + }; + + constexpr A() : n(true) {} + bool n; +}; + +static_assert(noexcept(A::B::f()), ""); + +template struct S { + static void recurse() noexcept(noexcept(S::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 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' requested here}} +} + + +namespace dr1330_example { + template struct A { + void f(...) throw (typename T::X); // expected-error {{'int'}} + void f(int); + }; + + int main() { + A().f(42); + } + + int test2() { + struct S { + template + static int f() noexcept(noexcept(A().f("boo!"))) { return 0; } // \ + // expected-note {{instantiation of exception spec}} + typedef decltype(f()) X; + }; + S().f(); // ok + S().f(); // expected-note {{instantiation of exception spec}} + } +} + +namespace core_19754_example { + template T declval() noexcept; + + template()))> + struct is_movable { static const bool value = true; }; + + template + struct wrap { + T val; + void irrelevant(wrap &p) noexcept(is_movable::value); + }; + + template + struct base { + base() {} + base(const typename T::type1 &); + base(const typename T::type2 &); + }; + + template + struct type1 { + wrap base; + }; + + template + struct type2 { + wrap base; + }; + + struct types { + typedef base base; + typedef type1 type1; + typedef type2 type2; + }; + + base val = base(); +} + +namespace pr9485 { + template void f1(T) throw(typename T::exception); // expected-note {{candidate}} + template void f1(T, int = 0) throw(typename T::noitpecxe); // expected-note {{candidate}} + + template void f2(T) noexcept(T::throws); // expected-note {{candidate}} + template 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 struct Derived : Base { + void f() noexcept (sizeof(T) == 4); // expected-error {{is more lax}} + void g() noexcept (T::error); +}; + +Derived d1; // ok +Derived 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 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 +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 +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 +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 +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 +struct BitfieldDep { + int bitfield : I + J; +}; + +void test_BitfieldDep() { + (void)sizeof(BitfieldDep); +} + +template +struct BitfieldNeg { + int bitfield : (-I); // expected-error{{bit-field 'bitfield' has negative width (-5)}} +}; + +template +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); // okay + (void)sizeof(BitfieldNeg2); // expected-note{{in instantiation of template class 'BitfieldNeg2' requested here}} +} + +template +void increment(T &x) { + (void)++x; +} + +struct Incrementable { + Incrementable &operator++(); +}; + +void test_increment(Incrementable inc) { + increment(inc); +} + +template +void add(const T &x) { + (void)(x + x); +} + +namespace PR6237 { + template + 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 +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(call_op, i); + double &dr = test_call_operator(call_op, d); +} + +template +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' requested here}} +} + +namespace PR6424 { + template struct X { + X() { + int *ip = I; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} + } + }; + + template struct Y { + typedef X<7> X7; + + void f() { X7(); } // expected-note{{instantiation}} + }; + + template void Y<3>::f(); + + template + 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 struct Y2 { + typedef X2<7> X; + void f() { + new X(); // expected-note{{instantiation of}} + } + }; + + template void Y2<3>::f(); + + template + void rdar10283928(int count) { + (void)new char[count](); + } + + template void rdar10283928(int); +} + +namespace PR10864 { + template class Vals {}; + template<> class Vals { public: static const int i = 1; }; + template<> class Vals { public: static const double i; }; + template void test_asm_tied(T o) { + __asm("addl $1, %0" : "=r" (o) : "0"(Vals::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 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 + struct BinOpOverload { + typedef A 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::type XY; + XY *xy = a1; + typedef N4::BinOpOverload::type XX; + XX *xx = a4; + typedef N4::BinOpOverload::type YY; + YY *yy = a2; + typedef N4::BinOpOverload::type ZZ; + ZZ *zz = a8; +} + +namespace N3 { + eight_bytes operator-(::N3::Z); +} + +namespace N4 { + template + struct UnaryOpOverload { + typedef A type; + }; +} + +void test_unary_op_overload(A<8> *a8) { + typedef N4::UnaryOpOverload::type UZ; + UZ *uz = a8; +} + +/* +namespace N5 { + template + struct Lookup { + enum { val = I, more = val + 1 }; + }; + + template + struct Cond { + enum Junk { is = B ? Lookup::more : Lookup::more>::val }; + }; + + enum { resultT = Cond::is, + resultF = Cond::is }; +} +*/ + +namespace N6 { + // non-typedependent + template + struct Lookup {}; + + template + struct Cond { + typedef Lookup True; + typedef Lookup False; + }; + + typedef Cond::True True; + typedef Cond::False False; + + // check that we have the right types + Lookup<1> const &L1(False()); + Lookup const &L2(True()); +} + + +namespace N7 { + // type dependent + template + struct Lookup {}; + + template + struct Cond { + T foo() { return B ? T() : E(); } + typedef Lookup Type; + }; + + //Cond C; // Errors + //int V(C.foo()); // Errors + //typedef Cond::Type Type; // Errors + typedef Cond::Type Type; +} + +template struct IntegralConstant { }; + +template +struct X0 { + void f(T x, IntegralConstant); +}; + +void test_X0(X0 x, IntegralConstant ic) { + x.f(5,ic); +} + +namespace N8 { + struct X { + X operator+(const X&) const; + }; + + template + 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 struct B { + bool f(A a) { + return a == 1; + } + }; + + template struct B; +} + +namespace N10 { + template + class A { + struct X { }; + + public: + ~A() { + f(reinterpret_cast(0), reinterpret_cast(0)); + } + + private: + void f(X *); + void f(X *, X *); + }; + + template class A; +} + +namespace N12 { + // PR5224 + template + struct A { typedef int t0; }; + + struct C { + C(int); + + template + static C *f0(T a0) {return new C((typename A::t0) 1); } + }; + + void f0(int **a) { C::f0(a); } +} + +namespace PR7202 { + template + struct meta { + typedef T type; + }; + + struct X { + struct dummy; + + template + X(T, typename meta::type = 0); + + template + X(T, A); + }; + + template + struct Z { }; + + template Z g(T); + + struct Y { + template + 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 A &operator<<(const T&); + }; + + template + 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 +struct ImaginaryLiteral0 { + void f(T &x) { + x = 3.0I; // expected-error{{incompatible type}} + } +}; + +template struct ImaginaryLiteral0<_Complex float>; +template struct ImaginaryLiteral0; // 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 + 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; +template struct N2::PlusEquals0; +template struct N2::PlusEquals0; +template struct N2::PlusEquals0; +template struct N2::PlusEquals0; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// Conditional operator +// --------------------------------------------------------------------- +template +struct Conditional0 { + void f(T t, U u) { + Result result = t? : u; + } +}; + +template struct Conditional0; + +// --------------------------------------------------------------------- +// Statement expressions +// --------------------------------------------------------------------- +template +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; +template struct StatementExpr0; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// __builtin_choose_expr +// --------------------------------------------------------------------- +template +struct Choose0 { + void f(T t, U u) { + Result r = __builtin_choose_expr(Cond, t, u); // expected-error{{lvalue}} + } +}; + +template struct Choose0; +template struct Choose0; +template struct Choose0; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// __builtin_va_arg +// --------------------------------------------------------------------- +template +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; + +template +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; // 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 +struct ValueInit0 { + int f() { + return int(); + } +}; + +template struct ValueInit0<5>; + +template +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 +struct BuildTemporary0 { + X f() { + return X(N, M); + } +}; + +template struct BuildTemporary0<5, 7>; + +template +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 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 +struct PR6671 { + void f() { (void)BadX<1>(); } // expected-note 2 {{instantiation}} +}; +template struct PR6671<1>; + +// --------------------------------------------------------------------- +// new/delete expressions +// --------------------------------------------------------------------- +struct Y { }; + +template +struct New0 { + T* f(bool x) { + if (x) + return new T; // expected-error{{no matching}} + else + return new T(); + } +}; + +template struct New0; +template struct New0; +template struct New0; // expected-note{{instantiation}} + +template +struct New1 { + T* f(bool x, Arg1 a1) { + return new T(a1); // expected-error{{no matching}} + } +}; + +template struct New1; +template struct New1; +template struct New1; // expected-note{{instantiation}} + +template +struct New2 { + T* f(bool x, Arg1 a1, Arg2 a2) { + return new T(a1, a2); // expected-error{{no matching}} + } +}; + +template struct New2; +template struct New2; // expected-note{{instantiation}} +// FIXME: template struct New2; + +// PR5833 +struct New3 { + New3(); + + void *operator new[](__SIZE_TYPE__) __attribute__((unavailable)); // expected-note{{explicitly made unavailable}} +}; + +template +void* object_creator() { + return new C(); // expected-error{{call to unavailable function 'operator new[]'}} +} + +template void *object_creator(); // expected-note{{instantiation}} + +template +struct Delete0 { + void f(T t) { + delete t; // expected-error{{cannot delete}} + ::delete [] t; // expected-error{{cannot delete}} + } +}; + +template struct Delete0; +template struct Delete0; +template struct Delete0; // expected-note{{instantiation}} + +namespace PR5755 { + template + void Foo() { + char* p = 0; + delete[] p; + } + + void Test() { + Foo(); + } +} + +namespace PR10480 { + template + struct X { + X(); + ~X() { + T *ptr = 1; // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} + } + }; + + template + void f() { + new X[1]; // expected-note{{in instantiation of member function 'PR10480::X::~X' requested here}} + } + + template void f(); +} + +// --------------------------------------------------------------------- +// throw expressions +// --------------------------------------------------------------------- +template +struct Throw1 { + void f(T t) { + throw; + throw t; // expected-error{{incomplete type}} + } +}; + +struct Incomplete; // expected-note 2{{forward}} + +template struct Throw1; +template struct Throw1; +template struct Throw1; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// typeid expressions +// --------------------------------------------------------------------- + +namespace std { + class type_info; +} + +template +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; +template struct TypeId0; // expected-note{{instantiation of member function}} +template struct TypeId0; + +// --------------------------------------------------------------------- +// type traits +// --------------------------------------------------------------------- +template +struct is_pod { + static const bool value = __is_pod(T); +}; + +static int is_pod0[is_pod::value? -1 : 1]; +static int is_pod1[is_pod::value? 1 : -1]; + +// --------------------------------------------------------------------- +// initializer lists +// --------------------------------------------------------------------- +template +struct InitList1 { + void f(Val1 val1) { + T x = { val1 }; + } +}; + +struct APair { + int *x; + const float *y; +}; + +template struct InitList1; +template struct InitList1; + +template +struct InitList2 { + void f(Val1 val1, Val2 val2) { + T x = { val1, val2 }; // expected-error{{cannot initialize}} + } +}; + +template struct InitList2; +template struct InitList2; // expected-note{{instantiation}} + +// --------------------------------------------------------------------- +// member references +// --------------------------------------------------------------------- +template +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; +template struct DotMemRef0; +template struct DotMemRef0; +template struct DotMemRef0; // expected-note{{instantiation}} + +template +struct ArrowMemRef0 { + void f(T t) { + Result result = t->m; // expected-error 2{{non-const lvalue reference}} + } +}; + +template +struct ArrowWrapper { + T operator->(); +}; + +template struct ArrowMemRef0; +template struct ArrowMemRef0; +template struct ArrowMemRef0; +template struct ArrowMemRef0; // expected-note{{instantiation}} + +template struct ArrowMemRef0, int&>; +template struct ArrowMemRef0, int&>; +template struct ArrowMemRef0, int (*)(int)>; +template struct ArrowMemRef0, float&>; // expected-note{{instantiation}} +template struct ArrowMemRef0 >, int&>; + +struct UnresolvedMemRefArray { + int f(int); + int f(char); +}; +UnresolvedMemRefArray Arr[10]; +template int UnresolvedMemRefArrayT(U u) { + return Arr->f(u); +} +template int UnresolvedMemRefArrayT(int); + +// FIXME: we should be able to return a MemInt without the reference! +MemInt &createMemInt(int); + +template +struct NonDepMemberExpr0 { + void f() { + createMemInt(N).m = N; + } +}; + +template struct NonDepMemberExpr0<0>; + +template +struct MemberFuncCall0 { + void f(T t) { + Result result = t.f(); + } +}; + +template +struct HasMemFunc0 { + T f(); +}; + + +template struct MemberFuncCall0, const int&>; + +template +struct ThisMemberFuncCall0 { + Result g(); + + void f() { + Result r1 = g(); + Result r2 = this->g(); + } +}; + +template struct ThisMemberFuncCall0; + +template +struct NonDepMemberCall0 { + void foo(HasMemFunc0 x) { + T result = x.f(); // expected-error{{non-const lvalue reference}} + } +}; + +template struct NonDepMemberCall0; +template struct NonDepMemberCall0; +template struct NonDepMemberCall0; // expected-note{{instantiation}} + + +template +struct QualifiedDeclRef0 { + T f() { + return is_pod::value; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'const bool'}} + } +}; + +template struct QualifiedDeclRef0; +template struct QualifiedDeclRef0; // 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 int x(A x) { return x++; } +int y() { return x(1); } + +namespace PR5880 { + template + 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 x; + A x2; // expected-note{{in instantiation of}} + + template + struct AnonymousUnion { + union { + int i; + float f; + }; + }; + + template + void test_anon_union() { + int array1[__builtin_offsetof(AnonymousUnion, f) == 0? 1 : -1]; + int array2[__builtin_offsetof(AnonymousUnion, f) == 0? 1 : -1]; + } + + template void test_anon_union(); +} 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 +struct S { + void f() { + __func__; // PredefinedExpr + 10; // IntegerLiteral + 10.5; // FloatingLiteral + 'c'; // CharacterLiteral + "hello"; // StringLiteral + true; // CXXBooleanLiteralExpr + nullptr; // CXXNullPtrLiteralExpr + __null; // GNUNullExpr + } +}; + +template struct S; 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 +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 *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 *xf) { + (void)xf->x; // expected-note{{in instantiation of template class 'X' requested here}} +} + +void test3(const X *xf) { + (void)xf->x; // expected-note{{in instantiation of template class 'X' requested here}} +} + +namespace PR7123 { + template struct requirement_; + + template struct instantiate + { }; + + template struct requirement ; + struct failed ; + + template struct requirement + { + static void failed() + { + ((Model*)0)->~Model(); // expected-note{{in instantiation of}} + } + }; + + template struct requirement_ : requirement + { }; + + template struct Requires_ + { typedef void type; }; + + template struct usage_requirements + { + ~usage_requirements() + {((Model*)0)->~Model(); } // expected-note{{in instantiation of}} + }; + + template < typename TT > struct BidirectionalIterator + { + enum + { value = 0 }; + + instantiate< requirement_)>::failed> int534; // expected-note{{in instantiation of}} + + ~BidirectionalIterator() + { i--; } // expected-error{{cannot decrement value of type 'PR7123::X'}} + + TT i; + }; + + struct X + { }; + + template + typename Requires_< BidirectionalIterator::value >::type sort(RanIter,RanIter){} + + void f() + { + X x; + sort(x,x); + } +} + +namespace PR7355 { + template class A { + class D; // expected-note{{declared here}} + D d; //expected-error{{implicit instantiation of undefined member 'PR7355::A::D'}} + }; + + A ai; // expected-note{{in instantiation of}} +} + +namespace PR8712 { + template + class B { + public: + B(const unsigned char i); + unsigned char value : (dim > 0 ? dim : 1); + }; + + template + inline B::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 X +{ + friend class Y; +}; +X 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 +struct X0 { + void f(T x, U y) { + (void)(x + y); // expected-error{{invalid operands}} + } +}; + +struct X1 { }; + +template struct X0; +template struct X0; +template struct X0; // expected-note{{instantiation of}} + +template +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; +template struct X2; // expected-note{{instantiation of}} + +template +struct X3 { + void f(T) { + Label: + T x; + goto Label; + } +}; + +template struct X3; + +template 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; // expected-note{{in instantiation of}} +template struct X4; // expected-note{{in instantiation of}} + +struct Incomplete; // expected-note 2{{forward declaration}} + +template struct X5 { + T f() { } // expected-error{{incomplete result type}} +}; +void test_X5(X5 x5); // okay! + +template struct X5; // expected-note{{instantiation}} + +template 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; +template struct X6; // expected-note{{instantiation}} + +template struct X7 { + void f() { + void *v = this; + } +}; + +template struct X7; + +template struct While0 { + void f(T t) { + while (t) { + } + + while (T t2 = T()) ; + } +}; + +template struct While0; + +template struct Do0 { + void f(T t) { + do { + } while (t); // expected-error{{not contextually}} + } +}; + +struct NotConvertibleToBool { }; +template struct Do0; +template struct Do0; // expected-note{{instantiation}} + +template struct For0 { + void f(T f, T l) { + for (; f != l; ++f) { + if (*f) + continue; + else if (*f == 17) + break; + } + } +}; + +template struct For0; + +template 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 *' is not a structure or union}} + } +}; + +template 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; + +template 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; +template struct Switch1; // expected-note{{instantiation}} + +template 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; +template struct IndirectGoto0; // expected-note{{instantiation}} + +template 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; // okay +template struct TryCatch0; // expected-note{{instantiation}} +template struct TryCatch0; // expected-note{{instantiation}} + +// PR4383 +template struct X; +template struct Y : public X { + Y& x() { return *this; } +}; + +// Make sure our assertions don't get too uppity. +namespace test0 { + template class A { void foo(T array[10]); }; + template class A; +} + +namespace PR7016 { + template void f() { T x = x; } + template void f(); +} + +namespace PR9880 { + struct lua_State; + struct no_tag { char a; }; // (A) + struct yes_tag { long a; long b; }; // (A) + + template + struct HasIndexMetamethod { + template + static no_tag check(...); + template + static yes_tag check(char[sizeof(&U::luaIndex)]); + enum { value = sizeof(check(0)) == sizeof(yes_tag) }; + }; + + class SomeClass { + public: + int luaIndex(lua_State* L); + }; + + int i = HasIndexMetamethod::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 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 struct S { + S() { } + S(T t); +}; + +template struct S; + +void f() { + S s1; + S s2(10); +} + +namespace PR7184 { + template + void f() { + typedef T type; + void g(int array[sizeof(type)]); + } + + template void f(); +} + +namespace UsedAttr { + template + 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(); // expected-note{{instantiation of}} + } +} + +namespace PR9654 { + typedef void ftype(int); + + template + ftype f; + + void g() { + f(0); + } +} + +namespace AliasTagDef { + template + T f() { + using S = struct { // expected-warning {{C++11}} + T g() { + return T(); + } + }; + return S().g(); + } + + int n = f(); +} + +namespace PR10273 { + template 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 struct if_c { }; +template struct if_ { + typedef if_c< static_cast(T1::value)> almost_type_; // expected-note 5{{in instantiation}} +}; +template struct wrap_constraints { }; +template +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* = 0); // expected-note 2{{in instantiation}} + +template struct not_satisfied { + static const bool value = sizeof( has_constraints_((Model*)0) == 1); // expected-error 3{{no matching function}} +}; +template struct requirement_; +template struct instantiate { +}; +template struct requirement_ : if_< not_satisfied >::type { // expected-note 5{{in instantiation}} +}; +template struct usage_requirements { +}; +template < typename TT > struct InputIterator { + typedef instantiate< & requirement_ x)>::failed> boost_concept_check1; // expected-note {{in instantiation}} +}; +template < typename TT > struct ForwardIterator : InputIterator { // expected-note {{in instantiation}} + typedef instantiate< & requirement_ x)>::failed> boost_concept_check2; // expected-note {{in instantiation}} + +}; +typedef instantiate< &requirement_ x)>::failed> boost_concept_checkX;// expected-note 3{{in instantiation}} + +template struct X0 { }; +template struct X0 { }; + +template +void instF0(X0 x0a, X0 x0b) { + X0 x0c; + X0 x0d; +} + +template void instF0(X0, X0); + +template struct FuncPtr { }; +template struct FuncPtr { }; + +template R unary_func(A1); + +template +void use_func_ptr() { + FuncPtr > fp1; + FuncPtr > fp2; +}; + +template void use_func_ptr(); + +namespace PR6990 { + template < typename , typename = int, typename = int > struct X1; + template + struct X2; + + template &)> + struct X3 + { + }; + + template + struct X3_base : X3< X1 > + { + protected: typedef X1< P> type; + X3 e; + }; + + struct r : X3_base + { + }; +} + +namespace InstantiateFunctionTypedef { + template + struct X { + typedef int functype(int, int); + functype func; + }; + + void f(X 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 +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 +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 struct X { explicit X(T* p = 0) { }; }; + template struct Y { Y(int, const T& x); }; + struct A { }; + template + struct B { + B() : y(0, X()) { } + Y > y; + }; + B b; +} + +namespace PR6657 { + struct X + { + X (int, int) { } + }; + + template + void f0() + { + X x = X(0, 0); + } + + void f1() + { + f0(); + } +} + +// 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 struct S { + static const int arr[]; + static const int x; + static int f(); + }; + + template const int S::arr[] = { 1, 2, 3 }; + template const int S::x = sizeof(arr) / sizeof(arr[0]); + template int S::f() { return x; } + + int x = S::f(); +} + +namespace PR7985 { + template struct integral_c { }; + + template + integral_c array_lengthof(T (&x)[N]) { return integral_c(); } // expected-note 2{{candidate template ignored: failed template argument deduction}} + + template + struct Data { + T x; + }; + + template + struct Description { + static const Data data[]; + }; + + template + const Data Description::data[] = {{ 1 }}; // expected-error{{cannot initialize a member subobject of type 'int *' with an rvalue of type 'int'}} + + template<> + Data Description::data[]; + + void test() { + integral_c<1> ic1 = array_lengthof(Description::data); + (void)sizeof(array_lengthof(Description::data)); + + sizeof(array_lengthof( // expected-error{{no matching function for call to 'array_lengthof'}} + Description::data // expected-note{{in instantiation of static data member 'PR7985::Description::data' requested here}} + )); + + array_lengthof(Description::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 rasterizer_sl_clip Conv::xi(x2), Conv::yi(y2)); +namespace agg +{ + template class rasterizer_scanline_aa + { + template bool sweep_scanline(Scanline& sl) + { + unsigned num_cells = m_outline.scanline_num_cells(m_scan_y); + while(num_cells) { } + } + } + class scanline_u8 {} + template class renderer_base { } +} + template + void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, const ColorT& color) + { + while(ras.sweep_scanline(sl)) + { + } + }; +namespace agg +{ + struct rgba8 + { + }; + template + 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 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 m_polygons; + virtual void on_init() + { + typedef agg::renderer_base 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 +void f0() { + struct X; + typedef struct Y { + T (X::* f1())(int) { return 0; } + } Y2; + + Y2 y = Y(); +} + +template void f0(); + +// PR5764 +namespace PR5764 { + struct X { + template + void Bar() { + typedef T ValueType; + struct Y { + Y() { V = ValueType(); } + + ValueType V; + }; + + Y y; + } + }; + + void test(X x) { + x.Bar(); + } +} + +// Instantiation of local classes with virtual functions. +namespace local_class_with_virtual_functions { + template struct X { }; + template struct Y { }; + + template + void f() { + struct Z : public X*> { + virtual void g(Y* y) { } + void g2(int x) {(void)x;} + }; + Z z; + (void)z; + } + + struct S { }; + void test() { f(); } +} + +namespace PR8801 { + template + 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(); +} 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 + struct X { + typedef int type; + + T field; // expected-note{{in instantiation of member class}} + }; + + template + struct Y { + struct Inner; + + typedef typename X::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'; it has not yet been instantiated}} + }; + }; + + Y y; // expected-note{{in instantiation of template class}} +} + +template +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::C *c1; +X::C *c2; + +X::X *xi; // expected-error{{qualified reference to 'X' is a constructor name rather than a type wherever a constructor can be declared}} +X::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::C *' from incompatible type 'X::C *'}} + xi = xf; // expected-error{{assigning to 'X::X *' from incompatible type 'X::X *'}} + // FIXME: error above doesn't print the type X::X cleanly! +} + +void test_instantiation(X::C *x, + X::D::E *e, + X::D::F *f) { + double &dr = x->foo(); + float &fr = e->bar(); + f->foo(); // expected-error{{implicit instantiation of undefined member 'X::D::F'}} + +} + + +X::C *c3; // okay +X::D::E *e1; // okay +X::D::E e2; // expected-note{{in instantiation of member class 'X::D::E' requested here}} + +// Redeclarations. +namespace test1 { + template struct Registry { + struct node; + static node *Head; + struct node { + node(int v) { Head = this; } + }; + }; + void test() { + Registry::node node(0); + } +} + +// Redeclarations during explicit instantiations. +namespace test2 { + template class A { + class Foo; + class Foo { + int foo(); + }; + }; + template class A; + + template class B { + class Foo; + class Foo { + public: + typedef int X; + }; + typename Foo::X x; + class Foo; + }; + template class B; + + template class C { + class Foo; + class Foo; + }; + template class C::Foo { + int x; + }; + template class C; +} + +namespace AliasTagDef { + template + struct F { + using S = struct U { // expected-warning {{C++11}} + T g() { + return T(); + } + }; + }; + + int m = F::S().g(); + int n = F::U().g(); +} + +namespace rdar10397846 { + template 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 void foo() + { + class A::B::C X; // expected-note{{in instantiation of member function}} + int A::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 +struct S { + S() { } +}; + +template +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 >CheckersOrdered; + CheckersOrdered Checkers; + + template + void registerCheck(CHECKER *check) { + Checkers.push_back(S()); // expected-note {{in instantiation of member function 'vector >::push_back' requested here}} + } +}; + +class RetainReleaseChecker { }; + +void f(ExprEngine& Eng) { + Eng.registerCheck(new RetainReleaseChecker); // expected-note {{in instantiation of function template specialization 'ExprEngine::registerCheck' requested here}} +} + +// PR 5838 +namespace test1 { + template struct A { + int a; + }; + + template struct B : A, A { + void f() { + a = 0; // should not be ambiguous + } + }; + template struct B; + + struct O { + int a; + template struct B : A { + void f() { + a = 0; // expected-error {{'test1::O::a' is not a member of class 'test1::O::B'}} + } + }; + }; + template struct O::B; // expected-note {{in instantiation}} +} + +// PR7248 +namespace test2 { + template struct A { + void foo() { + T::bar(); // expected-error {{type 'int' cannot}} + } + }; + + template class B { + void foo(A a) { + a.test2::template A::foo(); // expected-note {{in instantiation}} + } + }; + + template class B; +} 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 struct A { + A() : a(1) { } // expected-error{{cannot initialize a member subobject of type 'void *' with an rvalue of type 'int'}} + + T a; +}; + +A a0; +A a1; // expected-note{{in instantiation of member function 'A::A' requested here}} + +template struct B { + B() : b(1), // expected-warning {{field 'b' will be initialized after field 'a'}} + a(2) { } + + int a; + int b; +}; + +B b0; // expected-note {{in instantiation of member function 'B::B' requested here}} + +template struct AA { AA(int); }; +template class BB : public AA { +public: + BB() : AA(1) {} +}; +BB 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 +struct X1 { + int f(T* ptr, int T::*pm) { // expected-error{{member pointer}} + return ptr->*pm; + } +}; + +template struct X1; +template struct X1; // expected-note{{instantiation}} + +template +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; +template struct X2; // expected-note{{instantiation}} +template struct X2; // expected-note{{instantiation}} + +template +struct X3 { + X3 &operator=(const T& value) { + return *this; + } +}; + +X3 x3; + +typedef int Y::*IntMember; + +template +struct X4 { + X3 member; + + int &getMember(Y& y) { return y.*Member; } +}; + +int &get_X4(X4<&Y::x> x4, Y& y) { + return x4.getMember(y); +} + +template +void accept_X4(X4); + +void test_accept_X4(X4<&Y::x> x4) { + accept_X4(x4); +} + +namespace ValueDepMemberPointer { + template struct instantiate_function {}; + template struct S { + static void instantiate(); + typedef instantiate_function<&S::instantiate> x; // expected-note{{instantiation}} + }; + template void S::instantiate() { + int a[(int)sizeof(T)-42]; // expected-error{{array with a negative size}} + } + S 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 +struct X0 { + template T f0(U); + template U& f1(T*, U); // expected-error{{pointer to a reference}} \ + // expected-note{{candidate}} +}; + +X0 x0i; +X0 x0v; +X0 x0ir; // expected-note{{instantiation}} + +void test_X0(int *ip, double *dp) { + X0 xi; + int i1 = xi.f0(ip); + double *&dpr = xi.f1(ip, dp); + xi.f1(dp, dp); // expected-error{{no matching}} + + X0 xv; + double *&dpr2 = xv.f1(ip, dp); +} + +template +struct X1 { + template + struct Inner0 { + U x; + T y; // expected-error{{void}} + }; + + template + struct Inner1 { + U x; // expected-error{{void}} + T y; + }; + + template + struct Inner2 { + struct SuperInner { + U z; // expected-error{{void}} + }; + }; + + template + struct Inner3 { + void f0(T t, U u) { // expected-note{{passing argument to parameter 't' here}} + (void)(t + u); // expected-error{{invalid operands}} + } + + template + V f1(T t, U u, V) { + return t + u; // expected-error{{cannot initialize return object}} + } + }; + + template + struct Inner4; +}; + +template +template +struct X1::Inner4 { + template + V f2(T t, U u, V); + + static U value; +}; + +template +template +U X1::Inner4::value; // expected-error{{reference variable}} + +template +template +template +V X1::Inner4::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::Inner0 *xvip; // okay + X1::Inner0 xvi; // expected-note{{instantiation}} + + X1::Inner1 *xivp; // okay + X1::Inner1 xiv; // expected-note{{instantiation}} + + X1::Inner2::SuperInner *xisivp; // okay + X1::Inner2::SuperInner xisiv; // expected-note{{instantiation}} + + X1::Inner3 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::Inner3 id3b; + id3b.f0(ip, dp); // expected-note{{instantiation}} + + X1::Inner4 id4; + id4.f2(ip, i, dp); // expected-note{{instantiation}} + + X1::Inner4::value = 17; + i = X1::Inner4::value; // expected-note{{instantiation}} +} + + +template +struct X2 { + template // expected-error{{pointer to a reference}} + struct Inner; + + template // expected-error{{cannot have type 'float'}} + struct Inner2; +}; + +X2 x2a; // expected-note{{instantiation}} +X2 x2b; // expected-note{{instantiation}} + +namespace N0 { + template + struct X0 { }; + + struct X1 { + template void f(X0& vals) { g(vals); } + template void g(X0& vals) { } + }; + + void test(X1 x1, X0 x0i, X0 x0l) { + x1.f(x0i); + x1.f(x0l); + } +} + +namespace PR6239 { + template + struct X0 { + class type { + typedef T E; + template // subsitute T for E and bug goes away + struct sfinae { }; + + template + typename sfinae<&U::operator=>::type test(int); + }; + }; + + template + struct X1 { + typedef T E; + template // subsitute T for E and bug goes away + struct sfinae { }; + + template + typename sfinae<&U::operator=>::type test(int); + }; + +} + +namespace PR7587 { + template class X0; + template struct X1; + template class X2; + + template class X3 + { + template< + template class TT, + typename U = typename X1::type + > + struct Inner { + typedef X2::type> > Type; + }; + + const typename Inner::Type minCoeff() const; + }; + + template class X3 + { + template< + template class TT, + typename U = typename X1::type + > + struct Inner { + typedef X2::type> > Type; + }; + + const typename Inner::Type minCoeff() const; + }; + +} + +namespace PR7669 { + template struct X { + template struct Y { + template struct Z; + template struct Z {}; + }; + }; + + void a() + { + X::Y::Z<0,int>(); + } +} + +namespace PR8489 { + template + class C { + template + void F() {} // expected-note{{FT}} + }; + void f() { + C c; + c.F(); // expected-error{{no matching member function}} + } +} + +namespace rdar8986308 { + template struct __static_assert_test; + template <> struct __static_assert_test {}; + template struct __static_assert_check {}; + + namespace std { + + template + struct __has_rebind + { + private: + struct __two {char _; char __;}; + template static __two __test(...); + template static char __test(typename _Xp::template rebind<_Up>* = 0); + public: + static const bool value = sizeof(__test<_Tp>(0)) == 1; + }; + + } + + template struct B1 {}; + + template + struct B + { + template struct rebind {typedef B1 other;}; + }; + + template struct D1 {}; + + template + struct D + { + template struct rebind {typedef D1 other;}; + }; + + int main() + { + typedef __static_assert_check, double>::value))>)> __t64; + typedef __static_assert_check, 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 +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 *xi, int *ip, X *xf) { + xi->f(17); + xi->g(ip); + xf->f(&identity); + xf->g(identity); + X::h(17, 25); + X::h(identity, &identity); +} + +void test_bad() { + X xv; // expected-note{{in instantiation of template class 'X' requested here}} +} + +template +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 *oil, int i, long l) { + int &ir = oil->f(i, i); + float &fr = oil->f(i, l); +} + +void test_ovl_bad() { + Overloading off; // expected-note{{in instantiation of template class 'Overloading' requested here}} +} + +template +class HasDestructor { +public: + virtual ~HasDestructor() = 0; +}; + +int i = sizeof(HasDestructor); // FIXME: forces instantiation, but + // the code below should probably instantiate by itself. +int abstract_destructor[__is_abstract(HasDestructor)? 1 : -1]; + + +template +class Constructors { +public: + Constructors(const T&); + Constructors(const Constructors &other); +}; + +void test_constructors() { + Constructors ci1(17); + Constructors ci2 = ci1; +} + + +template +struct ConvertsTo { + operator T(); +}; + +void test_converts_to(ConvertsTo ci, ConvertsTo cip) { + int i = ci; + int *ip = cip; +} + +// PR4660 +template struct A0 { operator T*(); }; +template struct A1; + +int *a(A0 &x0, A1 &x1) { + int *y0 = x0; + int *y1 = x1; // expected-error{{no viable conversion}} +} + +struct X0Base { + int &f(); + int& g(int); + static double &g(double); +}; + +template +struct X0 : X0Base { +}; + +template +struct X1 : X0 { + int &f2() { + return X0Base::f(); + } +}; + +void test_X1(X1 x1i) { + int &ir = x1i.f2(); +} + +template +struct X2 : X0Base, U { + int &f2() { return X0Base::f(); } +}; + +template +struct X3 { + void test(T x) { + double& d1 = X0Base::g(x); + } +}; + + +template struct X3; + +// Don't try to instantiate this, it's invalid. +namespace test1 { + template class A {}; + template class B { + void foo(A &a) // expected-error {{no member named 'Undeclared' in namespace 'test1'}} + {} + }; + template class B; +} + +namespace PR6947 { + template< class T > + struct X { + int f0( ) + { + typedef void ( X::*impl_fun_ptr )( ); + impl_fun_ptr pImpl = &X::template + f0_impl1; + } + private: + int f1() { + } + template< class Processor> + void f0_impl1( ) + { + } + }; + + char g0() { + X pc; + pc.f0(); + } + +} + +namespace PR7022 { + template + struct X1 + { + typedef int state_t( ); + state_t g ; + }; + + template < typename U = X1 > 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 +struct X1 { + static void member() { T* x = 1; } // expected-error{{cannot initialize a variable of type 'int *' with an rvalue of type 'int'}} +}; + +template struct instantiate { }; + +template +struct X2 { + typedef instantiate<&X1::member> i; // expected-note{{in instantiation of}} +}; + +X2 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 +class StringSwitch { +public: + template + void Case(const char (&S)[N], const int & Value) { + } +}; + +void test_stringswitch(int argc, char *argv[]) { + (void)StringSwitch(); +} + +namespace PR6986 { + template + struct non_const_member_base + { + }; + + template + struct member: non_const_member_base + { + }; + + 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 + struct X0 { + X0() {} + template X0(const X0 &); + }; + + template + struct X1 : X0 { + X1() {} + template X1(const X1 &x) : X0(x) { } + }; + + X1 x1i; + X1 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 struct StringTest { + void f() { + (void)@"Hello"; + } +}; + +template struct StringTest; +template struct StringTest; + +// @selector expressions +template struct SelectorTest { + SEL f() { + return @selector(multiple:arguments:); + } + SEL f2() { + return @selector(multiple:arguments:); + } +}; + +template struct SelectorTest; +template struct SelectorTest; + +// @protocol expressions +@protocol P +@end + +template struct ProtocolTest { + void f() { + (void)@protocol(P); + } +}; + +template struct ProtocolTest; +template struct ProtocolTest; + +// @encode expressions +template struct EncodeTest { + static const char *encode(T t) { + return @encode(T); + } +}; + +template struct EncodeTest; +template struct EncodeTest; +template struct EncodeTest; 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 void f(T*, int) {} + +template struct S; +template struct S_ : S { typedef int type; }; // expected-note{{in instantiation}} +template 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 S_::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 +void Foo() { + (void)Iter()->x; +} + +void Func() { + Foo(); +} + 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 struct A { + struct B { // expected-note {{not complete until the closing '}'}} + B b; // expected-error {{has incomplete type 'test1::A::B'}} + }; + B b; // expected-note {{in instantiation of}} + }; + A a; // expected-note {{in instantiation of}} +} + +namespace test2 { + template 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 a; // expected-note {{in instantiation of}} +} + +namespace test3 { + // PR12317 + template struct A { + struct B { + enum { Val = 1 }; + char c[1 + Val]; // ok + }; + B b; + }; + A a; +} + +namespace test4 { + template struct M { typedef int type; }; + template struct A { + struct B { // expected-note {{not complete until the closing '}'}} + int k[typename A::type>::B().k[0] + 1]; // expected-error {{incomplete type}} + }; + B b; // expected-note {{in instantiation of}} + }; + A a; // expected-note {{in instantiation of}} +} + +// FIXME: PR12298: Recursive constexpr function template instantiation leads to +// stack overflow. +#if 0 +namespace test5 { + template 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().f(5); +} + +namespace test6 { + template constexpr T f(T); + template constexpr T g(T t) { + typedef int arr[f(T())]; + return t; + } + template constexpr T f(T t) { + typedef int arr[g(T())]; + return t; + } + // This should be ill-formed. + int n = f(0); +} + +namespace test7 { + template constexpr T g(T t) { + return t; + } + template 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 void f(T n) { + int buffer[n]; + [] { int x = sizeof(sizeof(buffer)); }(); +} +int main() { + f(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 +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::value == 5? 1 : -1]; +X xi0; // expected-note{{in instantiation of template class 'X' requested here}} + + +template +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 fy; // expected-note{{in instantiation of template class 'Y' requested here}} + + +// out-of-line static member variables + +template +struct Z { + static T value; +}; + +template +T Z::value; // expected-error{{no matching constructor}} + +struct DefCon {}; + +struct NoDefCon { + NoDefCon(const NoDefCon&); // expected-note{{candidate constructor}} +}; + +void test() { + DefCon &DC = Z::value; + NoDefCon &NDC = Z::value; // expected-note{{instantiation}} +} + +// PR5609 +struct X1 { + ~X1(); // The errors won't be triggered without this dtor. +}; + +template +struct Y1 { + static char Helper(T); + static const int value = sizeof(Helper(T())); +}; + +struct X2 { + virtual ~X2(); +}; + +namespace std { + class type_info { }; +} + +template +struct Y2 { + static T &Helper(); + static const int value = sizeof(typeid(Helper())); +}; + +template +struct Z1 {}; + +void Test() { + Z1::value> x; + int y[Y1::value]; + Z1::value> x2; + int y2[Y2::value]; +} + +// PR5672 +template +struct X3 {}; + +class Y3 { + public: + ~Y3(); // The error isn't triggered without this dtor. + + void Foo(X3<1>); +}; + +template +struct SizeOf { + static const int value = sizeof(T); +}; + +void MyTest3() { + Y3().Foo(X3::value>()); +} + +namespace PR6449 { + template + struct X0 { + static const bool var = false; + }; + + template + const bool X0::var; + + template + struct X1 : public X0 { + static const bool var = false; + }; + + template + const bool X1::var; + + template class X0; + template class X1; + +} 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 +struct Subscript0 { + void test(T t, U u) { + Result &result = t[u]; // expected-error{{no viable overloaded operator[] for type}} + } +}; + +template struct Subscript0; +template struct Subscript0; +template struct Subscript0; +template struct Subscript0; // expected-note{{instantiation}} + +// PR5345 +template +struct S { + bool operator[](int n) const { return true; } +}; + +template +void Foo(const S& s, T x) { + if (s[0]) {} +} + +void Bar() { + Foo(S(), 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 class MetaFun, typename Value> +struct apply { + typedef typename MetaFun::type type; +}; + +template +struct add_pointer { + typedef T* type; +}; + +template +struct add_reference { + typedef T& type; +}; + +int i; +apply::type ip = &i; +apply::type ir = i; +apply::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 struct B; // expected-note{{has a different type 'int'}} + +template class X> // expected-error{{cannot have type 'float'}} \ + // expected-note{{with type 'long'}} +struct X0 { }; + +X0 x0b1; +X0 x0b2; // expected-note{{while substituting}} +X0 x0b3; // expected-error{{template template argument has different template parameters}} + +template class TT> // expected-note{{parameter with type 'int'}} +struct X1 { }; + +template class TT> +struct X2 { + X1 x1; // expected-error{{has different template parameters}} +}; + +template struct X3i { }; +template struct X3l { }; // expected-note{{different type 'long'}} + +X2 x2okay; +X2 x2bad; // expected-note{{instantiation}} + +template class TT, class R = TT<1, 2> > +struct Comp { + typedef R r1; + template struct gt { + static const bool result = x > y; + }; + typedef gt<2, 1> r2; +}; + +template struct lt { + static const bool result = x < y; +}; + +Comp c0; + +namespace PR8629 { + template class TT> struct X0 + { + static void apply(); + }; + template struct Type { }; + + template struct X1 + { + template struct Inner; + + template void g() + { + typedef Inner Init; + X0::apply(); + } + template void f () + { + g >(); + } + }; + template template struct X1::Inner + { + template struct VeryInner { + }; + }; + struct X1Container + { + X1Container() + { + simplex_.f<0>(); + } + X1 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 struct TryCatch0 { + void f() { + try { + } catch (T&&) { // expected-error 2{{cannot catch exceptions by rvalue reference}} + } + } +}; + +template struct TryCatch0; // okay +template struct TryCatch0; // expected-note{{instantiation}} +template struct TryCatch0; // expected-note{{instantiation}} + + +namespace PR10232 { + template + 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::Exception'}} + } + } + }; + + template class Templated; // expected-note{{in instantiation of member function 'PR10232::Templated::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 +struct X { + typedef typeof(T*) typeof_type; + typedef typeof(f(T())) typeof_expr; +}; + +int *iptr0; +float *fptr0; +X::typeof_type &iptr1 = iptr0; + +X::typeof_expr &iptr2 = iptr0; +X::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 +struct add_pointer { + typedef T* type; // expected-error{{'type' declared as a pointer to a reference}} +}; + +add_pointer::type test1(int * ptr) { return ptr; } + +add_pointer::type test2(int * ptr) { + return ptr; // expected-error{{cannot initialize return object of type 'add_pointer::type' (aka 'float *') with an lvalue of type 'int *'}} +} + +add_pointer::type // expected-note{{in instantiation of template class 'add_pointer' 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 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(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 + struct A { + void f(); + }; + + template + struct B : A { + using A::f; + + void g() { + using namespace N; + f(); + } + }; + + template struct B; +} + +namespace test1 { + template struct Visitor1 { + void Visit(struct Object1*); + }; + template struct Visitor2 { + void Visit(struct Object2*); // expected-note {{candidate function}} + }; + + template struct JoinVisitor + : Visitor1, Visitor2 { + typedef Visitor1 Base1; + typedef Visitor2 Base2; + + void Visit(struct Object1*); // expected-note {{candidate function}} + using Base2::Visit; + }; + + class Knot : public JoinVisitor { + }; + + 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 void bar(T* ptr) { + using ns::foo; + foo(); + } + + template void bar(char *); +} + +namespace test3 { + template struct t { + struct s1 { + T f1() const; + }; + struct s2 : s1 { + using s1::f1; + T f1() const; + }; + }; + + void f2() + { + t::s2 a; + t::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 struct A; // expected-note 4{{template is declared here}} + +template struct B : A { }; // expected-error{{implicit instantiation of undefined template}} \ +// expected-error{{implicit instantiation of undefined template 'A'}} + +template struct C : B { } ; // expected-note{{instantiation of template class}} + +template struct D : C { }; // expected-note{{instantiation of template class}} + +template struct E : D { }; // expected-note{{instantiation of template class}} + +template struct F : E { }; // expected-note{{instantiation of template class}} + +void f() { + (void)sizeof(F); // expected-note{{instantiation of template class}} +} + +typedef struct { } X; + +void g() { + (void)sizeof(B); // expected-note{{in instantiation of template class 'B' requested here}} +} + +template +struct G : A, // expected-error{{implicit instantiation of undefined template 'A'}} + A // expected-error{{implicit instantiation of undefined template 'A'}} + { }; + +void h() { + (void)sizeof(G); // expected-note{{in instantiation of template class 'G' 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 struct Def1; + +template<> struct Def1 { + void foo(); +}; + +template<> struct Def1 { // expected-note{{previous definition is here}} + void bar(); +}; + +template<> struct Def1 { + void wibble(); +}; + +void test_Def1(Def1 *d1, Def1 *d2, + Def1 *d3) { + d1->foo(); + d2->bar(); + d3->wibble(); +} + +template // expected-error{{'T2' declared as a pointer to a reference}} + struct Def2; + +template<> struct Def2 { + void foo(); +}; + +void test_Def2(Def2 *d2) { + d2->foo(); +} + +typedef int& int_ref_t; +Def2 *d2; // expected-note{{in instantiation of default argument for 'Def2' required here}} + + +template<> struct Def1 { }; // expected-error{{redefinition of 'Def1'}} + +template struct Def3; + +template<> struct Def3 { + void foo(); +}; + +template<> struct Def3 { + void bar(); +}; + +void test_Def3(Def3 *d3a, Def3 *d3b) { + d3a->foo(); + d3b->bar(); +} + + +template struct Def4; + +template<> struct Def4 { + void foo(); +}; + +void test_Def4(Def4 *d4a) { + d4a->foo(); +} + +template struct Def5; + +template<> struct Def5 { + void foo(); +}; + +template<> struct Def5 { + void bar(); +}; + +void test_Def5(Def5 *d5a, Def5 *d5b) { + d5a->foo(); + d5b->bar(); +} + +template + struct Def6; + +template<> struct Def6 { + void foo(); +}; + +template<> struct Def6 { + void bar(); +}; + +bool test_Def6(Def6 *d6a, + Def6 *d6b, + Def6 *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 struct Constant; // expected-note{{template parameter is declared here}} \ +// FIXME: bad location expected-error{{a non-type template parameter cannot have type 'float'}} + +Constant *c1; + +int x; +float f(int, double); + +Constant *c2; +Constant *c3; +Constant *c4; +Constant *c5; + +Constant *c6; // expected-error{{non-type template argument of type 'float (int, double)' cannot be converted to a value of type 'float (*)(int, int)'}} + +Constant *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 struct A { }; + +template > + struct B : U { }; + +template<> +struct A { + void foo(); +}; + +template<> +struct A { + void bar(); +}; + +void test(B *b1, B *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 struct X : X { }; \ +// 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); // 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 struct A { using X = typename T::X; }; // expected-error {{no members}} +template typename T::X f(typename A::X); +template void f(...) {} +template auto g(typename A::X) -> typename T::X; // expected-note {{here}} expected-note {{substituting}} +template void g(...) {} + +void h() +{ + f(0); // ok, SFINAE in return type + g(0); // not ok, substitution inside A 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 +struct is_same { + static const bool value = false; +}; + +template +struct is_same { + static const bool value = true; +}; + +namespace PR9353 { + template class IM; + + template class IntervalMap> + void foo(IntervalMap* m) { typedef IntervalMap type; } + + void f(IM* m) { foo(m); } +} + +namespace PR9400 { + template