aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--clang/docs/ReleaseNotes.rst6
-rw-r--r--clang/include/clang/Basic/DiagnosticSemaKinds.td62
-rw-r--r--clang/include/clang/Sema/Sema.h57
-rw-r--r--clang/lib/Frontend/FrontendActions.cpp24
-rw-r--r--clang/lib/Sema/SemaInit.cpp7
-rw-r--r--clang/lib/Sema/SemaLambda.cpp7
-rw-r--r--clang/lib/Sema/SemaLookup.cpp14
-rw-r--r--clang/lib/Sema/SemaTemplate.cpp218
-rw-r--r--clang/lib/Sema/SemaTemplateDeduction.cpp5
-rw-r--r--clang/lib/Sema/SemaTemplateInstantiate.cpp117
-rw-r--r--clang/lib/Sema/TreeTransform.h2
-rw-r--r--clang/test/AST/ByteCode/cxx1z.cpp2
-rw-r--r--clang/test/AST/ByteCode/cxx20.cpp2
-rw-r--r--clang/test/AST/ByteCode/cxx2a.cpp3
-rw-r--r--clang/test/AST/ByteCode/cxx98.cpp2
-rw-r--r--clang/test/AST/ByteCode/records.cpp2
-rw-r--r--clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp1
-rw-r--r--clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp2
-rw-r--r--clang/test/CXX/drs/cwg0xx.cpp31
-rw-r--r--clang/test/CXX/drs/cwg10xx.cpp1
-rw-r--r--clang/test/CXX/drs/cwg13xx.cpp1
-rw-r--r--clang/test/CXX/drs/cwg18xx.cpp1
-rw-r--r--clang/test/CXX/drs/cwg1xx.cpp16
-rw-r--r--clang/test/CXX/drs/cwg20xx.cpp10
-rw-r--r--clang/test/CXX/drs/cwg21xx.cpp3
-rw-r--r--clang/test/CXX/drs/cwg3xx.cpp12
-rw-r--r--clang/test/CXX/drs/cwg4xx.cpp17
-rw-r--r--clang/test/CXX/drs/cwg6xx.cpp3
-rw-r--r--clang/test/CXX/expr/expr.const/p3-0x.cpp7
-rw-r--r--clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp2
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp2
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp7
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp2
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp20
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp8
-rw-r--r--clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp18
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp4
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp42
-rw-r--r--clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp10
-rw-r--r--clang/test/CXX/temp/temp.deduct/p9.cpp5
-rw-r--r--clang/test/CXX/temp/temp.param/p1.cpp9
-rw-r--r--clang/test/CXX/temp/temp.param/p12.cpp4
-rw-r--r--clang/test/CXX/temp/temp.param/p15-cxx0x.cpp10
-rw-r--r--clang/test/CXX/temp/temp.param/p8-cxx20.cpp2
-rw-r--r--clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp2
-rw-r--r--clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp10
-rw-r--r--clang/test/CXX/temp/temp.spec/part.spec.cpp4
-rw-r--r--clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp8
-rw-r--r--clang/test/Misc/integer-literal-printing.cpp7
-rw-r--r--clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp2
-rw-r--r--clang/test/Modules/missing-body-in-import.cpp1
-rw-r--r--clang/test/Modules/template-default-args.cpp4
-rw-r--r--clang/test/Parser/MicrosoftExtensions.cpp2
-rw-r--r--clang/test/Parser/cxx-template-argument.cpp12
-rw-r--r--clang/test/Parser/cxx-template-template-recovery.cpp6
-rw-r--r--clang/test/Parser/cxx1z-class-template-argument-deduction.cpp6
-rw-r--r--clang/test/Sema/invalid-member.cpp2
-rw-r--r--clang/test/SemaCXX/access-base-class.cpp24
-rw-r--r--clang/test/SemaCXX/alias-template.cpp5
-rw-r--r--clang/test/SemaCXX/anonymous-struct.cpp3
-rw-r--r--clang/test/SemaCXX/builtin-structured-binding-size.cpp1
-rw-r--r--clang/test/SemaCXX/constant-expression-cxx11.cpp4
-rw-r--r--clang/test/SemaCXX/constant-expression.cpp2
-rw-r--r--clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp1
-rw-r--r--clang/test/SemaCXX/cxx2a-consteval.cpp2
-rw-r--r--clang/test/SemaCXX/cxx2c-template-template-param.cpp25
-rw-r--r--clang/test/SemaCXX/cxx98-compat-flags.cpp3
-rw-r--r--clang/test/SemaCXX/cxx98-compat.cpp11
-rw-r--r--clang/test/SemaCXX/invalid-requirement-requires-expr.cpp3
-rw-r--r--clang/test/SemaCXX/invalid-std-initializer-list.cpp4
-rw-r--r--clang/test/SemaCXX/lambda-expressions.cpp6
-rw-r--r--clang/test/SemaCXX/make_integer_seq.cpp3
-rw-r--r--clang/test/SemaCXX/type-trait-common-type.cpp7
-rw-r--r--clang/test/SemaCXX/undefined-internal.cpp6
-rw-r--r--clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp1
-rw-r--r--clang/test/SemaHLSL/BuiltIns/Buffers.hlsl4
-rw-r--r--clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl4
-rw-r--r--clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl4
-rw-r--r--clang/test/SemaObjCXX/parameterized_classes_subst.mm2
-rw-r--r--clang/test/SemaTemplate/alias-templates.cpp7
-rw-r--r--clang/test/SemaTemplate/concepts.cpp3
-rw-r--r--clang/test/SemaTemplate/cwg2398.cpp40
-rw-r--r--clang/test/SemaTemplate/dedup-types-builtin.cpp4
-rw-r--r--clang/test/SemaTemplate/default-arguments.cpp25
-rw-r--r--clang/test/SemaTemplate/instantiate-member-pointers.cpp12
-rw-r--r--clang/test/SemaTemplate/instantiate-template-template-parm.cpp6
-rw-r--r--clang/test/SemaTemplate/instantiation-default-1.cpp13
-rw-r--r--clang/test/SemaTemplate/instantiation-default-2.cpp3
-rw-r--r--clang/test/SemaTemplate/instantiation-dependence.cpp3
-rw-r--r--clang/test/SemaTemplate/instantiation-depth-subst-2.cpp1
-rw-r--r--clang/test/SemaTemplate/instantiation-depth-subst.cpp3
-rw-r--r--clang/test/SemaTemplate/ms-unqualified-base-class.cpp4
-rw-r--r--clang/test/SemaTemplate/nested-template.cpp6
-rw-r--r--clang/test/SemaTemplate/partial-spec-instantiate.cpp3
-rw-r--r--clang/test/SemaTemplate/recovery-crash.cpp3
-rw-r--r--clang/test/SemaTemplate/temp_arg.cpp12
-rw-r--r--clang/test/SemaTemplate/temp_arg_nontype.cpp20
-rw-r--r--clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp2
-rw-r--r--clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp8
-rw-r--r--clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp24
-rw-r--r--clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp11
-rw-r--r--clang/test/SemaTemplate/temp_arg_template.cpp26
-rw-r--r--clang/test/SemaTemplate/temp_arg_template_p0522.cpp49
-rw-r--r--clang/test/SemaTemplate/temp_arg_type.cpp7
104 files changed, 688 insertions, 578 deletions
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 98c889c..e942834 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -304,7 +304,11 @@ Improvements to Clang's diagnostics
- Fixed false positives in ``-Waddress-of-packed-member`` diagnostics when
potential misaligned members get processed before they can get discarded.
(#GH144729)
-
+- Clang now more consistently adds a note pointing to the relevant template
+ parameter. Some diagnostics are reworded to better take advantage of this.
+- Template Template Parameter diagnostics now stop referring to template
+ parameters as template arguments, in some circumstances, better hiding
+ from the users template template parameter partial ordering arcana.
- Clang now emits dignostic with correct message in case of assigning to const reference captured in lambda. (#GH105647)
- Fixed false positive in ``-Wmissing-noreturn`` diagnostic when it was requiring the usage of
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index dc4c6d3..79ef6dd 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -5358,19 +5358,14 @@ def err_template_linkage : Error<"templates must have C++ linkage">;
def err_template_typedef : Error<"a typedef cannot be a template">;
def err_template_unnamed_class : Error<
"cannot declare a class template with no name">;
-def err_template_param_list_different_arity : Error<
- "%select{too few|too many}0 template parameters in template "
- "%select{|template parameter }1redeclaration">;
-def note_template_param_list_different_arity : Note<
- "%select{too few|too many}0 template parameters in template template "
- "argument">;
+def err_template_param_list_different_arity
+ : Error<"%select{too few|too many}0 template parameters in template "
+ "%select{|template parameter }1redeclaration">;
def note_template_prev_declaration : Note<
"previous template %select{declaration|template parameter}0 is here">;
-def err_template_param_different_kind : Error<
- "template parameter has a different kind in template "
- "%select{|template parameter }0redeclaration">;
-def note_template_param_different_kind : Note<
- "template parameter has a different kind in template argument">;
+def err_template_param_different_kind
+ : Error<"template parameter has a different kind in template "
+ "%select{|template parameter }0redeclaration">;
def err_invalid_decl_specifier_in_nontype_parm : Error<
"invalid declaration specifier in template non-type parameter">;
@@ -5379,8 +5374,6 @@ def err_template_nontype_parm_different_type : Error<
"template non-type parameter has a different type %0 in template "
"%select{|template parameter }1redeclaration">;
-def note_template_nontype_parm_different_type : Note<
- "template non-type parameter has a different type %0 in template argument">;
def note_template_nontype_parm_prev_declaration : Note<
"previous non-type template parameter with type %0 is here">;
def err_template_nontype_parm_bad_type : Error<
@@ -5454,10 +5447,17 @@ def err_template_missing_args : Error<
"%select{class template|function template|variable template|alias template|"
"template template parameter|concept|template}0 %1 requires template "
"arguments">;
-def err_template_arg_list_different_arity : Error<
- "%select{too few|too many}0 template arguments for "
- "%select{class template|function template|variable template|alias template|"
- "template template parameter|concept|template}1 %2">;
+def err_template_param_missing_arg
+ : Error<"missing template argument for template parameter">;
+def err_template_template_param_missing_param
+ : Error<"no template parameter in this template template parameter "
+ "corresponds to non-defaulted template parameter of argument "
+ "template">;
+def err_template_too_many_args
+ : Error<"too many template arguments for "
+ "%select{class template|function template|variable template|alias "
+ "template|"
+ "template template parameter|concept|template}0 %1">;
def note_template_decl_here : Note<"template is declared here">;
def note_template_decl_external : Note<
"template declaration from hidden source: %0">;
@@ -5500,12 +5500,9 @@ def err_template_arg_not_valid_template
def note_template_arg_refers_to_template_here
: Note<"template argument refers to a %select{function template|class "
"template|variable template|concept}0 %1, here">;
-def err_template_arg_template_params_mismatch : Error<
- "template template argument has different template parameters than its "
- "corresponding template template parameter">;
-def note_template_arg_template_params_mismatch : Note<
- "template template argument has different template parameters than its "
- "corresponding template template parameter">;
+def note_template_arg_template_params_mismatch
+ : Note<"template template argument is incompatible with its "
+ "corresponding template template parameter">;
def err_non_deduced_mismatch : Error<
"could not match %diff{$ against $|types}0,1">;
def err_inconsistent_deduction : Error<
@@ -5770,8 +5767,10 @@ def err_template_recursion_depth_exceeded : Error<
def err_constraint_depends_on_self
: Error<"satisfaction of constraint %0 depends on itself">,
NoSFINAE;
-def note_template_recursion_depth : Note<
- "use -ftemplate-depth=N to increase recursive template instantiation depth">;
+def note_template_recursion_depth
+ : Note<"use -ftemplate-depth=N to increase recursive template "
+ "instantiation depth">,
+ NoSFINAE;
def err_template_instantiate_within_definition : Error<
"%select{implicit|explicit}0 instantiation of template %1 within its"
@@ -6050,14 +6049,11 @@ def err_template_param_pack_default_arg : Error<
def err_template_param_pack_must_be_last_template_parameter : Error<
"template parameter pack must be the last template parameter">;
-def err_template_parameter_pack_non_pack : Error<
- "%select{template type|non-type template|template template}0 parameter"
- "%select{| pack}1 conflicts with previous %select{template type|"
- "non-type template|template template}0 parameter%select{ pack|}1">;
-def note_template_parameter_pack_non_pack : Note<
- "%select{template type|non-type template|template template}0 parameter"
- "%select{| pack}1 does not match %select{template type|non-type template"
- "|template template}0 parameter%select{ pack|}1 in template argument">;
+def err_template_parameter_pack_non_pack
+ : Error<"%select{template type|non-type template|template template}0 "
+ "parameter"
+ "%select{| pack}1 conflicts with previous %select{template type|"
+ "non-type template|template template}0 parameter%select{ pack|}1">;
def note_template_parameter_pack_here : Note<
"previous %select{template type|non-type template|template template}0 "
"parameter%select{| pack}1 declared here">;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index 2bd6be2..3e464d9 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -12026,7 +12026,7 @@ public:
bool *ConstraintsNotSatisfied = nullptr);
bool CheckTemplateTypeArgument(
- TemplateTypeParmDecl *Param, TemplateArgumentLoc &Arg,
+ TemplateArgumentLoc &Arg,
SmallVectorImpl<TemplateArgument> &SugaredConverted,
SmallVectorImpl<TemplateArgument> &CanonicalConverted);
@@ -12066,9 +12066,13 @@ public:
TemplateTemplateParmDecl *Param,
const TemplateArgumentLoc &Arg);
+ /// Print the given named declaration to a string,
+ /// using the current PrintingPolicy, except that
+ /// TerseOutput will always be set.
+ SmallString<128> toTerseString(const NamedDecl &D) const;
+
void NoteTemplateLocation(const NamedDecl &Decl,
std::optional<SourceRange> ParamRange = {});
- void NoteTemplateParameterLocation(const NamedDecl &Decl);
/// Given a non-type template argument that refers to a
/// declaration and the type of its corresponding non-type template
@@ -12183,15 +12187,13 @@ public:
bool TemplateParameterListsAreEqual(
const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New,
const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain,
- TemplateParameterListEqualKind Kind,
- SourceLocation TemplateArgLoc = SourceLocation());
+ TemplateParameterListEqualKind Kind);
- bool TemplateParameterListsAreEqual(
- TemplateParameterList *New, TemplateParameterList *Old, bool Complain,
- TemplateParameterListEqualKind Kind,
- SourceLocation TemplateArgLoc = SourceLocation()) {
+ bool TemplateParameterListsAreEqual(TemplateParameterList *New,
+ TemplateParameterList *Old, bool Complain,
+ TemplateParameterListEqualKind Kind) {
return TemplateParameterListsAreEqual(nullptr, New, nullptr, Old, Complain,
- Kind, TemplateArgLoc);
+ Kind);
}
/// Check whether a template can be declared within this scope.
@@ -13088,6 +13090,11 @@ public:
/// We are performing partial ordering for template template parameters.
PartialOrderingTTP,
+
+ /// We are Checking a Template Parameter, so for any diagnostics which
+ /// occur in this scope, we will add a context note which points to this
+ /// template parameter.
+ CheckTemplateParameter,
} Kind;
/// Was the enclosing context a non-instantiation SFINAE context?
@@ -13318,6 +13325,10 @@ public:
PartialOrderingTTP, TemplateDecl *PArg,
SourceRange InstantiationRange = SourceRange());
+ struct CheckTemplateParameter {};
+ /// \brief Note that we are checking a template parameter.
+ InstantiatingTemplate(Sema &SemaRef, CheckTemplateParameter);
+
/// Note that we have finished instantiating this template.
void Clear();
@@ -13335,8 +13346,6 @@ public:
Sema &SemaRef;
bool Invalid;
bool AlreadyInstantiating;
- bool CheckInstantiationDepth(SourceLocation PointOfInstantiation,
- SourceRange InstantiationRange);
InstantiatingTemplate(Sema &SemaRef,
CodeSynthesisContext::SynthesisKind Kind,
@@ -13351,6 +13360,30 @@ public:
InstantiatingTemplate &operator=(const InstantiatingTemplate &) = delete;
};
+ /// For any diagnostics which occur within its scope, adds a context note
+ /// pointing to the declaration of the template parameter.
+ struct CheckTemplateParameterRAII : InstantiatingTemplate {
+ CheckTemplateParameterRAII(Sema &S, NamedDecl *Param = nullptr)
+ : InstantiatingTemplate(S, CheckTemplateParameter()),
+ Context(isInvalid() ? nullptr : &S.CodeSynthesisContexts.back()) {
+ setParam(Param);
+ }
+
+ void setParam(NamedDecl *Param) {
+ assert(!Param || Param->isTemplateParameter());
+ if (isInvalid())
+ return;
+ Context->Entity = Param;
+ Context->PointOfInstantiation =
+ Param ? Param->getLocation() : SourceLocation();
+ Context->InstantiationRange =
+ Param ? Param->getSourceRange() : SourceRange();
+ }
+
+ private:
+ Sema::CodeSynthesisContext *Context;
+ };
+
bool SubstTemplateArgument(const TemplateArgumentLoc &Input,
const MultiLevelTemplateArgumentList &TemplateArgs,
TemplateArgumentLoc &Output,
@@ -13529,7 +13562,7 @@ public:
~ArgPackSubstIndexRAII() { Self.ArgPackSubstIndex = OldSubstIndex; }
};
- void pushCodeSynthesisContext(CodeSynthesisContext Ctx);
+ bool pushCodeSynthesisContext(CodeSynthesisContext Ctx);
void popCodeSynthesisContext();
void PrintContextStack(InstantiationContextDiagFuncRef DiagFunc) {
diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp
index 7424958..a73e0a6 100644
--- a/clang/lib/Frontend/FrontendActions.cpp
+++ b/clang/lib/Frontend/FrontendActions.cpp
@@ -418,7 +418,8 @@ public:
}
private:
- static std::string toString(CodeSynthesisContext::SynthesisKind Kind) {
+ static std::optional<std::string>
+ toString(CodeSynthesisContext::SynthesisKind Kind) {
switch (Kind) {
case CodeSynthesisContext::TemplateInstantiation:
return "TemplateInstantiation";
@@ -476,8 +477,10 @@ private:
return "TypeAliasTemplateInstantiation";
case CodeSynthesisContext::PartialOrderingTTP:
return "PartialOrderingTTP";
+ case CodeSynthesisContext::CheckTemplateParameter:
+ return std::nullopt;
}
- return "";
+ return std::nullopt;
}
template <bool BeginInstantiation>
@@ -485,12 +488,14 @@ private:
const CodeSynthesisContext &Inst) {
std::string YAML;
{
+ std::optional<TemplightEntry> Entry =
+ getTemplightEntry<BeginInstantiation>(TheSema, Inst);
+ if (!Entry)
+ return;
llvm::raw_string_ostream OS(YAML);
llvm::yaml::Output YO(OS);
- TemplightEntry Entry =
- getTemplightEntry<BeginInstantiation>(TheSema, Inst);
llvm::yaml::EmptyContext Context;
- llvm::yaml::yamlize(YO, Entry, true, Context);
+ llvm::yaml::yamlize(YO, *Entry, true, Context);
}
Out << "---" << YAML << "\n";
}
@@ -570,10 +575,13 @@ private:
}
template <bool BeginInstantiation>
- static TemplightEntry getTemplightEntry(const Sema &TheSema,
- const CodeSynthesisContext &Inst) {
+ static std::optional<TemplightEntry>
+ getTemplightEntry(const Sema &TheSema, const CodeSynthesisContext &Inst) {
TemplightEntry Entry;
- Entry.Kind = toString(Inst.Kind);
+ std::optional<std::string> Kind = toString(Inst.Kind);
+ if (!Kind)
+ return std::nullopt;
+ Entry.Kind = *Kind;
Entry.Event = BeginInstantiation ? "Begin" : "End";
llvm::raw_string_ostream OS(Entry.Name);
printEntryName(TheSema, Inst.Entity, OS);
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index c971293..e79ac26 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -7342,7 +7342,7 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S,
void InitializationSequence::PrintInitLocationNote(Sema &S,
const InitializedEntity &Entity) {
- if (Entity.isParamOrTemplateParamKind() && Entity.getDecl()) {
+ if (Entity.isParameterKind() && Entity.getDecl()) {
if (Entity.getDecl()->getLocation().isInvalid())
return;
@@ -7351,9 +7351,8 @@ void InitializationSequence::PrintInitLocationNote(Sema &S,
<< Entity.getDecl()->getDeclName();
else
S.Diag(Entity.getDecl()->getLocation(), diag::note_parameter_here);
- }
- else if (Entity.getKind() == InitializedEntity::EK_RelatedResult &&
- Entity.getMethodDecl())
+ } else if (Entity.getKind() == InitializedEntity::EK_RelatedResult &&
+ Entity.getMethodDecl())
S.Diag(Entity.getMethodDecl()->getLocation(),
diag::note_method_return_type_change)
<< Entity.getMethodDecl()->getDeclName();
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index fbc2e7e..abd030b 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -1525,13 +1525,16 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
TemplateParameterList *TemplateParams =
getGenericLambdaTemplateParameterList(LSI, *this);
if (TemplateParams) {
- for (const auto *TP : TemplateParams->asArray()) {
+ CheckTemplateParameterRAII CTP(*this);
+ for (auto *TP : TemplateParams->asArray()) {
if (!TP->getIdentifier())
continue;
+ CTP.setParam(TP);
for (const auto &Capture : Intro.Captures) {
if (Capture.Id == TP->getIdentifier()) {
Diag(Capture.Loc, diag::err_template_param_shadow) << Capture.Id;
- NoteTemplateParameterLocation(*TP);
+ // forget we already emitted this stack.
+ LastEmittedCodeSynthesisContextDepth = 0;
}
}
}
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index 25728de..305aab6 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -1613,9 +1613,13 @@ llvm::DenseSet<Module*> &Sema::getLookupModules() {
unsigned N = CodeSynthesisContexts.size();
for (unsigned I = CodeSynthesisContextLookupModules.size();
I != N; ++I) {
- Module *M = CodeSynthesisContexts[I].Entity ?
- getDefiningModule(*this, CodeSynthesisContexts[I].Entity) :
- nullptr;
+ auto &Ctx = CodeSynthesisContexts[I];
+ // FIXME: Are there any other context kinds that shouldn't be looked at
+ // here?
+ if (Ctx.Kind == CodeSynthesisContext::PartialOrderingTTP ||
+ Ctx.Kind == CodeSynthesisContext::CheckTemplateParameter)
+ continue;
+ Module *M = Ctx.Entity ? getDefiningModule(*this, Ctx.Entity) : nullptr;
if (M && !LookupModulesCache.insert(M).second)
M = nullptr;
CodeSynthesisContextLookupModules.push_back(M);
@@ -3738,7 +3742,8 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R,
TemplateParameterList *Params = FD->getTemplateParameters();
if (Params->size() == 1) {
IsTemplate = true;
- if (!Params->getParam(0)->isTemplateParameterPack() && !StringLit) {
+ NamedDecl *Param = Params->getParam(0);
+ if (!Param->isTemplateParameterPack() && !StringLit) {
// Implied but not stated: user-defined integer and floating literals
// only ever use numeric literal operator templates, not templates
// taking a parameter of class type.
@@ -3751,6 +3756,7 @@ Sema::LookupLiteralOperator(Scope *S, LookupResult &R,
if (StringLit) {
SFINAETrap Trap(*this);
CheckTemplateArgumentInfo CTAI;
+ CheckTemplateParameterRAII CTP(*this, Param);
TemplateArgumentLoc Arg(
TemplateArgument(StringLit, /*IsCanonical=*/false), StringLit);
if (CheckTemplateArgument(
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 3ebbb30..ef789f6 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -921,9 +921,11 @@ void Sema::DiagnoseTemplateParameterShadow(SourceLocation Loc, Decl *PrevDecl,
? diag::ext_template_param_shadow
: (SupportedForCompatibility ? diag::ext_compat_template_param_shadow
: diag::err_template_param_shadow);
- const auto *ND = cast<NamedDecl>(PrevDecl);
+ auto *ND = cast<NamedDecl>(PrevDecl);
+ CheckTemplateParameterRAII CTP(*this, ND);
+ // FIXME: Don't put the name in the diagnostic, unless there is no source
+ // location.
Diag(Loc, DiagId) << ND->getDeclName();
- NoteTemplateParameterLocation(*ND);
}
TemplateDecl *Sema::AdjustDeclIfTemplate(Decl *&D) {
@@ -5135,7 +5137,7 @@ TemplateNameKind Sema::ActOnTemplateName(Scope *S,
}
bool Sema::CheckTemplateTypeArgument(
- TemplateTypeParmDecl *Param, TemplateArgumentLoc &AL,
+ TemplateArgumentLoc &AL,
SmallVectorImpl<TemplateArgument> &SugaredConverted,
SmallVectorImpl<TemplateArgument> &CanonicalConverted) {
const TemplateArgument &Arg = AL.getArgument();
@@ -5191,7 +5193,6 @@ bool Sema::CheckTemplateTypeArgument(
? diag::ext_ms_template_type_arg_missing_typename
: diag::err_template_arg_must_be_type_suggest)
<< FixItHint::CreateInsertion(Loc, "typename ");
- NoteTemplateParameterLocation(*Param);
// Recover by synthesizing a type using the location information that we
// already have.
@@ -5229,7 +5230,6 @@ bool Sema::CheckTemplateTypeArgument(
// is not a type.
SourceRange SR = AL.getSourceRange();
Diag(SR.getBegin(), diag::err_template_arg_must_be_type) << SR;
- NoteTemplateParameterLocation(*Param);
return true;
}
@@ -5502,8 +5502,8 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
CheckTemplateArgumentInfo &CTAI,
CheckTemplateArgumentKind CTAK) {
// Check template type parameters.
- if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(Param))
- return CheckTemplateTypeArgument(TTP, ArgLoc, CTAI.SugaredConverted,
+ if (isa<TemplateTypeParmDecl>(Param))
+ return CheckTemplateTypeArgument(ArgLoc, CTAI.SugaredConverted,
CTAI.CanonicalConverted);
const TemplateArgument &Arg = ArgLoc.getArgument();
@@ -5646,8 +5646,6 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
// therefore cannot be a non-type template argument.
Diag(ArgLoc.getLocation(), diag::err_template_arg_must_be_expr)
<< ArgLoc.getSourceRange();
- NoteTemplateParameterLocation(*Param);
-
return true;
case TemplateArgument::Type: {
@@ -5667,7 +5665,6 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
Diag(SR.getBegin(), diag::err_template_arg_nontype_ambig) << SR << T;
else
Diag(SR.getBegin(), diag::err_template_arg_must_be_expr) << SR;
- NoteTemplateParameterLocation(*Param);
return true;
}
@@ -5771,11 +5768,11 @@ bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
}
/// Diagnose a missing template argument.
-template<typename TemplateParmDecl>
+template <typename TemplateParmDecl>
static bool diagnoseMissingArgument(Sema &S, SourceLocation Loc,
- TemplateDecl *TD,
- const TemplateParmDecl *D,
- TemplateArgumentListInfo &Args) {
+ TemplateDecl *TD, const TemplateParmDecl *D,
+ TemplateArgumentListInfo &Args,
+ bool MatchingTTP) {
// Dig out the most recent declaration of the template parameter; there may be
// declarations of the template that are more recent than TD.
D = cast<TemplateParmDecl>(cast<TemplateDecl>(TD->getMostRecentDecl())
@@ -5793,16 +5790,12 @@ static bool diagnoseMissingArgument(Sema &S, SourceLocation Loc,
return true;
}
+ SourceLocation DiagLoc = Args.getRAngleLoc();
// FIXME: If there's a more recent default argument that *is* visible,
// diagnose that it was declared too late.
-
- TemplateParameterList *Params = TD->getTemplateParameters();
-
- S.Diag(Loc, diag::err_template_arg_list_different_arity)
- << /*not enough args*/0
- << (int)S.getTemplateNameKindForDiagnostics(TemplateName(TD))
- << TD;
- S.NoteTemplateLocation(*TD, Params->getSourceRange());
+ S.Diag(DiagLoc.isValid() ? DiagLoc : Loc,
+ MatchingTTP ? diag::err_template_template_param_missing_param
+ : diag::err_template_param_missing_arg);
return true;
}
@@ -5836,11 +5829,14 @@ bool Sema::CheckTemplateArgumentList(
SmallVector<TemplateArgument, 2> CanonicalArgumentPack;
unsigned ArgIdx = 0, NumArgs = NewArgs.size();
LocalInstantiationScope InstScope(*this, true);
+ CheckTemplateParameterRAII CTP(*this);
for (TemplateParameterList::iterator ParamBegin = Params->begin(),
ParamEnd = Params->end(),
Param = ParamBegin;
Param != ParamEnd;
/* increment in loop */) {
+ CTP.setParam(*Param);
+
if (size_t ParamIdx = Param - ParamBegin;
DefaultArgs && ParamIdx >= DefaultArgs.StartPos) {
// All written arguments should have been consumed by this point.
@@ -5877,11 +5873,9 @@ bool Sema::CheckTemplateArgumentList(
continue;
} else if (ArgIdx == NumArgs && !PartialTemplateArgs) {
// Not enough arguments for this parameter pack.
- Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
- << /*not enough args*/0
- << (int)getTemplateNameKindForDiagnostics(TemplateName(Template))
- << Template;
- NoteTemplateLocation(*Template, Params->getSourceRange());
+ Diag(RAngleLoc, CTAI.MatchingTTP
+ ? diag::err_template_template_param_missing_param
+ : diag::err_template_param_missing_arg);
return true;
}
}
@@ -5919,6 +5913,7 @@ bool Sema::CheckTemplateArgumentList(
SmallVector<TemplateArgument, 4> Args(ParamEnd - Param);
for (TemplateParameterList::iterator First = Param; Param != ParamEnd;
++Param) {
+ CTP.setParam(*Param);
TemplateArgument &Arg = Args[Param - First];
Arg = ArgLoc.getArgument();
if (!(*Param)->isTemplateParameterPack() ||
@@ -5959,7 +5954,6 @@ bool Sema::CheckTemplateArgumentList(
diag::err_template_expansion_into_fixed_list)
<< (isa<ConceptDecl>(Template) ? 1 : 0)
<< ArgLoc.getSourceRange();
- NoteTemplateParameterLocation(**Param);
return true;
}
}
@@ -6066,14 +6060,14 @@ bool Sema::CheckTemplateArgumentList(
if (!HasDefaultArg) {
if (TemplateTypeParmDecl *TTP = dyn_cast<TemplateTypeParmDecl>(*Param))
return diagnoseMissingArgument(*this, TemplateLoc, Template, TTP,
- NewArgs);
+ NewArgs, CTAI.MatchingTTP);
if (NonTypeTemplateParmDecl *NTTP =
dyn_cast<NonTypeTemplateParmDecl>(*Param))
return diagnoseMissingArgument(*this, TemplateLoc, Template, NTTP,
- NewArgs);
+ NewArgs, CTAI.MatchingTTP);
return diagnoseMissingArgument(*this, TemplateLoc, Template,
cast<TemplateTemplateParmDecl>(*Param),
- NewArgs);
+ NewArgs, CTAI.MatchingTTP);
}
return true;
}
@@ -6109,6 +6103,7 @@ bool Sema::CheckTemplateArgumentList(
++Param;
++ArgIdx;
}
+ CTP.Clear();
// If we're performing a partial argument substitution, allow any trailing
// pack expansions; they might be empty. This can happen even if
@@ -6129,8 +6124,7 @@ bool Sema::CheckTemplateArgumentList(
// If we have any leftover arguments, then there were too many arguments.
// Complain and fail.
if (ArgIdx < NumArgs) {
- Diag(TemplateLoc, diag::err_template_arg_list_different_arity)
- << /*too many args*/1
+ Diag(TemplateLoc, diag::err_template_too_many_args)
<< (int)getTemplateNameKindForDiagnostics(TemplateName(Template))
<< Template
<< SourceRange(NewArgs[ArgIdx].getLocation(), NewArgs.getRAngleLoc());
@@ -6558,8 +6552,6 @@ isNullPointerValueTemplateArgument(Sema &S, NamedDecl *Param,
<< Arg->getType() << Arg->getSourceRange();
for (unsigned I = 0, N = Notes.size(); I != N; ++I)
S.Diag(Notes[I].first, Notes[I].second);
-
- S.NoteTemplateParameterLocation(*Param);
return NPV_Error;
}
@@ -6584,8 +6576,7 @@ isNullPointerValueTemplateArgument(Sema &S, NamedDecl *Param,
// The types didn't match, but we know we got a null pointer; complain,
// then recover as if the types were correct.
S.Diag(Arg->getExprLoc(), diag::err_template_arg_wrongtype_null_constant)
- << Arg->getType() << ParamType << Arg->getSourceRange();
- S.NoteTemplateParameterLocation(*Param);
+ << Arg->getType() << ParamType << Arg->getSourceRange();
return NPV_NullPointer;
}
@@ -6594,8 +6585,7 @@ isNullPointerValueTemplateArgument(Sema &S, NamedDecl *Param,
// We could just return NPV_NotNullPointer, but we can print a better
// message with the information we have here.
S.Diag(Arg->getExprLoc(), diag::err_template_arg_invalid)
- << EvalResult.Val.getAsString(S.Context, ParamType);
- S.NoteTemplateParameterLocation(*Param);
+ << EvalResult.Val.getAsString(S.Context, ParamType);
return NPV_Error;
}
@@ -6607,7 +6597,6 @@ isNullPointerValueTemplateArgument(Sema &S, NamedDecl *Param,
<< ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), Code)
<< FixItHint::CreateInsertion(S.getLocForEndOfToken(Arg->getEndLoc()),
")");
- S.NoteTemplateParameterLocation(*Param);
return NPV_NullPointer;
}
@@ -6649,7 +6638,6 @@ CheckTemplateArgumentIsCompatibleWithParameter(Sema &S, NamedDecl *Param,
S.Diag(Arg->getBeginLoc(),
diag::err_template_arg_ref_bind_ignores_quals)
<< ParamType << Arg->getType() << Arg->getSourceRange();
- S.NoteTemplateParameterLocation(*Param);
return true;
}
}
@@ -6667,7 +6655,6 @@ CheckTemplateArgumentIsCompatibleWithParameter(Sema &S, NamedDecl *Param,
else
S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_convertible)
<< ArgIn->getType() << ParamType << Arg->getSourceRange();
- S.NoteTemplateParameterLocation(*Param);
return true;
}
}
@@ -6807,7 +6794,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction(
if (!Entity) {
S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_decl_ref)
<< Arg->getSourceRange();
- S.NoteTemplateParameterLocation(*Param);
return true;
}
@@ -6815,7 +6801,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction(
if (isa<FieldDecl>(Entity) || isa<IndirectFieldDecl>(Entity)) {
S.Diag(Arg->getBeginLoc(), diag::err_template_arg_field)
<< Entity << Arg->getSourceRange();
- S.NoteTemplateParameterLocation(*Param);
return true;
}
@@ -6824,7 +6809,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction(
if (!Method->isStatic()) {
S.Diag(Arg->getBeginLoc(), diag::err_template_arg_method)
<< Method << Arg->getSourceRange();
- S.NoteTemplateParameterLocation(*Param);
return true;
}
}
@@ -6864,7 +6848,6 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction(
if (Var->getType()->isReferenceType()) {
S.Diag(Arg->getBeginLoc(), diag::err_template_arg_reference_var)
<< Var->getType() << Arg->getSourceRange();
- S.NoteTemplateParameterLocation(*Param);
return true;
}
@@ -6884,15 +6867,12 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction(
if (!S.Context.hasSameUnqualifiedType(Entity->getType(),
ParamType.getNonReferenceType())) {
S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer)
- << ParamType;
- S.NoteTemplateParameterLocation(*Param);
+ << ParamType;
return true;
}
S.Diag(AddrOpLoc, diag::err_template_arg_address_of_non_pointer)
- << ParamType
- << FixItHint::CreateRemoval(AddrOpLoc);
- S.NoteTemplateParameterLocation(*Param);
+ << ParamType << FixItHint::CreateRemoval(AddrOpLoc);
ArgType = Entity->getType();
}
@@ -6913,15 +6893,12 @@ static bool CheckTemplateArgumentAddressOfObjectOrFunction(
ArgType = S.Context.getPointerType(Entity->getType());
if (!S.Context.hasSameUnqualifiedType(ArgType, ParamType)) {
S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_address_of)
- << ParamType;
- S.NoteTemplateParameterLocation(*Param);
+ << ParamType;
return true;
}
S.Diag(Arg->getBeginLoc(), diag::err_template_arg_not_address_of)
- << ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), "&");
-
- S.NoteTemplateParameterLocation(*Param);
+ << ParamType << FixItHint::CreateInsertion(Arg->getBeginLoc(), "&");
}
}
@@ -7032,7 +7009,6 @@ static bool CheckTemplateArgumentPointerToMember(
// We can't perform this conversion.
S.Diag(ResultArg->getBeginLoc(), diag::err_template_arg_not_convertible)
<< ResultArg->getType() << ParamType << ResultArg->getSourceRange();
- S.NoteTemplateParameterLocation(*Param);
return true;
}
@@ -7142,7 +7118,6 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
diag::err_non_type_template_parm_type_deduction_failure)
<< Param->getDeclName() << NTTP->getType() << Arg->getType()
<< Arg->getSourceRange();
- NoteTemplateParameterLocation(*Param);
return ExprError();
}
ParamType = SubstAutoTypeDependent(ParamType);
@@ -7154,10 +7129,8 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
// declaration, but here we'll pass the argument location because that's
// where the parameter type is deduced.
ParamType = CheckNonTypeTemplateParameterType(ParamType, Arg->getExprLoc());
- if (ParamType.isNull()) {
- NoteTemplateParameterLocation(*Param);
+ if (ParamType.isNull())
return ExprError();
- }
}
// We should have already dropped all cv-qualifiers by now.
@@ -7197,7 +7170,6 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
// template parameter type.
Diag(StartLoc, diag::err_deduced_non_type_template_arg_type_mismatch)
<< Arg->getType() << ParamType.getUnqualifiedType();
- NoteTemplateParameterLocation(*Param);
return ExprError();
}
@@ -7280,10 +7252,8 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
DeductionArg, ParamType,
StrictCheck ? CCEKind::TempArgStrict : CCEKind::TemplateArg, Param);
assert(!ArgResult.isUnset());
- if (ArgResult.isInvalid()) {
- NoteTemplateParameterLocation(*Param);
+ if (ArgResult.isInvalid())
return ExprError();
- }
} else {
ArgResult = DeductionArg;
}
@@ -7449,7 +7419,6 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
if (!ArgType->isIntegralOrEnumerationType()) {
Diag(Arg->getBeginLoc(), diag::err_template_arg_not_integral_or_enumeral)
<< ArgType << Arg->getSourceRange();
- NoteTemplateParameterLocation(*Param);
return ExprError();
}
if (!Arg->isValueDependent()) {
@@ -7488,7 +7457,6 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
// We can't perform this conversion.
Diag(StartLoc, diag::err_template_arg_not_convertible)
<< Arg->getType() << ParamType << Arg->getSourceRange();
- NoteTemplateParameterLocation(*Param);
return ExprError();
}
@@ -7534,7 +7502,6 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
Diag(Arg->getBeginLoc(), diag::warn_template_arg_negative)
<< toString(OldValue, 10) << toString(Value, 10) << ParamType
<< Arg->getSourceRange();
- NoteTemplateParameterLocation(*Param);
}
// Complain if we overflowed the template parameter's type.
@@ -7545,12 +7512,10 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
RequiredBits = OldValue.getActiveBits() + 1;
else
RequiredBits = OldValue.getSignificantBits();
- if (RequiredBits > AllowedBits) {
+ if (RequiredBits > AllowedBits)
Diag(Arg->getBeginLoc(), diag::warn_template_arg_too_large)
<< toString(OldValue, 10) << toString(Value, 10) << ParamType
<< Arg->getSourceRange();
- NoteTemplateParameterLocation(*Param);
- }
}
QualType T = ParamType->isEnumeralType() ? ParamType : IntegerType;
@@ -7676,7 +7641,6 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
case NPV_NotNullPointer:
Diag(Arg->getExprLoc(), diag::err_template_arg_not_convertible)
<< Arg->getType() << ParamType;
- NoteTemplateParameterLocation(*Param);
return ExprError();
case NPV_Error:
@@ -7704,7 +7668,7 @@ ExprResult Sema::CheckTemplateArgument(NamedDecl *Param, QualType ParamType,
static void DiagnoseTemplateParameterListArityMismatch(
Sema &S, TemplateParameterList *New, TemplateParameterList *Old,
- Sema::TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc);
+ Sema::TemplateParameterListEqualKind Kind);
bool Sema::CheckDeclCompatibleWithTemplateTemplate(
TemplateDecl *Template, TemplateTemplateParmDecl *Param,
@@ -7832,7 +7796,6 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param,
Diag(Arg.getLocation(),
diag::err_template_template_parameter_not_at_least_as_constrained)
<< Template << Param << Arg.getSourceRange();
- Diag(Param->getLocation(), diag::note_entity_declared_at) << Param;
Diag(Template->getLocation(), diag::note_entity_declared_at) << Template;
MaybeEmitAmbiguousAtomicConstraintsDiagnostic(Param, ParamsAC, Template,
TemplateAC);
@@ -7841,25 +7804,24 @@ bool Sema::CheckTemplateTemplateArgument(TemplateTemplateParmDecl *Param,
return false;
}
-static Sema::SemaDiagnosticBuilder noteLocation(Sema &S, const NamedDecl &Decl,
- unsigned HereDiagID,
- unsigned ExternalDiagID) {
- if (Decl.getLocation().isValid())
- return S.Diag(Decl.getLocation(), HereDiagID);
-
+SmallString<128> Sema::toTerseString(const NamedDecl &D) const {
SmallString<128> Str;
llvm::raw_svector_ostream Out(Str);
- PrintingPolicy PP = S.getPrintingPolicy();
+ PrintingPolicy PP = getPrintingPolicy();
PP.TerseOutput = 1;
- Decl.print(Out, PP);
- return S.Diag(Decl.getLocation(), ExternalDiagID) << Out.str();
+ D.print(Out, PP);
+ return Str;
}
+// FIXME: Transform this into a context note.
void Sema::NoteTemplateLocation(const NamedDecl &Decl,
std::optional<SourceRange> ParamRange) {
+ bool HasLoc = Decl.getLocation().isValid();
SemaDiagnosticBuilder DB =
- noteLocation(*this, Decl, diag::note_template_decl_here,
- diag::note_template_decl_external);
+ Diag(Decl.getLocation(), HasLoc ? diag::note_template_decl_here
+ : diag::note_template_decl_external);
+ if (!HasLoc)
+ DB << toTerseString(Decl).str();
if (ParamRange && ParamRange->isValid()) {
assert(Decl.getLocation().isValid() &&
"Parameter range has location when Decl does not");
@@ -7867,11 +7829,6 @@ void Sema::NoteTemplateLocation(const NamedDecl &Decl,
}
}
-void Sema::NoteTemplateParameterLocation(const NamedDecl &Decl) {
- noteLocation(*this, Decl, diag::note_template_param_here,
- diag::note_template_param_external);
-}
-
/// Given a non-type template argument that refers to a
/// declaration and the type of its corresponding non-type template
/// parameter, produce an expression that properly refers to that
@@ -8149,21 +8106,17 @@ Sema::BuildExpressionFromNonTypeTemplateArgument(const TemplateArgument &Arg,
}
/// Match two template parameters within template parameter lists.
-static bool MatchTemplateParameterKind(
- Sema &S, NamedDecl *New,
- const Sema::TemplateCompareNewDeclInfo &NewInstFrom, NamedDecl *Old,
- const NamedDecl *OldInstFrom, bool Complain,
- Sema::TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc) {
+static bool
+MatchTemplateParameterKind(Sema &S, NamedDecl *New,
+ const Sema::TemplateCompareNewDeclInfo &NewInstFrom,
+ NamedDecl *Old, const NamedDecl *OldInstFrom,
+ bool Complain,
+ Sema::TemplateParameterListEqualKind Kind) {
// Check the actual kind (type, non-type, template).
if (Old->getKind() != New->getKind()) {
if (Complain) {
- unsigned NextDiag = diag::err_template_param_different_kind;
- if (TemplateArgLoc.isValid()) {
- S.Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch);
- NextDiag = diag::note_template_param_different_kind;
- }
- S.Diag(New->getLocation(), NextDiag)
- << (Kind != Sema::TPL_TemplateMatch);
+ S.Diag(New->getLocation(), diag::err_template_param_different_kind)
+ << (Kind != Sema::TPL_TemplateMatch);
S.Diag(Old->getLocation(), diag::note_template_prev_declaration)
<< (Kind != Sema::TPL_TemplateMatch);
}
@@ -8177,18 +8130,11 @@ static bool MatchTemplateParameterKind(
// a parameter pack where the template template argument does not.
if (Old->isTemplateParameterPack() != New->isTemplateParameterPack()) {
if (Complain) {
- unsigned NextDiag = diag::err_template_parameter_pack_non_pack;
- if (TemplateArgLoc.isValid()) {
- S.Diag(TemplateArgLoc,
- diag::err_template_arg_template_params_mismatch);
- NextDiag = diag::note_template_parameter_pack_non_pack;
- }
-
unsigned ParamKind = isa<TemplateTypeParmDecl>(New)? 0
: isa<NonTypeTemplateParmDecl>(New)? 1
: 2;
- S.Diag(New->getLocation(), NextDiag)
- << ParamKind << New->isParameterPack();
+ S.Diag(New->getLocation(), diag::err_template_parameter_pack_non_pack)
+ << ParamKind << New->isParameterPack();
S.Diag(Old->getLocation(), diag::note_template_parameter_pack_here)
<< ParamKind << Old->isParameterPack();
}
@@ -8215,13 +8161,8 @@ static bool MatchTemplateParameterKind(
QualType NewType = S.Context.getUnconstrainedType(NewNTTP->getType());
if (!S.Context.hasSameType(OldType, NewType)) {
if (Complain) {
- unsigned NextDiag = diag::err_template_nontype_parm_different_type;
- if (TemplateArgLoc.isValid()) {
- S.Diag(TemplateArgLoc,
- diag::err_template_arg_template_params_mismatch);
- NextDiag = diag::note_template_nontype_parm_different_type;
- }
- S.Diag(NewNTTP->getLocation(), NextDiag)
+ S.Diag(NewNTTP->getLocation(),
+ diag::err_template_nontype_parm_different_type)
<< NewNTTP->getType() << (Kind != Sema::TPL_TemplateMatch);
S.Diag(OldNTTP->getLocation(),
diag::note_template_nontype_parm_prev_declaration)
@@ -8244,8 +8185,7 @@ static bool MatchTemplateParameterKind(
OldTTP->getTemplateParameters(), Complain,
(Kind == Sema::TPL_TemplateMatch
? Sema::TPL_TemplateTemplateParmMatch
- : Kind),
- TemplateArgLoc))
+ : Kind)))
return false;
}
@@ -8297,21 +8237,12 @@ static bool MatchTemplateParameterKind(
/// Diagnose a known arity mismatch when comparing template argument
/// lists.
-static
-void DiagnoseTemplateParameterListArityMismatch(Sema &S,
- TemplateParameterList *New,
- TemplateParameterList *Old,
- Sema::TemplateParameterListEqualKind Kind,
- SourceLocation TemplateArgLoc) {
- unsigned NextDiag = diag::err_template_param_list_different_arity;
- if (TemplateArgLoc.isValid()) {
- S.Diag(TemplateArgLoc, diag::err_template_arg_template_params_mismatch);
- NextDiag = diag::note_template_param_list_different_arity;
- }
- S.Diag(New->getTemplateLoc(), NextDiag)
- << (New->size() > Old->size())
- << (Kind != Sema::TPL_TemplateMatch)
- << SourceRange(New->getTemplateLoc(), New->getRAngleLoc());
+static void DiagnoseTemplateParameterListArityMismatch(
+ Sema &S, TemplateParameterList *New, TemplateParameterList *Old,
+ Sema::TemplateParameterListEqualKind Kind) {
+ S.Diag(New->getTemplateLoc(), diag::err_template_param_list_different_arity)
+ << (New->size() > Old->size()) << (Kind != Sema::TPL_TemplateMatch)
+ << SourceRange(New->getTemplateLoc(), New->getRAngleLoc());
S.Diag(Old->getTemplateLoc(), diag::note_template_prev_declaration)
<< (Kind != Sema::TPL_TemplateMatch)
<< SourceRange(Old->getTemplateLoc(), Old->getRAngleLoc());
@@ -8320,11 +8251,10 @@ void DiagnoseTemplateParameterListArityMismatch(Sema &S,
bool Sema::TemplateParameterListsAreEqual(
const TemplateCompareNewDeclInfo &NewInstFrom, TemplateParameterList *New,
const NamedDecl *OldInstFrom, TemplateParameterList *Old, bool Complain,
- TemplateParameterListEqualKind Kind, SourceLocation TemplateArgLoc) {
+ TemplateParameterListEqualKind Kind) {
if (Old->size() != New->size()) {
if (Complain)
- DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind,
- TemplateArgLoc);
+ DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind);
return false;
}
@@ -8342,21 +8272,18 @@ bool Sema::TemplateParameterListsAreEqual(
OldParm != OldParmEnd; ++OldParm, ++NewParm) {
if (NewParm == NewParmEnd) {
if (Complain)
- DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind,
- TemplateArgLoc);
+ DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind);
return false;
}
if (!MatchTemplateParameterKind(*this, *NewParm, NewInstFrom, *OldParm,
- OldInstFrom, Complain, Kind,
- TemplateArgLoc))
+ OldInstFrom, Complain, Kind))
return false;
}
// Make sure we exhausted all of the arguments.
if (NewParm != NewParmEnd) {
if (Complain)
- DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind,
- TemplateArgLoc);
+ DiagnoseTemplateParameterListArityMismatch(*this, New, Old, Kind);
return false;
}
@@ -8664,7 +8591,6 @@ static bool CheckNonTypeTemplatePartialSpecializationArgs(
S.Diag(IsDefaultArgument ? TemplateNameLoc : ArgExpr->getBeginLoc(),
diag::err_dependent_typed_non_type_arg_in_partial_spec)
<< Param->getType();
- S.NoteTemplateParameterLocation(*Param);
return true;
}
}
@@ -8682,12 +8608,14 @@ bool Sema::CheckTemplatePartialSpecializationArgs(
TemplateParameterList *TemplateParams =
PrimaryTemplate->getTemplateParameters();
+ CheckTemplateParameterRAII CTP(*this);
for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
NonTypeTemplateParmDecl *Param
= dyn_cast<NonTypeTemplateParmDecl>(TemplateParams->getParam(I));
if (!Param)
continue;
+ CTP.setParam(Param);
if (CheckNonTypeTemplatePartialSpecializationArgs(*this, TemplateNameLoc,
Param, &TemplateArgs[I],
1, I >= NumExplicit))
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index f6ee745..cbc64a7 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -2980,7 +2980,7 @@ ConvertDeducedTemplateArgument(Sema &S, NamedDecl *Param,
// arguments).
S.Diag(Param->getLocation(),
diag::err_template_arg_deduced_incomplete_pack)
- << Arg << Param;
+ << Arg << Param;
return true;
}
if (ConvertArg(InnerArg, SugaredPackedArgsBuilder.size()))
@@ -3039,9 +3039,10 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments(
TemplateDeductionInfo &Info, Sema::CheckTemplateArgumentInfo &CTAI,
LocalInstantiationScope *CurrentInstantiationScope,
unsigned NumAlreadyConverted, bool *IsIncomplete) {
+ Sema::CheckTemplateParameterRAII CTP(S);
for (unsigned I = 0, N = TemplateParams->size(); I != N; ++I) {
NamedDecl *Param = TemplateParams->getParam(I);
-
+ CTP.setParam(Param);
// C++0x [temp.arg.explicit]p3:
// A trailing template parameter pack (14.5.3) not otherwise deduced will
// be deduced to an empty sequence of template arguments.
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 1ff94d7..0c8dec5 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -592,6 +592,7 @@ bool Sema::CodeSynthesisContext::isInstantiationRecord() const {
case BuildingDeductionGuides:
case TypeAliasTemplateInstantiation:
case PartialOrderingTTP:
+ case CheckTemplateParameter:
return false;
// This function should never be called when Kind's value is Memoization.
@@ -616,29 +617,30 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
Invalid = true;
return;
}
- Invalid = CheckInstantiationDepth(PointOfInstantiation, InstantiationRange);
+
+ CodeSynthesisContext Inst;
+ Inst.Kind = Kind;
+ Inst.PointOfInstantiation = PointOfInstantiation;
+ Inst.Entity = Entity;
+ Inst.Template = Template;
+ Inst.TemplateArgs = TemplateArgs.data();
+ Inst.NumTemplateArgs = TemplateArgs.size();
+ Inst.DeductionInfo = DeductionInfo;
+ Inst.InstantiationRange = InstantiationRange;
+ Inst.InConstraintSubstitution =
+ Inst.Kind == CodeSynthesisContext::ConstraintSubstitution;
+ if (!SemaRef.CodeSynthesisContexts.empty())
+ Inst.InConstraintSubstitution |=
+ SemaRef.CodeSynthesisContexts.back().InConstraintSubstitution;
+
+ Invalid = SemaRef.pushCodeSynthesisContext(Inst);
if (!Invalid) {
- CodeSynthesisContext Inst;
- Inst.Kind = Kind;
- Inst.PointOfInstantiation = PointOfInstantiation;
- Inst.Entity = Entity;
- Inst.Template = Template;
- Inst.TemplateArgs = TemplateArgs.data();
- Inst.NumTemplateArgs = TemplateArgs.size();
- Inst.DeductionInfo = DeductionInfo;
- Inst.InstantiationRange = InstantiationRange;
- Inst.InConstraintSubstitution =
- Inst.Kind == CodeSynthesisContext::ConstraintSubstitution;
- if (!SemaRef.CodeSynthesisContexts.empty())
- Inst.InConstraintSubstitution |=
- SemaRef.CodeSynthesisContexts.back().InConstraintSubstitution;
-
- SemaRef.pushCodeSynthesisContext(Inst);
-
- AlreadyInstantiating = !Inst.Entity ? false :
- !SemaRef.InstantiatingSpecializations
- .insert({Inst.Entity->getCanonicalDecl(), Inst.Kind})
- .second;
+ AlreadyInstantiating =
+ !Inst.Entity
+ ? false
+ : !SemaRef.InstantiatingSpecializations
+ .insert({Inst.Entity->getCanonicalDecl(), Inst.Kind})
+ .second;
atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, Inst);
}
}
@@ -832,20 +834,43 @@ Sema::InstantiatingTemplate::InstantiatingTemplate(
Sema &SemaRef, SourceLocation ArgLoc, PartialOrderingTTP,
TemplateDecl *PArg, SourceRange InstantiationRange)
: InstantiatingTemplate(SemaRef, CodeSynthesisContext::PartialOrderingTTP,
- ArgLoc, InstantiationRange, PArg) {}
+ ArgLoc, SourceRange(), PArg) {}
+
+Sema::InstantiatingTemplate::InstantiatingTemplate(Sema &SemaRef,
+ CheckTemplateParameter)
+ : InstantiatingTemplate(
+ SemaRef, CodeSynthesisContext::CheckTemplateParameter,
+ /*PointOfInstantiation*/ SourceLocation(),
+ /*InstantiationRange=*/SourceRange(), /*Entity=*/nullptr) {}
-void Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) {
+bool Sema::pushCodeSynthesisContext(CodeSynthesisContext Ctx) {
Ctx.SavedInNonInstantiationSFINAEContext = InNonInstantiationSFINAEContext;
InNonInstantiationSFINAEContext = false;
- CodeSynthesisContexts.push_back(Ctx);
-
- if (!Ctx.isInstantiationRecord())
+ if (!Ctx.isInstantiationRecord()) {
++NonInstantiationEntries;
+ } else {
+ assert(SemaRef.NonInstantiationEntries <=
+ SemaRef.CodeSynthesisContexts.size());
+ if ((SemaRef.CodeSynthesisContexts.size() -
+ SemaRef.NonInstantiationEntries) >
+ SemaRef.getLangOpts().InstantiationDepth) {
+ SemaRef.Diag(Ctx.PointOfInstantiation,
+ diag::err_template_recursion_depth_exceeded)
+ << SemaRef.getLangOpts().InstantiationDepth << Ctx.InstantiationRange;
+ SemaRef.Diag(Ctx.PointOfInstantiation,
+ diag::note_template_recursion_depth)
+ << SemaRef.getLangOpts().InstantiationDepth;
+ return true;
+ }
+ }
+
+ CodeSynthesisContexts.push_back(Ctx);
// Check to see if we're low on stack space. We can't do anything about this
// from here, but we can at least warn the user.
StackHandler.warnOnStackNearlyExhausted(Ctx.PointOfInstantiation);
+ return false;
}
void Sema::popCodeSynthesisContext() {
@@ -907,25 +932,6 @@ static std::string convertCallArgsToString(Sema &S,
return Result;
}
-bool Sema::InstantiatingTemplate::CheckInstantiationDepth(
- SourceLocation PointOfInstantiation,
- SourceRange InstantiationRange) {
- assert(SemaRef.NonInstantiationEntries <=
- SemaRef.CodeSynthesisContexts.size());
- if ((SemaRef.CodeSynthesisContexts.size() -
- SemaRef.NonInstantiationEntries)
- <= SemaRef.getLangOpts().InstantiationDepth)
- return false;
-
- SemaRef.Diag(PointOfInstantiation,
- diag::err_template_recursion_depth_exceeded)
- << SemaRef.getLangOpts().InstantiationDepth
- << InstantiationRange;
- SemaRef.Diag(PointOfInstantiation, diag::note_template_recursion_depth)
- << SemaRef.getLangOpts().InstantiationDepth;
- return true;
-}
-
void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) {
// Determine which template instantiations to skip, if any.
unsigned SkipStart = CodeSynthesisContexts.size(), SkipEnd = SkipStart;
@@ -1276,12 +1282,20 @@ void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) {
case CodeSynthesisContext::PartialOrderingTTP:
DiagFunc(Active->PointOfInstantiation,
PDiag(diag::note_template_arg_template_params_mismatch));
- if (SourceLocation ParamLoc = Active->Entity->getLocation();
- ParamLoc.isValid())
- DiagFunc(ParamLoc, PDiag(diag::note_template_prev_declaration)
- << /*isTemplateTemplateParam=*/true
- << Active->InstantiationRange);
break;
+ case CodeSynthesisContext::CheckTemplateParameter: {
+ if (!Active->Entity)
+ break;
+ const auto &ND = *cast<NamedDecl>(Active->Entity);
+ if (SourceLocation Loc = ND.getLocation(); Loc.isValid()) {
+ DiagFunc(Loc, PDiag(diag::note_template_param_here)
+ << ND.getSourceRange());
+ break;
+ }
+ DiagFunc(SourceLocation(), PDiag(diag::note_template_param_external)
+ << toTerseString(ND).str());
+ break;
+ }
}
}
}
@@ -1325,6 +1339,7 @@ std::optional<TemplateDeductionInfo *> Sema::isSFINAEContext() const {
case CodeSynthesisContext::DefaultTemplateArgumentChecking:
case CodeSynthesisContext::RewritingOperatorAsSpaceship:
case CodeSynthesisContext::PartialOrderingTTP:
+ case CodeSynthesisContext::CheckTemplateParameter:
// A default template argument instantiation and substitution into
// template parameters with arguments for prior parameters may or may
// not be a SFINAE context; look further up the stack.
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 0214078..995465ba 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -16307,6 +16307,8 @@ ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmPackExpr(
template <typename Derived>
ExprResult TreeTransform<Derived>::TransformSubstNonTypeTemplateParmExpr(
SubstNonTypeTemplateParmExpr *E) {
+ Sema::CheckTemplateParameterRAII CTP(SemaRef, E->getParameter());
+
Expr *OrigReplacement = E->getReplacement()->IgnoreImplicitAsWritten();
ExprResult Replacement = getDerived().TransformExpr(OrigReplacement);
if (Replacement.isInvalid())
diff --git a/clang/test/AST/ByteCode/cxx1z.cpp b/clang/test/AST/ByteCode/cxx1z.cpp
index 57f9923..ca5f10f 100644
--- a/clang/test/AST/ByteCode/cxx1z.cpp
+++ b/clang/test/AST/ByteCode/cxx1z.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fexperimental-new-constant-interpreter -std=c++17 -verify=expected,both %s
// RUN: %clang_cc1 -std=c++17 -verify=ref,both %s
-template<typename T, T val> struct A {};
+template<typename T, T val> struct A {}; // both-note 6{{template parameter is declared here}}
namespace Temp {
struct S { int n; };
constexpr S &addr(S &&s) { return s; }
diff --git a/clang/test/AST/ByteCode/cxx20.cpp b/clang/test/AST/ByteCode/cxx20.cpp
index 67bf9a7..ad40de3 100644
--- a/clang/test/AST/ByteCode/cxx20.cpp
+++ b/clang/test/AST/ByteCode/cxx20.cpp
@@ -905,7 +905,7 @@ namespace VirtDtor {
}
namespace TemporaryInNTTP {
- template<auto n> struct B { /* ... */ };
+ template<auto n> struct B { /* ... */ }; // both-note {{template parameter is declared here}}
struct J1 {
J1 *self=this;
};
diff --git a/clang/test/AST/ByteCode/cxx2a.cpp b/clang/test/AST/ByteCode/cxx2a.cpp
index 533173d..a13e675 100644
--- a/clang/test/AST/ByteCode/cxx2a.cpp
+++ b/clang/test/AST/ByteCode/cxx2a.cpp
@@ -242,7 +242,8 @@ namespace GH150705 {
namespace DependentRequiresExpr {
template <class T,
- bool = []() -> bool { // both-error {{not a constant expression}}
+ bool = // both-note {{template parameter is declared here}}
+ []() -> bool { // both-error {{not a constant expression}}
if (requires { T::type; })
return true;
return false;
diff --git a/clang/test/AST/ByteCode/cxx98.cpp b/clang/test/AST/ByteCode/cxx98.cpp
index 1150a4e..c0587e1 100644
--- a/clang/test/AST/ByteCode/cxx98.cpp
+++ b/clang/test/AST/ByteCode/cxx98.cpp
@@ -6,7 +6,7 @@
namespace IntOrEnum {
const int k = 0;
const int &p = k; // both-note {{declared here}}
- template<int n> struct S {};
+ template<int n> struct S {}; // both-note {{template parameter is declared here}}
S<p> s; // both-error {{not an integral constant expression}} \
// both-note {{read of variable 'p' of non-integral, non-enumeration type 'const int &'}}
}
diff --git a/clang/test/AST/ByteCode/records.cpp b/clang/test/AST/ByteCode/records.cpp
index 48cf811..fa8f850 100644
--- a/clang/test/AST/ByteCode/records.cpp
+++ b/clang/test/AST/ByteCode/records.cpp
@@ -1738,7 +1738,7 @@ namespace CtorOfInvalidClass {
// both-error {{must be initialized by a constant expression}}
#if __cplusplus >= 202002L
- template <typename T, auto Q>
+ template <typename T, auto Q>// both-note {{template parameter is declared here}}
concept ReferenceOf = Q;
/// This calls a valid and constexpr copy constructor of InvalidCtor,
/// but should still be rejected.
diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp
index 9632fda..fc4e359 100644
--- a/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp
+++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.unqual/p7.cpp
@@ -33,5 +33,6 @@ namespace test1 {
// specifiers.
namespace test2 {
template <class T> struct bar {};
+ // expected-note@-1 {{template parameter is declared here}}
template <class T> struct foo : bar<foo> {}; // expected-error {{use of class template 'foo' requires template arguments}} expected-note {{template is declared here}}
}
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
index 5bb4708f..2a2b338 100644
--- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.list/p7-0x.cpp
@@ -253,5 +253,5 @@ void P1957R2(void *a, int *b, Agg<int> *c, int Agg<int>::*d) {
Agg<bool> tc = {c}; // expected-error {{cannot be narrowed}} expected-note {{}}
Agg<bool> td = {d}; // expected-error {{cannot be narrowed}} expected-note {{}}
}
-template<bool> struct BoolParam {};
+template<bool> struct BoolParam {}; // expected-note {{template parameter is declared here}}
BoolParam<&P1957R2> bp; // expected-error {{not allowed in a converted constant expression}}
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp
index 805be67..c94bc02 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -806,6 +806,7 @@ namespace cwg49 { // cwg49: 2.8
// since-cxx17-error@#cwg49-c {{non-type template argument is not a constant expression}}
// since-cxx17-note@#cwg49-c {{read of non-constexpr variable 'q' is not allowed in a constant expression}}
// since-cxx17-note@#cwg49-q {{declared here}}
+ // since-cxx17-note@#cwg49-A {{template parameter is declared here}}
} // namespace cwg49
namespace cwg50 { // cwg50: 2.7
@@ -1018,9 +1019,9 @@ namespace cwg62 { // cwg62: 2.9
struct A {
struct { int n; } b;
};
- template<typename T> struct X {};
- template<typename T> T get() { return get<T>(); }
- template<typename T> int take(T) { return 0; }
+ template<typename T> struct X {}; // #cwg62-X
+ template<typename T> T get() { return get<T>(); } // #cwg62-get
+ template<typename T> int take(T) { return 0; } // #cwg62-take
X<A> x1;
A a = get<A>();
@@ -1034,22 +1035,27 @@ namespace cwg62 { // cwg62: 2.9
X<NoNameForLinkagePtr> x2;
// cxx98-error@-1 {{template argument uses unnamed type}}
+ // cxx98-note@#cwg62-X {{template parameter is declared here}}
// cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}}
X<const NoNameForLinkagePtr> x3;
// cxx98-error@-1 {{template argument uses unnamed type}}
+ // cxx98-note@#cwg62-X {{template parameter is declared here}}
// cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}}
NoNameForLinkagePtr p1 = get<NoNameForLinkagePtr>();
// cxx98-error@-1 {{template argument uses unnamed type}}
+ // cxx98-note@#cwg62-get {{template parameter is declared here}}
// cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}}
- // cxx98-note@-3 {{while substituting explicitly-specified template arguments}}
+ // cxx98-note@-4 {{while substituting explicitly-specified template arguments}}
NoNameForLinkagePtr p2 = get<const NoNameForLinkagePtr>();
// cxx98-error@-1 {{template argument uses unnamed type}}
+ // cxx98-note@#cwg62-get {{template parameter is declared here}}
// cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}}
- // cxx98-note@-3 {{while substituting explicitly-specified template arguments}}
+ // cxx98-note@-4 {{while substituting explicitly-specified template arguments}}
int n1 = take(noNameForLinkagePtr);
// cxx98-error@-1 {{template argument uses unnamed type}}
+ // cxx98-note@#cwg62-take {{template parameter is declared here}}
// cxx98-note@#cwg62-unnamed {{unnamed type used in template argument was declared here}}
- // cxx98-note@-3 {{while substituting deduced template arguments}}
+ // cxx98-note@-4 {{while substituting deduced template arguments}}
X<Danger> x4;
@@ -1057,18 +1063,24 @@ namespace cwg62 { // cwg62: 2.9
struct NoLinkage {};
X<NoLinkage> a;
// cxx98-error@-1 {{template argument uses local type }}
+ // cxx98-note@#cwg62-X {{template parameter is declared here}}
X<const NoLinkage> b;
// cxx98-error@-1 {{template argument uses local type }}
+ // cxx98-note@#cwg62-X {{template parameter is declared here}}
get<NoLinkage>();
// cxx98-error@-1 {{template argument uses local type }}
- // cxx98-note@-2 {{while substituting explicitly-specified template arguments}}
+ // cxx98-note@#cwg62-get {{template parameter is declared here}}
+ // cxx98-note@-3 {{while substituting explicitly-specified template arguments}}
get<const NoLinkage>();
// cxx98-error@-1 {{template argument uses local type }}
- // cxx98-note@-2 {{while substituting explicitly-specified template arguments}}
+ // cxx98-note@#cwg62-get {{template parameter is declared here}}
+ // cxx98-note@-3 {{while substituting explicitly-specified template arguments}}
X<void (*)(NoLinkage A::*)> c;
// cxx98-error@-1 {{template argument uses local type }}
+ // cxx98-note@#cwg62-X {{template parameter is declared here}}
X<int NoLinkage::*> d;
// cxx98-error@-1 {{template argument uses local type }}
+ // cxx98-note@#cwg62-X {{template parameter is declared here}}
}
} // namespace cwg62
@@ -1135,10 +1147,11 @@ namespace cwg69 { // cwg69: 9
extern template void f<char>();
// cxx98-error@-1 {{extern templates are a C++11 extension}}
// expected-error@-2 {{explicit instantiation declaration of 'f' with internal linkage}}
- template<void(*)()> struct Q {};
+ template<void(*)()> struct Q {}; // #cwg69-Q
Q<&f<int> > q;
// cxx98-error@-1 {{non-type template argument referring to function 'f<int>' with internal linkage is a C++11 extension}}
// cxx98-note@#cwg69-f {{non-type template argument refers to function here}}
+ // cxx98-note@#cwg69-Q {{template parameter is declared here}}
} // namespace cwg69
namespace cwg70 { // cwg70: 2.7
diff --git a/clang/test/CXX/drs/cwg10xx.cpp b/clang/test/CXX/drs/cwg10xx.cpp
index c5b96c4..10ee505 100644
--- a/clang/test/CXX/drs/cwg10xx.cpp
+++ b/clang/test/CXX/drs/cwg10xx.cpp
@@ -43,6 +43,7 @@ namespace cwg1004 { // cwg1004: 5
template<class T, template<class> class U = T::template A> struct Third { };
// expected-error@-1 {{is a constructor name}}
// expected-note@#cwg1004-t {{in instantiation of default argument}}
+ // expected-note@-3 {{template parameter is declared here}}
Third<A<int> > t; // #cwg1004-t
} // namespace cwg1004
diff --git a/clang/test/CXX/drs/cwg13xx.cpp b/clang/test/CXX/drs/cwg13xx.cpp
index ad6ee01..0fae345 100644
--- a/clang/test/CXX/drs/cwg13xx.cpp
+++ b/clang/test/CXX/drs/cwg13xx.cpp
@@ -180,6 +180,7 @@ namespace cwg1315 { // cwg1315: partial
// dependent type of T::value is not the same as 'int'.
// A core issue will be opened to decide what is supposed to happen here.
template <typename T, int I> struct C;
+ // expected-note@-1 {{template parameter is declared here}}
template <typename T> struct C<T, T::value>;
// expected-error@-1 {{type of specialized non-type template argument depends on a template parameter of the partial specialization}}
} // namespace cwg1315
diff --git a/clang/test/CXX/drs/cwg18xx.cpp b/clang/test/CXX/drs/cwg18xx.cpp
index 9948075..0d46eab 100644
--- a/clang/test/CXX/drs/cwg18xx.cpp
+++ b/clang/test/CXX/drs/cwg18xx.cpp
@@ -26,6 +26,7 @@ S<i> V; // #cwg1801-S-i
// cxx98-14-error@-1 {{non-type template argument does not refer to any declaration}}
// cxx98-14-note@#cwg1801-S {{template parameter is declared here}}
// cxx17-error@#cwg1801-S-i {{non-type template argument refers to subobject '.i'}}
+// cxx17-note@#cwg1801-S {{template parameter is declared here}}
} // namespace cwg1801
namespace cwg1802 { // cwg1802: 3.1
diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp
index c9dce77..e15a225 100644
--- a/clang/test/CXX/drs/cwg1xx.cpp
+++ b/clang/test/CXX/drs/cwg1xx.cpp
@@ -26,18 +26,22 @@ namespace cwg100 { // cwg100: 2.7
// cxx98-14-error@#cwg100-a {{non-type template argument does not refer to any declaration}}
// cxx98-14-note@#cwg100-A {{template parameter is declared here}}
// since-cxx17-error@#cwg100-a {{pointer to string literal is not allowed in a template argument}}
+ // since-cxx17-note@#cwg100-A {{template parameter is declared here}}
B<"bar"> b; // #cwg100-b
// cxx98-14-error@#cwg100-b {{non-type template argument does not refer to any declaration}}
// cxx98-14-note@#cwg100-B {{template parameter is declared here}}
// since-cxx17-error@#cwg100-b {{reference to string literal is not allowed in a template argument}}
+ // since-cxx17-note@#cwg100-B {{template parameter is declared here}}
C<"baz"> c; // #cwg100-c
// cxx98-14-error@#cwg100-c {{non-type template argument does not refer to any declaration}}
// cxx98-14-note@#cwg100-C {{template parameter is declared here}}
// since-cxx17-error@#cwg100-c {{pointer to subobject of string literal is not allowed in a template argument}}
+ // since-cxx17-note@#cwg100-C {{template parameter is declared here}}
D<*"quux"> d; // #cwg100-d
// cxx98-14-error@#cwg100-d {{non-type template argument does not refer to any declaration}}
// cxx98-14-note@#cwg100-D {{template parameter is declared here}}
// since-cxx17-error@#cwg100-d {{reference to subobject of string literal is not allowed in a template argument}}
+ // since-cxx17-note@#cwg100-D {{template parameter is declared here}}
} // namespace cwg100
namespace cwg101 { // cwg101: 3.5
@@ -152,15 +156,17 @@ namespace cwg112 { // cwg112: 3.1
volatile T a2[1] = {};
const Arr a3 = {}; // #cwg112-a3
volatile Arr a4 = {};
- template<const volatile T*> struct X {};
+ template<const volatile T*> struct X {}; // #cwg112-X
// FIXME: Test this somehow in C++11 and on.
X<a1> x1;
// cxx98-error@-1 {{non-type template argument referring to object 'a1' with internal linkage is a C++11 extension}}
// cxx98-note@#cwg112-a1 {{non-type template argument refers to object here}}
+ // cxx98-note@#cwg112-X {{template parameter is declared here}}
X<a2> x2;
X<a3> x3;
// cxx98-error@-1 {{non-type template argument referring to object 'a3' with internal linkage is a C++11 extension}}
// cxx98-note@#cwg112-a3 {{non-type template argument refers to object here}}
+ // cxx98-note@#cwg112-X {{template parameter is declared here}}
X<a4> x4;
} // namespace cwg112
@@ -634,7 +640,7 @@ namespace example3 {
struct Base {
private:
static const int i = 10; // #cwg138-ex3-Base-i
-
+
public:
struct Data;
// Elaborated type specifier is not the sole constituent of declaration,
@@ -648,7 +654,7 @@ public:
};
};
struct Data {
- void f() {
+ void f() {
int i2 = Base::i;
// expected-error@-1 {{'i' is a private member of 'cwg138::example3::Base'}}
// expected-note@#cwg138-ex3-Base-i {{declared private here}}
@@ -1308,8 +1314,8 @@ namespace cwg184 { // cwg184: 2.7
template<template<typename TT> class T> void A<T>::f() { // #cwg184-T
T<> t;
- // expected-error@-1 {{too few template arguments for template template parameter 'T'}}
- // expected-note@#cwg184-T {{template is declared here}}
+ // expected-error@-1 {{missing template argument for template parameter}}
+ // expected-note@#cwg184-T {{template parameter is declared here}}
}
template<template<typename TT = char> class T> void A<T>::g() {
diff --git a/clang/test/CXX/drs/cwg20xx.cpp b/clang/test/CXX/drs/cwg20xx.cpp
index 141a101..fd31a51f 100644
--- a/clang/test/CXX/drs/cwg20xx.cpp
+++ b/clang/test/CXX/drs/cwg20xx.cpp
@@ -27,7 +27,7 @@ int b = __builtin_addressof(b2)->foo;
// cwg2009: na
namespace cwg2026 { // cwg2026: 11
- template<int> struct X {};
+ template<int> struct X {}; // #cwg2026-X
const int a = a + 1; // #cwg2026-a
// expected-warning@-1 {{variable 'a' is uninitialized when used within its own initialization}}
@@ -35,9 +35,11 @@ namespace cwg2026 { // cwg2026: 11
// cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}}
// cxx98-note@-2 {{initializer of 'a' is not a constant expression}}
// cxx98-note@#cwg2026-a {{declared here}}
+ // cxx98-note@#cwg2026-X {{template parameter is declared here}}
// since-cxx11-error@#cwg2026-xa {{non-type template argument is not a constant expression}}
// since-cxx11-note@#cwg2026-xa {{initializer of 'a' is not a constant expression}}
// since-cxx11-note@#cwg2026-a {{declared here}}
+ // since-cxx11-note@#cwg2026-X {{template parameter is declared here}}
#if __cplusplus >= 201103L
constexpr int b = b;
@@ -65,9 +67,11 @@ namespace cwg2026 { // cwg2026: 11
// cxx98-error@-1 {{non-type template argument of type 'int' is not an integral constant expression}}
// cxx98-note@-2 {{initializer of 'e' is not a constant expression}}
// cxx98-note@#cwg2026-e {{declared here}}
+ // cxx98-note@#cwg2026-X {{template parameter is declared here}}
// since-cxx11-error@#cwg2026-xe {{non-type template argument is not a constant expression}}
// since-cxx11-note@#cwg2026-xe {{initializer of 'e' is not a constant expression}}
// since-cxx11-note@#cwg2026-e {{declared here}}
+ // since-cxx11-note@#cwg2026-X {{template parameter is declared here}}
#if __cplusplus >= 201103L
static constexpr int f = f;
@@ -149,7 +153,7 @@ namespace cwg2076 { // cwg2076: 13
operator string_view() const;
};
- void foo(const string &); // #cwg2076-foo
+ void foo(const string &); // #cwg2076-foo
void bar(string_view); // #cwg2076-bar
void func(const string &arg) {
@@ -429,7 +433,7 @@ int f()
return 0;
}
} // namespace GH42233
-} // namespace cwg2091
+} // namespace cwg2091
namespace cwg2094 { // cwg2094: 5
struct A { int n; };
diff --git a/clang/test/CXX/drs/cwg21xx.cpp b/clang/test/CXX/drs/cwg21xx.cpp
index 42a7c4d..97bf320 100644
--- a/clang/test/CXX/drs/cwg21xx.cpp
+++ b/clang/test/CXX/drs/cwg21xx.cpp
@@ -24,7 +24,7 @@ namespace std {
}
namespace cwg2100 { // cwg2100: 12
- template<const int *P, bool = true> struct X {};
+ template<const int *P, bool = true> struct X {}; // #cwg2100-X
template<typename T> struct A {
static const int n = 1;
int f() {
@@ -35,6 +35,7 @@ namespace cwg2100 { // cwg2100: 12
return X<&n>::n; // ok, value-dependent
// cxx98-14-error@-1 {{non-type template argument refers to object 'n' that does not have linkage}}
// cxx98-14-note@#cwg2100-n {{non-type template argument refers to object here}}
+ // cxx98-14-note@#cwg2100-X {{template parameter is declared here}}
}
};
template<const int *P> struct X<P> {
diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp
index bbd87c0..423322a 100644
--- a/clang/test/CXX/drs/cwg3xx.cpp
+++ b/clang/test/CXX/drs/cwg3xx.cpp
@@ -317,18 +317,20 @@ namespace cwg319 { // cwg319: no
typedef int (*pa)[n1];
pa parr; // ok, type has linkage despite using 'n1'
- template<typename> struct X {};
+ template<typename> struct X {}; // #cwg319-X
void f() {
struct A { int n; };
extern A a; // FIXME: ill-formed
X<A> xa;
// cxx98-error@-1 {{template argument uses local type 'A'}}
+ // cxx98-note@#cwg319-X {{template parameter is declared here}}
typedef A B;
extern B b; // FIXME: ill-formed
X<B> xb;
// cxx98-error@-1 {{template argument uses local type 'A'}}
+ // cxx98-note@#cwg319-X {{template parameter is declared here}}
const int n = 1;
typedef int (*C)[n];
@@ -997,6 +999,7 @@ namespace cwg354 { // cwg354: 3.1 c++11
// since-cxx17-note@#cwg354-ptr_mem {{template parameter is declared here}}
ptr_mem<(int S::*)0> m1;
// cxx98-error@-1 {{non-type template argument is not a pointer to member constant}}
+ // cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}}
ptr_mem<(float S::*)0> m2; // #cwg354-m2
// cxx98-error@#cwg354-m2 {{non-type template argument of type 'float S::*' cannot be converted to a value of type 'int S::*'}}
// cxx98-note@#cwg354-ptr_mem {{template parameter is declared here}}
@@ -1502,7 +1505,7 @@ namespace cwg389 { // cwg389: no
typedef struct {} const C; // #cwg389-C
typedef enum {} const D; // #cwg389-D
};
- template<typename> struct T {};
+ template<typename> struct T {}; // #cwg389-T
struct WithLinkage1 {};
enum WithLinkage2 {};
@@ -1543,18 +1546,23 @@ namespace cwg389 { // cwg389: no
typedef T<WithoutLinkage1> BadArg1;
// expected-error@-1 {{template argument uses unnamed type}}
+ // expected-note@#cwg389-T {{template parameter is declared here}}
// expected-note@#cwg389-no-link-1 {{unnamed type used in template argument was declared here}}
typedef T<WithoutLinkage2> BadArg2;
// expected-error@-1 {{template argument uses unnamed type}}
+ // expected-note@#cwg389-T {{template parameter is declared here}}
// expected-note@#cwg389-no-link-2 {{unnamed type used in template argument was declared here}}
typedef T<WithoutLinkage3> BadArg3;
// expected-error@-1 {{template argument uses unnamed type}}
+ // expected-note@#cwg389-T {{template parameter is declared here}}
// expected-note@#cwg389-C {{unnamed type used in template argument was declared here}}
typedef T<WithoutLinkage4> BadArg4;
// expected-error@-1 {{template argument uses unnamed type}}
+ // expected-note@#cwg389-T {{template parameter is declared here}}
// expected-note@#cwg389-D {{unnamed type used in template argument was declared here}}
typedef T<WithoutLinkage5> BadArg5;
// expected-error@-1 {{template argument uses unnamed type}}
+ // expected-note@#cwg389-T {{template parameter is declared here}}
// expected-note@#cwg389-C {{unnamed type used in template argument was declared here}}
#endif
diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp
index 8497f97..e5c9efa 100644
--- a/clang/test/CXX/drs/cwg4xx.cpp
+++ b/clang/test/CXX/drs/cwg4xx.cpp
@@ -52,12 +52,15 @@ namespace cwg401 { // cwg401: 2.8
// expected-error@#cwg401-A {{'type' is a private member of 'cwg401::C'}}
// expected-note@#cwg402-friend-A-C {{in instantiation of default argument for 'A<C>' required here}}
// expected-note@#cwg402-C-type {{implicitly declared private here}}
+ // expected-note@#cwg401-A {{template parameter is declared here}}
// expected-error@#cwg401-A {{'type' is a protected member of 'cwg401::B'}}
// expected-note@#cwg402-b {{in instantiation of default argument for 'A<B>' required here}}
// expected-note@#cwg402-B-type {{declared protected here}}
+ // expected-note@#cwg401-A {{template parameter is declared here}}
// expected-error@#cwg401-A {{'type' is a private member of 'cwg401::D'}}
// expected-note@#cwg402-d {{in instantiation of default argument for 'A<D>' required here}}
// expected-note@#cwg402-D-type {{implicitly declared private here}}
+ // expected-note@#cwg401-A {{template parameter is declared here}}
class B {
protected:
typedef int type; // #cwg402-B-type
@@ -89,8 +92,9 @@ namespace cwg401 { // cwg401: 2.8
// to not treat the default template argument as a SFINAE context in C++98.
template<class T, class U = typename T::type> void f(T) {} // #cwg402-f
// cxx98-error@-1 {{default template arguments for a function template are a C++11 extension}}
- // cxx98-error@-2 {{'type' is a protected member of 'cwg401::B'}}
- // cxx98-note@-3 {{in instantiation of default argument for 'f<B>' required here}}
+ // cxx98-note@-2 {{template parameter is declared here}}
+ // cxx98-error@-3 {{'type' is a protected member of 'cwg401::B'}}
+ // cxx98-note@-4 {{in instantiation of default argument for 'f<B>' required here}}
// cxx98-note@#cwg402-f-b {{while substituting deduced template arguments into function template 'f' [with T = B, U = (no value)]}}
// cxx98-note@#cwg402-B-type {{declared protected here}}
void g(B b) { f(b); } // #cwg402-f-b
@@ -645,15 +649,17 @@ namespace cwg431 { // cwg431: 2.8
} // namespace cwg431
namespace cwg432 { // cwg432: 3.0
- template<typename T> struct A {};
+ template<typename T> struct A {}; // #cwg432-A
template<typename T> struct B : A<B> {};
// expected-error@-1 {{use of class template 'B' requires template arguments}}
- // expected-note@-2 {{template is declared here}}
+ // expected-note@#cwg432-A {{template parameter is declared here}}
+ // expected-note@-3 {{template is declared here}}
template<typename T> struct C : A<C<T> > {};
#if __cplusplus >= 201103L
template<typename T> struct D : decltype(A<D>()) {};
// since-cxx11-error@-1 {{use of class template 'D' requires template arguments}}
- // since-cxx11-note@-2 {{template is declared here}}
+ // since-cxx11-note@#cwg432-A {{template parameter is declared here}}
+ // since-cxx11-note@-3 {{template is declared here}}
#endif
} // namespace cwg432
@@ -1386,6 +1392,7 @@ namespace cwg487 { // cwg487: 2.7
namespace cwg488 { // cwg488: 2.9 c++11
template <typename T> void f(T);
+ // cxx98-note@-1 {{template parameter is declared here}}
void f(int);
void g() {
// FIXME: It seems CWG thought this should be a SFINAE failure prior to
diff --git a/clang/test/CXX/drs/cwg6xx.cpp b/clang/test/CXX/drs/cwg6xx.cpp
index 11eb0bf..c17e1e2 100644
--- a/clang/test/CXX/drs/cwg6xx.cpp
+++ b/clang/test/CXX/drs/cwg6xx.cpp
@@ -79,10 +79,11 @@ namespace cwg602 { // cwg602: 2.7
} // namespace cwg602
namespace cwg603 { // cwg603: 3.1
- template<unsigned char> struct S {};
+ template<unsigned char> struct S {}; // #cwg603-S
typedef S<'\001'> S1;
typedef S<(1ul << __CHAR_BIT__) + 1> S1;
// since-cxx11-error@-1 {{non-type template argument evaluates to 257, which cannot be narrowed to type 'unsigned char'}}
+ // since-cxx11-note@#cwg603-S {{template parameter is declared here}}
} // namespace cwg603
// cwg604: na
diff --git a/clang/test/CXX/expr/expr.const/p3-0x.cpp b/clang/test/CXX/expr/expr.const/p3-0x.cpp
index 3eedef3..f40e1af 100644
--- a/clang/test/CXX/expr/expr.const/p3-0x.cpp
+++ b/clang/test/CXX/expr/expr.const/p3-0x.cpp
@@ -4,7 +4,7 @@
// A converted constant expression of type T is a core constant expression,
int nonconst = 8; // expected-note 3 {{here}}
enum NonConstE : unsigned char { NCE = nonconst }; // expected-error {{enumerator value is not a constant expression}} expected-note {{read of non-const}}
-template<int = nonconst> struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}}
+template<int = nonconst> struct NonConstT {}; // expected-error {{non-type template argument is not a constant expression}} expected-note {{read of non-const}} expected-note {{template parameter is declared here}}
void NonConstF() {
switch (nonconst) {
case nonconst: // expected-error {{case value is not a constant expression}} expected-note {{read of non-const}}
@@ -66,7 +66,7 @@ enum class EEE : unsigned short {
e = 123456, // expected-error {{enumerator value evaluates to 123456, which cannot be narrowed to type 'unsigned short'}}
f = -3 // expected-error {{enumerator value evaluates to -3, which cannot be narrowed to type 'unsigned short'}}
};
-template<unsigned char> using A = int; // cxx17-note 2{{template parameter is declared here}}
+template<unsigned char> using A = int; // expected-note 4{{template parameter is declared here}}
using Int = A<E6>;
using Int = A<EE::EE32>; // expected-error {{not implicitly convertible}}
@@ -79,7 +79,8 @@ using Int = A<-3>; // expected-error {{template argument evaluates to -3, which
// integral conversions as well as boolean conversions.
// FIXME: Per core issue 1407, this is not correct.
template<typename T, T v> struct Val { static constexpr T value = v; };
-// cxx17-note@-1 2{{template parameter is declared here}}
+// cxx17-note@-1 1{{template parameter is declared here}}
+// expected-note@-2 2{{template parameter is declared here}}
static_assert(Val<bool, E1>::value == 1, ""); // ok
static_assert(Val<bool, '\0'>::value == 0, ""); // ok
static_assert(Val<bool, U'\1'>::value == 1, ""); // ok
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
index 5433cfb..2572e76 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/type-requirement.cpp
@@ -77,7 +77,7 @@ using r2i3 = r2<int, int>; // expected-error{{constraints not satisfied for clas
namespace ns2 {
template<typename T, typename U> struct identity {};
- template<typename... Ts> requires requires { typename identity<Ts...>; } // expected-note 2{{because 'typename identity<Ts...>' would be invalid: too few template arguments for class template 'identity'}}
+ template<typename... Ts> requires requires { typename identity<Ts...>; } // expected-note 2{{because 'typename identity<Ts...>' would be invalid: missing template argument for template parameter}}
struct r4 {};
using r4i1 = r4<int>; // expected-error{{constraints not satisfied for class template 'r4' [with Ts = <int>]}}
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp
index 692958e..332f69b 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1-11.cpp
@@ -9,7 +9,7 @@ template<int *ip> struct IP { // expected-note 6 {{template parameter is declar
IP<ip> *ip2;
};
-template<int &ip> struct IR {};
+template<int &ip> struct IR {}; // expected-note {{template parameter is declared here}}
constexpr std::nullptr_t get_nullptr() { return nullptr; }
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
index 73c7c75..b6a0fdd 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p1.cpp
@@ -31,16 +31,16 @@ namespace non_type_tmpl_param {
// omitted if the name refers to a function or array and shall be omitted
// if the corresopnding template-parameter is a reference; or
namespace addr_of_obj_or_func {
- template <int* p> struct X0 { }; // expected-note 5{{here}}
+ template <int* p> struct X0 { }; // expected-note 5{{here}} cxx17-note 2{{here}}
#if __cplusplus >= 201103L
// precxx17-note@-2 2{{template parameter is declared here}}
#endif
- template <int (*fp)(int)> struct X1 { }; // cxx17-note {{here}}
+ template <int (*fp)(int)> struct X1 { }; // cxx17-note {{here}} precxx17-note{{here}}
#if __cplusplus <= 199711L
// precxx17-note@-2 {{here}}
#endif
- template <int &p> struct X2 { }; // expected-note 4{{here}}
+ template <int &p> struct X2 { }; // expected-note 5{{here}}
template <const int &p> struct X2k { }; // expected-note {{here}}
template <int (&fp)(int)> struct X3 { }; // expected-note 4{{here}}
@@ -180,6 +180,7 @@ namespace addr_of_obj_or_func {
namespace bad_args {
template <int* N> struct X0 { }; // precxx17-note 4{{template parameter is declared here}}
+ // cxx17-note@-1 3{{template parameter is declared here}}
int i = 42;
X0<&i + 2> x0a; // precxx17-error{{non-type template argument does not refer to any declaration}} \
cxx17-error {{non-type template argument is not a constant expression}} \
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
index 4b93d86..d35a298 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
@@ -49,7 +49,7 @@ namespace pointer_to_object_parameters {
operator int() const;
};
- template<X const *Ptr> struct A2; // expected-note 0-1{{template parameter is declared here}}
+ template<X const *Ptr> struct A2; // expected-note 1-2{{template parameter is declared here}}
X *X_ptr; // expected-note 0-1{{declared here}}
X an_X;
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
index 3caed04..2638bef 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-0x.cpp
@@ -20,39 +20,39 @@ eval<E<int, float>> eE; // expected-error{{implicit instantiation of undefined t
template<
template <int ...N> // expected-error {{cannot be narrowed from type 'int' to 'short'}}
// expected-error@-1 {{conversion from 'int' to 'void *' is not allowed in a converted constant expression}}
- class TT // expected-note 2{{previous template template parameter is here}}
+ class TT // expected-note 2{{template parameter is declared here}}
> struct X0 { };
template<int I, int J, int ...Rest> struct X0a;
template<int ...Rest> struct X0b;
template<int I, long J> struct X0c;
-template<int I, short J> struct X0d;
-template<int I, void *J> struct X0e; // expected-note{{template parameter is declared here}}
+template<int I, short J> struct X0d; // expected-note {{template parameter is declared here}}
+template<int I, void *J> struct X0e; // expected-note {{template parameter is declared here}}
X0<X0a> inst_x0a;
X0<X0b> inst_x0b;
X0<X0c> inst_x0c;
-X0<X0d> inst_x0d; // expected-note {{has different template parameters}}
-X0<X0e> inst_x0e; // expected-note{{template template argument has different template parameters than its corresponding template template parameter}}
+X0<X0d> inst_x0d; // expected-note {{template template argument is incompatible}}
+X0<X0e> inst_x0e; // expected-note {{template template argument is incompatible}}
template<typename T,
template <T ...N> // expected-error {{conversion from 'short' to 'void *' is not allowed in a converted constant expression}}
// expected-error@-1 {{cannot be narrowed from type 'int' to 'short'}}
- class TT // expected-note 2{{previous template template parameter is here}}
+ class TT // expected-note 2{{template parameter is declared here}}
> struct X1 { };
template<int I, int J, int ...Rest> struct X1a;
template<long I, long ...Rest> struct X1b;
template<short I, short J> struct X1c;
-template<short I, long J> struct X1d;
-template<short I, void *J> struct X1e; // expected-note{{template parameter is declared here}}
+template<short I, long J> struct X1d; // expected-note {{template parameter is declared here}}
+template<short I, void *J> struct X1e; // expected-note {{template parameter is declared here}}
X1<int, X1a> inst_x1a;
X1<long, X1b> inst_x1b;
X1<short, X1c> inst_x1c;
X1<short, X1d> inst_sx1d;
-X1<int, X1d> inst_ix1d; // expected-note {{has different template parameters}}
-X1<short, X1e> inst_x1e; // expected-note {{has different template parameters}}
+X1<int, X1d> inst_ix1d; // expected-note {{template template argument is incompatible}}
+X1<short, X1e> inst_x1e; // expected-note {{template template argument is incompatible}}
template <int> class X2; // expected-note{{template is declared here}} \
// expected-note{{template is declared here}}
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
index 342ffba..5570a7f 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.template/p3-2a.cpp
@@ -13,12 +13,12 @@ template<F> struct W { }; // #W
S1<X> s11;
S1<Y> s12;
// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
-// expected-note@#S1 {{'P' declared here}}
+// expected-note@#S1 {{template parameter is declared here}}
// expected-note@#Y {{'Y' declared here}}
S1<Z> s13;
S1<W> s14;
// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
-// expected-note@#S1 {{'P' declared here}}
+// expected-note@#S1 {{template parameter is declared here}}
// expected-note@#W {{'W' declared here}}
// expected-note@#F 1-2{{similar constraint expressions not considered equivalent}}
// expected-note@#C 1-2{{similar constraint}}
@@ -43,12 +43,12 @@ template<template<typename T> requires C<T> class P> struct S4 { }; // #S4
S4<X> s41;
S4<Y> s42;
// expected-error@-1 {{template template argument 'Y' is more constrained than template template parameter 'P'}}
-// expected-note@#S4 {{'P' declared here}}
+// expected-note@#S4 {{template parameter is declared here}}
// expected-note@#Y {{'Y' declared here}}
S4<Z> s43;
S4<W> s44;
// expected-error@-1 {{template template argument 'W' is more constrained than template template parameter 'P'}}
-// expected-note@#S4 {{'P' declared here}}
+// expected-note@#S4 {{template parameter is declared here}}
// expected-note@#W {{'W' declared here}}
template<template<typename T> requires C<T> typename U> struct S5 {
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp
index 650f858..65f3e17 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.type/p2.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify -Wvla %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98 -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
template<class T> struct A {
@@ -13,7 +13,8 @@ template<typename T> struct B {
};
B<function> b; // expected-note{{instantiation of}}
-template <typename T> int f0(void *, const T&); // expected-note{{candidate template ignored: substitution failure}}
+template <typename T> // #f0-temphead
+int f0(void *, const T&); // expected-note{{candidate template ignored: substitution failure}}
enum {e};
// expected-note@-1 {{unnamed type used in template argument was declared here}}
@@ -22,6 +23,7 @@ void test_f0(int n) { // #here
#if __cplusplus <= 199711L
// expected-warning@-2 {{template argument uses unnamed type}}
// expected-note@-3 {{while substituting deduced template arguments}}
+ // expected-note@#f0-temphead {{template parameter is declared here}}
#endif
int vla[n]; // expected-warning {{variable length arrays in C++ are a Clang extension}}
@@ -33,9 +35,9 @@ void test_f0(int n) { // #here
}
namespace N0 {
- template <typename R, typename A1> void f0(R (*)(A1));
- template <typename T> int f1(T);
- template <typename T, typename U> int f1(T, U);
+ template <typename R, typename A1> void f0(R (*)(A1)); // #f0
+ template <typename T> int f1(T); // #f1-1
+ template <typename T, typename U> int f1(T, U); // #f1-2
enum {e1};
#if __cplusplus <= 199711L
// expected-note@-2 2{{unnamed type used in template argument was declared here}}
@@ -51,7 +53,7 @@ namespace N0 {
// expected-note@-2 {{unnamed type used in template argument was declared here}}
#endif
- template<typename T> struct X;
+ template<typename T> struct X; // cxx98-note {{template parameter is declared here}}
template<typename T> struct X<T*> { };
void f() {
@@ -59,24 +61,28 @@ namespace N0 {
#if __cplusplus <= 199711L
// expected-warning@-2 {{template argument uses unnamed type}}
// expected-note@-3 {{while substituting deduced template arguments}}
+ // expected-note@#f0 {{template parameter is declared here}}
#endif
&f1<__typeof__(e1)>);
#if __cplusplus <= 199711L
// expected-warning@-2 {{template argument uses unnamed type}}
// expected-note@-3 {{while substituting explicitly-specified template arguments}}
+ // expected-note@#f1-1 {{template parameter is declared here}}
#endif
int (*fp1)(int, __typeof__(e2)) = f1;
#if __cplusplus <= 199711L
// expected-warning@-2 {{template argument uses unnamed type}}
// expected-note@-3 {{while substituting deduced template arguments}}
+ // expected-note@#f1-2 {{template parameter is declared here}}
#endif
f1(e2);
#if __cplusplus <= 199711L
// expected-warning@-2 {{template argument uses unnamed type}}
// expected-note@-3 {{while substituting deduced template arguments}}
+ // expected-note@#f1-1 {{template parameter is declared here}}
#endif
f1(e2);
diff --git a/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp
index 388a80e..cf01e40 100644
--- a/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.class.spec/p8-1y.cpp
@@ -25,7 +25,7 @@ template<typename Outer> struct X {
template<typename Inner> static int y<Outer>; // expected-error 3{{cannot be deduced}} expected-note 3{{'Inner'}}
template<typename Inner> static int y<Inner>; // expected-error {{does not specialize}}
- template<typename, int> static int z;
+ template<typename, int> static int z; // expected-note {{template parameter is declared here}}
template<Outer N> static int z<int, N>; // expected-error {{not implicitly convertible}}
};
template<typename Outer> template<typename Inner> int X<Outer>::y<Outer>; // expected-error {{cannot be deduced}} expected-note {{'Inner'}}
@@ -33,4 +33,4 @@ template<typename Outer> template<typename Inner> int X<Outer>::y<Inner>; // exp
template<> template<typename Inner> int X<int>::y<Inner>; // expected-error {{does not specialize}} expected-note {{instantiation of}}
X<int> xi;
-X<int*> xf; // expected-note {{instantiation of}}
+X<int*> xf; // expected-note 2{{instantiation of}}
diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
index ab4c663d..cab5c96 100644
--- a/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/fixed-expansion.cpp
@@ -14,10 +14,10 @@ struct is_same<T, T> {
};
namespace ExpandIntoFixed {
- template<typename T,
- typename U,
- typename V = pair<T, U>,
- typename W = V*>
+ template<typename T,
+ typename U,
+ typename V = pair<T, U>,
+ typename W = V*>
class X0 { };
template<typename ...Ts>
@@ -26,24 +26,24 @@ namespace ExpandIntoFixed {
typedef X0<Ts...> type;
};
- static_assert(is_same<X1<int, int>::type,
+ static_assert(is_same<X1<int, int>::type,
X0<int, int, pair<int, int>, pair<int, int>*>>::value,
"fails with two default arguments");
- static_assert(is_same<X1<int, int, float>::type,
+ static_assert(is_same<X1<int, int, float>::type,
X0<int, int, float, float*>>::value,
"fails with one default argument");
- static_assert(is_same<X1<int, int, float, double>::type,
+ static_assert(is_same<X1<int, int, float, double>::type,
X0<int, int, float, double>>::value,
"fails with no default arguments");
}
namespace ExpandIntoFixedShifted {
- template<typename T,
- typename U,
- typename V = pair<T, U>,
- typename W = V*>
+ template<typename T,
+ typename U,
+ typename V = pair<T, U>,
+ typename W = V*>
class X0 { };
template<typename ...Ts>
@@ -52,15 +52,15 @@ namespace ExpandIntoFixedShifted {
typedef X0<char, Ts...> type;
};
- static_assert(is_same<X1<int>::type,
+ static_assert(is_same<X1<int>::type,
X0<char, int, pair<char, int>, pair<char, int>*>>::value,
"fails with two default arguments");
- static_assert(is_same<X1<int, float>::type,
+ static_assert(is_same<X1<int, float>::type,
X0<char, int, float, float*>>::value,
"fails with one default argument");
- static_assert(is_same<X1<int, float, double>::type,
+ static_assert(is_same<X1<int, float, double>::type,
X0<char, int, float, double>>::value,
"fails with no default arguments");
}
@@ -76,11 +76,11 @@ namespace Deduction {
}
namespace PR9021a {
- template<typename, typename>
+ template<typename, typename>
struct A { };
template<typename ...T>
- struct B {
+ struct B {
A<T...> a1;
};
@@ -93,9 +93,9 @@ namespace PR9021b {
template<class, class>
struct t2
{
-
+
};
-
+
template<template<class...> class M>
struct m
{
@@ -107,14 +107,14 @@ namespace PR9021b {
}
namespace PartialSpecialization {
- template<typename T, typename U, typename V = U>
- struct X0; // expected-note 2{{template is declared here}}
+ template<typename T, typename U, typename V = U> // expected-note {{template parameter is declared here}}
+ struct X0; // expected-note {{template is declared here}}
template<typename ...Ts>
struct X0<Ts...> { // expected-error {{class template partial specialization is not more specialized than the primary template}}
};
- X0<int> x0i; // expected-error{{too few template arguments for class template 'X0'}}
+ X0<int> x0i; // expected-error{{missing template argument for template parameter}}
X0<int, float> x0if;
X0<int, float, double> x0ifd;
}
diff --git a/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp b/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
index 30e7c65..c6e6038 100644
--- a/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.variadic/multi-level-substitution.cpp
@@ -48,7 +48,7 @@ namespace PacksAtDifferentLevels {
int check1[X<short, int>::Inner<tuple<pair<short, unsigned short>,
pair<int, unsigned int>,
pair<long, unsigned long>>
- >::value == 1? 1 : -1];
+ >::value == 1? 1 : -1];
template<unsigned ...Values> struct unsigned_tuple { };
template<typename ...Types>
@@ -99,7 +99,7 @@ namespace PacksAtDifferentLevels {
int check5[X2<short, int>::Inner<int(pair<short, unsigned short>,
pair<int, unsigned int>,
pair<long, unsigned long>)
- >::value == 1? 1 : -1];
+ >::value == 1? 1 : -1];
template<typename T, typename U>
struct some_function_object {
@@ -217,8 +217,8 @@ namespace ExpandingNonTypeTemplateParameters {
template<typename ...Types>
struct tuple_of_values {
template<Types ...Values> // expected-error{{a non-type template parameter cannot have type 'float'}} \
- // expected-note{{template parameter is declared here}}
- struct apply { // expected-note 2{{template is declared here}}
+ // expected-note 2{{template parameter is declared here}}
+ struct apply { // expected-note {{template is declared here}}
typedef tuple<value_c<Types, Values>...> type;
};
};
@@ -236,7 +236,7 @@ namespace ExpandingNonTypeTemplateParameters {
tuple_of_values<int&, float&>::apply<i, i>::type tv2; // expected-error{{non-type template parameter of reference type 'float &' cannot bind to template argument of type 'int'}}
- tuple_of_values<int&, float&>::apply<i>::type tv3; // expected-error{{too few template arguments for class template 'apply'}}
+ tuple_of_values<int&, float&>::apply<i>::type tv3; // expected-error{{missing template argument for template parameter}}
tuple_of_values<int&, float&>::apply<i, f, i>::type tv4; // expected-error{{too many template arguments for class template 'apply'}}
}
diff --git a/clang/test/CXX/temp/temp.deduct/p9.cpp b/clang/test/CXX/temp/temp.deduct/p9.cpp
index 7b661c2..5f9ea27 100644
--- a/clang/test/CXX/temp/temp.deduct/p9.cpp
+++ b/clang/test/CXX/temp/temp.deduct/p9.cpp
@@ -15,13 +15,14 @@ void test_f() {
}
template <class T, unsigned = sizeof([]() { T::invalid; })>
+// expected-note@-1 {{template parameter is declared here}}
void g(T);
void g(...);
void test_g() {
- g(0); // expected-error@-4 {{type 'int' cannot be used prior to '::'}}
+ g(0); // expected-error@-5 {{type 'int' cannot be used prior to '::'}}
// expected-note@-4 {{in instantiation of default argument}}
// expected-note@-2 {{while substituting deduced template arguments}}
- // expected-note@-7 {{while substituting into a lambda expression here}}
+ // expected-note@-8 {{while substituting into a lambda expression here}}
}
template <class T>
diff --git a/clang/test/CXX/temp/temp.param/p1.cpp b/clang/test/CXX/temp/temp.param/p1.cpp
index e9a9789..e2eecdf 100644
--- a/clang/test/CXX/temp/temp.param/p1.cpp
+++ b/clang/test/CXX/temp/temp.param/p1.cpp
@@ -5,8 +5,9 @@ template<template<> class C> class D; // expected-error{{template template param
struct A {};
-template<class M,
- class T = A, // expected-note{{previous default template argument defined here}}
+template<class M,
+ class T // expected-note {{template parameter is declared here}}
+ = A, // expected-note{{previous default template argument defined here}}
class C> // expected-error{{template parameter missing a default argument}}
-class X0 {}; // expected-note{{template is declared here}}
-X0<int> x0; // expected-error{{too few template arguments for class template 'X0'}}
+class X0 {};
+X0<int> x0; // expected-error{{missing template argument for template parameter}}
diff --git a/clang/test/CXX/temp/temp.param/p12.cpp b/clang/test/CXX/temp/temp.param/p12.cpp
index 8317e7f..e3dfb65 100644
--- a/clang/test/CXX/temp/temp.param/p12.cpp
+++ b/clang/test/CXX/temp/temp.param/p12.cpp
@@ -32,9 +32,9 @@ template<int N,
class B3n;
// Check validity of default arguments
-template<template<class, int> class =// expected-note {{previous template template parameter is here}}
+template<template<class, int> class =// expected-note {{template parameter is declared here}}
Y1> // expected-error{{too many template arguments for class template 'Y1'}}
- // expected-note@-1 {{template template argument has different template parameters than its corresponding template template parameter}}
+ // expected-note@-1 {{template template argument is incompatible}}
class C1 {};
C1<> c1; // expected-note{{while checking a default template argument}}
diff --git a/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp b/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp
index 238490c..ce29766 100644
--- a/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp
+++ b/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp
@@ -77,9 +77,9 @@ template<typename T> struct wrap {
template<typename T> struct takedrop_impl;
template<place...X> struct takedrop_impl<places<X...>> {
- template<template<decltype(X)> class ...Take,
+ template<template<decltype(X)> class ...Take, // expected-note 2{{template parameter is declared here}}
template<place > class ...Drop>
- struct inner { // expected-note 2{{declared}}
+ struct inner {
typedef types<typename Take<_>::type...> take;
typedef types<typename Drop<_>::type...> drop;
};
@@ -87,11 +87,11 @@ template<place...X> struct takedrop_impl<places<X...>> {
template<unsigned N, typename...Ts> struct take {
using type = typename takedrop_impl<typename make_places<N>::type>::
- template inner<wrap<Ts>::template inner...>::take; // expected-error {{too few template arguments}}
+ template inner<wrap<Ts>::template inner...>::take; // expected-error {{missing template argument}}
};
template<unsigned N, typename...Ts> struct drop {
using type = typename takedrop_impl<typename make_places<N>::type>::
- template inner<wrap<Ts>::template inner...>::drop; // expected-error {{too few template arguments}}
+ template inner<wrap<Ts>::template inner...>::drop; // expected-error {{missing template argument}}
};
using T1 = take<3, int, char, double, long>::type; // expected-note {{previous}}
@@ -118,7 +118,7 @@ using D3 = drop<5, int, char, double, long>::type; // expected-note {{in instant
// implicitly a pack expansion.
template<typename ...Default> struct DefArg {
template<template<typename T = Default> class ...Classes> struct Inner { // expected-error {{default argument contains unexpanded parameter pack}} expected-note {{here}}
- Inner(Classes<>...); // expected-error {{too few}}
+ Inner(Classes<>...); // expected-error {{missing template argument}}
};
};
template<typename T> struct vector {};
diff --git a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
index a3478c0..aa1666f 100644
--- a/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
+++ b/clang/test/CXX/temp/temp.param/p8-cxx20.cpp
@@ -59,7 +59,7 @@ namespace ConstDestruction {
f<D{1, true}>();
}
- template<D d> struct Z {};
+ template<D d> struct Z {}; // expected-note {{template parameter is declared here}}
Z<D{2, true}> z1;
Z<D{2, false}> z2; // expected-error {{non-type template argument is not a constant expression}} expected-note-re {{in call to '{{.*}}.~D()'}}
}
diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp
index ecb8237..cb048ec 100644
--- a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.constexpr/p2.cpp
@@ -2,7 +2,7 @@
// RUN: %clang_cc1 -std=c++11 -verify=cxx11 %s
// cxx11-no-diagnostics
-template<int n> struct S;
+template<int n> struct S; // cxx98-note {{template parameter is declared here}}
template<int n> struct T {
T() {
diff --git a/clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp b/clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
index 741ebc5..749b455 100644
--- a/clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
+++ b/clang/test/CXX/temp/temp.spec/cxx1y-variable-template-no-body.cpp
@@ -3,27 +3,27 @@
// RUN: not %clang_cc1 --std=c++1y -x c++ -fixit %t -DFIXING
// RUN: %clang_cc1 --std=c++1y -x c++ %t -DFIXING
-template<typename T>
-T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
+template<typename T> // expected-note {{template parameter is declared here}}
+T pi = T(3.1415926535897932385);
template int pi<int>;
#ifndef FIXING
-template float pi<>; // expected-error {{too few template arguments for variable template 'pi'}}
+template float pi<>; // expected-error {{missing template argument for template parameter}}
template double pi_var0; // expected-error {{explicit instantiation of 'pi_var0' does not refer to a function template, variable template, member function, member class, or static data member}}
#endif
// Should recover as if definition
template double pi_var = 5; // expected-error {{variable cannot be defined in an explicit instantiation; if this declaration is meant to be a variable definition, remove the 'template' keyword}}
#ifndef FIXING
-template<typename T>
+template<typename T>
T pi0 = T(3.1415926535897932385); // expected-note {{previous definition is here}}
template int pi0 = 10; // expected-error {{variable cannot be defined in an explicit instantiation; if this declaration is meant to be a variable definition, remove the 'template' keyword}} \
expected-error{{redefinition of 'pi0' as different kind of symbol}}
#endif
-template<typename T>
+template<typename T>
T pi1 = T(3.1415926535897932385); // expected-note 0-2 {{here}}
// Should recover as if specialization
diff --git a/clang/test/CXX/temp/temp.spec/part.spec.cpp b/clang/test/CXX/temp/temp.spec/part.spec.cpp
index 4b0fdb9..3923d16 100644
--- a/clang/test/CXX/temp/temp.spec/part.spec.cpp
+++ b/clang/test/CXX/temp/temp.spec/part.spec.cpp
@@ -250,7 +250,7 @@ template <typename T> class PCT1 {};
template <typename T1, typename T2> class PCT2 {};
template <int X> class PCT3 {};
template <void (TestClass::*)()> class PCT4 {};
-template <void (*)()> class PCT5 {};
+template <void (*)()> class PCT5 {}; // expected-note {{template parameter is declared here}}
template <typename T> class PCT6 {
// expected-note@+1 3{{implicitly declared private here}}
template <typename NT> class NPCT1 {};
@@ -416,7 +416,7 @@ template <typename T1, typename T2> class PCTT1 {};
template <typename T1, typename T2, typename T3> class PCTT2 {};
template <typename T, int X> class PCTT3 {};
template <typename T, void (TestClass::*)()> class PCTT4 {};
-template <typename T, void (*)()> class PCTT5 {};
+template <typename T, void (*)()> class PCTT5 {}; // expected-note {{template parameter is declared here}}
template <typename T1, typename T2> class PCTT6 {
template <typename NT> class NCT1 {};
template <typename NT> class NCT2; // forward declaration
diff --git a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp
index 0283dba..63fd997 100644
--- a/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp
+++ b/clang/test/CXX/temp/temp.spec/temp.expl.spec/p20.cpp
@@ -2,13 +2,13 @@
template<typename T>
void f(T);
-template<typename T>
-struct A { }; // expected-note{{template is declared here}}
+template<typename T> // expected-note {{template parameter is declared here}}
+struct A { };
struct X {
template<> friend void f<int>(int); // expected-error{{in a friend}}
template<> friend class A<int>; // expected-error{{cannot be a friend}}
-
+
friend void f<float>(float); // okay
friend class A<float>; // okay
};
@@ -18,6 +18,6 @@ struct PR41792 {
template <> friend void f<>(int);
// expected-error@+2{{template specialization declaration cannot be a friend}}
- // expected-error@+1{{too few template arguments for class template 'A'}}
+ // expected-error@+1{{missing template argument for template parameter}}
template <> friend class A<>;
};
diff --git a/clang/test/Misc/integer-literal-printing.cpp b/clang/test/Misc/integer-literal-printing.cpp
index bd231a3..bc52b3f0 100644
--- a/clang/test/Misc/integer-literal-printing.cpp
+++ b/clang/test/Misc/integer-literal-printing.cpp
@@ -14,6 +14,7 @@ enum class boolTy : bool {
template <boolTy T> struct Type3Helper;
template <> struct Type3Helper<boolTy::b> { typedef boolTy Ty; };
template <boolTy T, typename Type3Helper<T>::Ty U> struct Type3 {};
+// expected-note@-1 {{template parameter is declared here}}
// PR14386
enum class charTy : char {
@@ -23,6 +24,7 @@ enum class charTy : char {
template <charTy T> struct Type4Helper;
template <> struct Type4Helper<charTy::c> { typedef charTy Ty; };
template <charTy T, typename Type4Helper<T>::Ty U> struct Type4 {};
+// expected-note@-1 {{template parameter is declared here}}
enum class scharTy : signed char {
c = 0,
@@ -31,6 +33,7 @@ enum class scharTy : signed char {
template <scharTy T> struct Type5Helper;
template <> struct Type5Helper<scharTy::c> { typedef scharTy Ty; };
template <scharTy T, typename Type5Helper<T>::Ty U> struct Type5 {};
+// expected-note@-1 {{template parameter is declared here}}
enum class ucharTy : unsigned char {
c = 0,
@@ -39,6 +42,7 @@ enum class ucharTy : unsigned char {
template <ucharTy T> struct Type6Helper;
template <> struct Type6Helper<ucharTy::c> { typedef ucharTy Ty; };
template <ucharTy T, typename Type6Helper<T>::Ty U> struct Type6 {};
+// expected-note@-1 {{template parameter is declared here}}
enum class wcharTy : wchar_t {
c = 0,
@@ -47,6 +51,7 @@ enum class wcharTy : wchar_t {
template <wcharTy T> struct Type7Helper;
template <> struct Type7Helper<wcharTy::c> { typedef wcharTy Ty; };
template <wcharTy T, typename Type7Helper<T>::Ty U> struct Type7 {};
+// expected-note@-1 {{template parameter is declared here}}
enum class char16Ty : char16_t {
c = 0,
@@ -55,6 +60,7 @@ enum class char16Ty : char16_t {
template <char16Ty T> struct Type8Helper;
template <> struct Type8Helper<char16Ty::c> { typedef char16Ty Ty; };
template <char16Ty T, typename Type8Helper<T>::Ty U> struct Type8 {};
+// expected-note@-1 {{template parameter is declared here}}
enum class char32Ty : char16_t {
c = 0,
@@ -63,6 +69,7 @@ enum class char32Ty : char16_t {
template <char32Ty T> struct Type9Helper;
template <> struct Type9Helper<char32Ty::c> { typedef char32Ty Ty; };
template <char32Ty T, typename Type9Helper<T>::Ty U> struct Type9 {};
+// expected-note@-1 {{template parameter is declared here}}
void Function() {
Function1(Type1<-42>()); // expected-error{{no matching function for call to 'Function1'}}
diff --git a/clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp b/clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp
index 73dff88..250b54a 100644
--- a/clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp
+++ b/clang/test/Modules/malformed-constraint-template-non-type-parm-decl.cpp
@@ -11,7 +11,7 @@
//--- mod.cppm
export module mod;
-template <typename T, auto Q>
+template <typename T, auto Q> // expected-note 2{{template parameter is declared here}}
concept ReferenceOf = Q;
// expected-error@+2 {{unknown type name 'AngleIsInvalidNow'}}
diff --git a/clang/test/Modules/missing-body-in-import.cpp b/clang/test/Modules/missing-body-in-import.cpp
index b52ebba..e25f7b5 100644
--- a/clang/test/Modules/missing-body-in-import.cpp
+++ b/clang/test/Modules/missing-body-in-import.cpp
@@ -29,6 +29,7 @@ export module mod2;
import mod1;
struct C: B <A{"a", "b"}> { // expected-error {{non-type template argument is not a constant expression}}
+ // expected-note@mod1.cppm:11 {{template parameter is declared here}}
constexpr C(int a) { }
};
diff --git a/clang/test/Modules/template-default-args.cpp b/clang/test/Modules/template-default-args.cpp
index 85b2a18..1d8de70 100644
--- a/clang/test/Modules/template-default-args.cpp
+++ b/clang/test/Modules/template-default-args.cpp
@@ -22,7 +22,7 @@ template<typename T = int> struct B;
template<typename T = int> struct C;
template<typename T> struct D {};
template<typename T> struct F {};
-template<typename T> struct G {};
+template<typename T> struct G {}; // #G
template<typename T> struct J {};
template<typename T = int> struct J;
struct K : J<> {};
@@ -39,8 +39,10 @@ E<> e;
F<> f;
G<> g; // expected-error {{missing '#include "a.h"'; default argument of 'G' must be defined before it is used}}
// expected-note@a.h:7 {{default argument declared here is not reachable}}
+// expected-note@#G {{template parameter is declared here}}
H<> h; // expected-error {{missing '#include "a.h"'; default argument of 'H' must be defined before it is used}}
// expected-note@a.h:8 {{default argument declared here is not reachable}}
+// expected-note@a.h:8 {{template parameter is declared here}}
I<> i;
L<> *l;
END
diff --git a/clang/test/Parser/MicrosoftExtensions.cpp b/clang/test/Parser/MicrosoftExtensions.cpp
index e32d7fa..9989fb8 100644
--- a/clang/test/Parser/MicrosoftExtensions.cpp
+++ b/clang/test/Parser/MicrosoftExtensions.cpp
@@ -126,7 +126,7 @@ void template_uuid()
}
-template <class T, const GUID* g = &__uuidof(T)> // expected-note {{template parameter is declared here}}
+template <class T, const GUID* g = &__uuidof(T)> // expected-note 2{{template parameter is declared here}}
class COM_CLASS_TEMPLATE { };
typedef COM_CLASS_TEMPLATE<struct_with_uuid, &*&__uuidof(struct_with_uuid)> COM_TYPE_1; // expected-warning {{non-type template argument containing a dereference operation is a Microsoft extension}}
diff --git a/clang/test/Parser/cxx-template-argument.cpp b/clang/test/Parser/cxx-template-argument.cpp
index 3c2169f..ffe53e7 100644
--- a/clang/test/Parser/cxx-template-argument.cpp
+++ b/clang/test/Parser/cxx-template-argument.cpp
@@ -57,9 +57,9 @@ namespace PR13210 {
// Don't emit spurious messages
namespace pr16225add {
- template<class T1, typename T2> struct Known { }; // expected-note 3 {{template is declared here}}
+ template<class T1, typename T2> struct Known { }; // expected-note 3{{template parameter is declared here}}
template<class T1, typename T2> struct X;
- template<class T1, typename T2> struct ABC; // expected-note {{template is declared here}}
+ template<class T1, typename T2> struct ABC; // expected-note {{template parameter is declared here}}
template<int N1, int N2> struct ABC2 {};
template<class T1, typename T2> struct foo :
@@ -68,7 +68,7 @@ namespace pr16225add {
template<class T1, typename T2> struct foo2 :
UnknownBase<T1,T2>, // expected-error {{no template named 'UnknownBase'}}
- Known<T1> // expected-error {{too few template arguments for class template 'Known'}}
+ Known<T1> // expected-error {{missing template argument for template parameter}}
{ };
template<class T1, typename T2> struct foo3 :
@@ -76,8 +76,8 @@ namespace pr16225add {
{ };
template<class T1, typename T2> struct foo4 :
- UnknownBase<T1,ABC<T2> >, // expected-error {{too few template arguments for class template 'ABC'}}
- Known<T1> // expected-error {{too few template arguments for class template 'Known'}}
+ UnknownBase<T1,ABC<T2> >, // expected-error {{missing template argument for template parameter}}
+ Known<T1> // expected-error {{missing template argument for template parameter}}
{ };
template<class T1, typename T2> struct foo5 :
@@ -92,7 +92,7 @@ namespace pr16225add {
#if __cplusplus <= 199711L
// expected-error@-2 {{use '> >'}}
#endif
- Known<T1> // expected-error {{too few template arguments for class template 'Known'}}
+ Known<T1> // expected-error {{missing template argument for template parameter}}
{ };
template<class T1, typename T2, int N> struct foo7 :
diff --git a/clang/test/Parser/cxx-template-template-recovery.cpp b/clang/test/Parser/cxx-template-template-recovery.cpp
index 61ef82d..5f9bf17 100644
--- a/clang/test/Parser/cxx-template-template-recovery.cpp
+++ b/clang/test/Parser/cxx-template-template-recovery.cpp
@@ -19,8 +19,10 @@ template <typename T>
concept C3 = true; // #C3
template <typename T>
auto V3 = true; // #V3
-template <template <typename T> typename C>
-constexpr bool test = true;
+
+template <template <typename T>
+ typename C> // expected-note 6{{template parameter is declared here}}
+ constexpr bool test = true;
static_assert(test<a::C1>); // expected-error {{template argument does not refer to a class or alias template, or template template parameter}} \
// expected-note@#C1 {{here}}
diff --git a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
index 9d27f83..a8a9f33 100644
--- a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -11,7 +11,7 @@ A(int) -> A<int>;
// Make sure we still correctly parse cases where a template can appear without arguments.
namespace template_template_arg {
template<template<typename> typename> struct X {};
- template<typename> struct Y {};
+ template<typename> struct Y {}; // expected-note 2{{template parameter is declared here}}
X<A> xa;
Y<A> ya; // expected-error {{requires template arguments}}
@@ -36,7 +36,7 @@ namespace template_template_arg {
namespace template_template_arg_pack {
template<template<typename> typename...> struct XP {};
- template<typename...> struct YP {};
+ template<typename...> struct YP {}; // expected-note 2{{template parameter is declared here}}
struct Z { template<typename T> struct Q {}; }; // expected-note 2{{here}}
@@ -116,7 +116,7 @@ namespace stmt {
}
namespace expr {
- template<typename T> struct U {};
+ template<typename T> struct U {}; // expected-note {{template parameter is declared here}}
void j() {
(void)typeid(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
(void)sizeof(A); // expected-error{{requires template arguments; argument deduction not allowed here}}
diff --git a/clang/test/Sema/invalid-member.cpp b/clang/test/Sema/invalid-member.cpp
index 0e3fec1..ccce392 100644
--- a/clang/test/Sema/invalid-member.cpp
+++ b/clang/test/Sema/invalid-member.cpp
@@ -22,7 +22,7 @@ static_assert(sizeof(Z) == 1, "No valid members");
constexpr int N = undef; // expected-error {{use of undeclared identifier}} \
expected-note {{declared here}}
-template<int a>
+template<int a> // expected-note {{template parameter is declared here}}
class ABC {};
class T {
ABC<N> abc; // expected-error {{non-type template argument is not a constant expression}} \
diff --git a/clang/test/SemaCXX/access-base-class.cpp b/clang/test/SemaCXX/access-base-class.cpp
index 47d0f02..7d5fe38 100644
--- a/clang/test/SemaCXX/access-base-class.cpp
+++ b/clang/test/SemaCXX/access-base-class.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
namespace T1 {
-
+
class A { };
class B : private A { }; // expected-note {{declared private here}}
@@ -10,7 +10,7 @@ void f(B* b) {
}
-namespace T2 {
+namespace T2 {
class A { };
class B : A { }; // expected-note {{implicitly declared private here}}
@@ -24,7 +24,7 @@ void f(B* b) {
namespace T3 {
class A { };
-class B : public A { };
+class B : public A { };
void f(B* b) {
A *a = b;
@@ -50,30 +50,30 @@ void f(D *d) {
namespace T5 {
class A {};
-
+
class B : private A {
void f(B *b) {
A *a = b;
}
- };
+ };
}
namespace T6 {
class C;
-
+
class A {}; // expected-note{{member is declared here}}
-
+
class B : private A { // expected-note {{declared private here}} expected-note {{constrained by private inheritance here}}
void f(C* c);
};
-
- class C : public B {
+
+ class C : public B {
void f(C *c) {
A* a = c; // expected-error {{cannot cast 'C' to its private base class 'A'}} \
// expected-error {{'A' is a private member of 'T6::A'}}
}
};
-
+
void B::f(C *c) {
A *a = c;
}
@@ -82,7 +82,7 @@ namespace T6 {
namespace T7 {
class A {};
class B : public A {};
- class C : private B {
+ class C : private B {
void f(C *c) {
A* a = c; // okay
}
@@ -98,7 +98,7 @@ struct flag {
template <class T>
struct trait : flag<sizeof(T)> {}; // expected-note 2{{here}}
-template <class T, bool Inferred = trait<T>::value> // expected-note {{here}}
+template <class T, bool Inferred = trait<T>::value> // expected-note 2{{here}}
struct a {};
template <class T>
diff --git a/clang/test/SemaCXX/alias-template.cpp b/clang/test/SemaCXX/alias-template.cpp
index b49d36a..90095b3 100644
--- a/clang/test/SemaCXX/alias-template.cpp
+++ b/clang/test/SemaCXX/alias-template.cpp
@@ -167,7 +167,10 @@ namespace SFINAE {
f<E>();
}
- template<typename T, typename U = EnableIf<is_enum<T>>> struct fail1 {}; // expected-note {{here}}
+ template<typename T,
+ typename U = // expected-note {{template parameter is declared here}}
+ EnableIf<is_enum<T>>> // expected-note {{in instantiation of template type alias 'EnableIf' requested here}}
+ struct fail1 {};
template<typename T> struct fail2 : DisableIf<is_enum<T>> {}; // expected-note {{here}}
fail1<int> f1; // expected-note {{here}}
diff --git a/clang/test/SemaCXX/anonymous-struct.cpp b/clang/test/SemaCXX/anonymous-struct.cpp
index 5927f4e..a8688af 100644
--- a/clang/test/SemaCXX/anonymous-struct.cpp
+++ b/clang/test/SemaCXX/anonymous-struct.cpp
@@ -27,7 +27,7 @@ struct E {
};
};
-template <class T> void foo(T);
+template <class T> void foo(T); // #foo
typedef struct { // expected-error {{anonymous non-C-compatible type given name for linkage purposes by typedef declaration after its linkage was computed; add a tag name here to establish linkage prior to definition}}
// expected-note@-1 {{unnamed type used in template argument was declared here}}
@@ -36,6 +36,7 @@ typedef struct { // expected-error {{anonymous non-C-compatible type given name
#if __cplusplus <= 199711L
// expected-warning@-2 {{template argument uses unnamed type}}
// expected-note@-3 {{while substituting deduced template arguments}}
+ // expected-note@#foo {{template parameter is declared here}}
#endif
}
} A; // expected-note {{type is given name 'A' for linkage purposes by this typedef declaration}}
diff --git a/clang/test/SemaCXX/builtin-structured-binding-size.cpp b/clang/test/SemaCXX/builtin-structured-binding-size.cpp
index bcd13a6..b780752 100644
--- a/clang/test/SemaCXX/builtin-structured-binding-size.cpp
+++ b/clang/test/SemaCXX/builtin-structured-binding-size.cpp
@@ -119,6 +119,7 @@ T<int> t1;
// expected-error@#tpl-1 {{non-type template argument is not a constant expression}} \
// expected-note@-1 {{in instantiation of default argument for 'T<int>' required here}} \
// expected-note@-1 {{while checking a default template argument used here}} \
+// expected-note@#tpl-1 2{{template parameter is declared here}}
static_assert(T<S3>::value == 3);
diff --git a/clang/test/SemaCXX/constant-expression-cxx11.cpp b/clang/test/SemaCXX/constant-expression-cxx11.cpp
index 91c4ff1..4e17121 100644
--- a/clang/test/SemaCXX/constant-expression-cxx11.cpp
+++ b/clang/test/SemaCXX/constant-expression-cxx11.cpp
@@ -102,7 +102,7 @@ static_assert(n9 == 123, "");
}
namespace TemplateArgumentConversion {
- template<int n> struct IntParam {};
+ template<int n> struct IntParam {}; // expected-note {{template parameter is declared here}}
using IntParam0 = IntParam<0>;
using IntParam0 = IntParam<id(0)>;
@@ -1533,7 +1533,7 @@ namespace MutableMembers {
constexpr int mmn2 = mm.n; // expected-error {{constant expression}} expected-note {{read of mutable member 'n' is not allowed in a constant expression}}
// Here's one reason why allowing this would be a disaster...
- template<int n> struct Id { int k = n; };
+ template<int n> struct Id { int k = n; }; // expected-note {{template parameter is declared here}}
int f() {
constexpr MM m = { 0 };
++m.n;
diff --git a/clang/test/SemaCXX/constant-expression.cpp b/clang/test/SemaCXX/constant-expression.cpp
index ef48ee5..a710def 100644
--- a/clang/test/SemaCXX/constant-expression.cpp
+++ b/clang/test/SemaCXX/constant-expression.cpp
@@ -99,7 +99,7 @@ void diags(int n) {
namespace IntOrEnum {
const int k = 0;
const int &p = k; // expected-note {{declared here}}
- template<int n> struct S {};
+ template<int n> struct S {}; // expected-note {{template parameter is declared here}}
S<p> s; // expected-error {{not an integral constant expression}} expected-note {{read of variable 'p' of non-integral, non-enumeration type 'const int &'}}
}
diff --git a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp
index c8204c2..6b8495e 100644
--- a/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp
+++ b/clang/test/SemaCXX/cxx1z-noexcept-function-type.cpp
@@ -74,6 +74,7 @@ namespace DependentDefaultCtorExceptionSpec {
};
struct InstantiateFromAnotherClass {
template <class B, class T = decltype(static_cast<bool (B::*)(int)>(&B::foo))> // expected-note {{in instantiation of function template specialization}}
+ // expected-note@-1 {{template parameter is declared here}}
InstantiateFromAnotherClass(B *) {} // expected-note {{in instantiation of default argument}}
};
NoexceptWithThis<int> f{};
diff --git a/clang/test/SemaCXX/cxx2a-consteval.cpp b/clang/test/SemaCXX/cxx2a-consteval.cpp
index 1474c48..54390e3f 100644
--- a/clang/test/SemaCXX/cxx2a-consteval.cpp
+++ b/clang/test/SemaCXX/cxx2a-consteval.cpp
@@ -201,7 +201,7 @@ struct A {
using mem_ptr_type = int (A::*)(int);
-template<mem_ptr_type ptr>
+template<mem_ptr_type ptr> // expected-note 2{{template parameter is declared here}}
struct C {};
C<&A::f> c;
diff --git a/clang/test/SemaCXX/cxx2c-template-template-param.cpp b/clang/test/SemaCXX/cxx2c-template-template-param.cpp
index ed55a059..a0b8d79 100644
--- a/clang/test/SemaCXX/cxx2c-template-template-param.cpp
+++ b/clang/test/SemaCXX/cxx2c-template-template-param.cpp
@@ -3,12 +3,16 @@
namespace Errors {
template <template<typename T> auto>
+// expected-note@-1 4{{template parameter is declared here}}
struct S1;
template <template<auto T> auto>
+// expected-note@-1 4{{template parameter is declared here}}
struct S2;
template <template<typename T> concept>
+// expected-note@-1 4{{template parameter is declared here}}
struct S3;
template <template<auto T> concept>
+// expected-note@-1 4{{template parameter is declared here}}
struct S4;
int a;
@@ -36,7 +40,7 @@ S4<Var> t16; // expected-error {{template argument does not refer to a concept,
}
-template <template<typename T> auto V> // expected-note {{previous template template parameter is here}} \
+template <template<typename T> auto V> // expected-note {{template parameter is declared here}} \
// expected-error{{template argument for non-type template parameter must be an expression}}
struct S1 {
static_assert(V<int> == 42);
@@ -44,18 +48,18 @@ struct S1 {
static_assert(V<double> == 0);
};
template <template<auto T> auto V> // expected-error {{template argument for template type parameter must be a type}} \
- // expected-note {{previous template template parameter is here}}
+ // expected-note {{template parameter is declared here}}
struct S2 {
static_assert(V<0> == 1);
static_assert(V<1> == 0);
};
template <template<typename T> concept C > // expected-error {{template argument for non-type template parameter must be an expression}} \
- // expected-note {{previous template template parameter is here}}
+ // expected-note {{template parameter is declared here}}
struct S3 {
static_assert(C<int>);
};
template <template<auto> concept C> // expected-error {{template argument for template type parameter must be a type}} \
- // expected-note {{previous template template parameter is here}}
+ // expected-note {{template parameter is declared here}}
struct S4 {
static_assert(C<0>);
};
@@ -80,14 +84,14 @@ requires (N%2 == 0)
constexpr auto Var2<N> = 1;
void test () {
- S1<Var2> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}}
- S2<Var> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}}
+ S1<Var2> sE; // expected-note {{template template argument is incompatible with its corresponding template template parameter}}
+ S2<Var> sE; // expected-note {{template template argument is incompatible with its corresponding template template parameter}}
S1<Var> s1;
S2<Var2> s2;
S3<C> s3;
- S4<C> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}}
+ S4<C> sE; // expected-note {{template template argument is incompatible with its corresponding template template parameter}}
S4<CI> s4;
- S3<CI> sE; // expected-note {{template template argument has different template parameters than its corresponding template template parameter}}
+ S3<CI> sE; // expected-note {{template template argument is incompatible with its corresponding template template parameter}}
}
@@ -342,10 +346,11 @@ concept D = Var<int>;
namespace InvalidName {
template <typename T, template <typename> concept C>
-concept A = C<T>; // expected-note {{here}}
+// expected-note@-1 {{template parameter is declared here}}
+concept A = C<T>;
template <A<concept missing<int>> T> // expected-error {{expected expression}} \
- // expected-error {{too few template arguments for concept 'A'}} \
+ // expected-error {{missing template argument for template parameter}} \
// expected-error {{unknown type name 'T'}} \
// expected-error {{expected unqualified-id}}
auto f();
diff --git a/clang/test/SemaCXX/cxx98-compat-flags.cpp b/clang/test/SemaCXX/cxx98-compat-flags.cpp
index 6ffb3a5..3986251 100644
--- a/clang/test/SemaCXX/cxx98-compat-flags.cpp
+++ b/clang/test/SemaCXX/cxx98-compat-flags.cpp
@@ -1,7 +1,8 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-compat-pedantic -verify %s
// RUN: %clang_cc1 -fsyntax-only -std=c++17 -Wc++98-compat-pedantic -Wno-bind-to-temporary-copy -Wno-unnamed-type-template-args -Wno-local-type-template-args -Wno-binary-literal -Werror %s
-template<typename T> int TemplateFn(T) { return 0; }
+template<typename T> // expected-note 2{{template parameter is declared here}}
+int TemplateFn(T) { return 0; }
void LocalTemplateArg() {
struct S {};
TemplateFn(S()); // expected-warning {{local type 'S' as template argument is incompatible with C++98}}
diff --git a/clang/test/SemaCXX/cxx98-compat.cpp b/clang/test/SemaCXX/cxx98-compat.cpp
index 8e7acf7..9a8a8e2 100644
--- a/clang/test/SemaCXX/cxx98-compat.cpp
+++ b/clang/test/SemaCXX/cxx98-compat.cpp
@@ -183,7 +183,8 @@ struct DelegCtor {
template<int n = 0> void DefaultFuncTemplateArg(); // expected-warning {{default template arguments for a function template are incompatible with C++98}}
-template<typename T> int TemplateFn(T) { return 0; }
+template<typename T> // expected-note 2{{template parameter is declared here}}
+int TemplateFn(T) { return 0; }
void LocalTemplateArg() {
struct S {};
TemplateFn(S()); // expected-warning {{local type 'S' as template argument is incompatible with C++98}}
@@ -198,7 +199,7 @@ int UnnamedTemplateArg = TemplateFn(obj_of_unnamed_type); // expected-warning {{
#ifndef CXX17COMPAT
namespace RedundantParensInAddressTemplateParam {
int n;
- template<int*p> struct S {};
+ template<int*p> struct S {}; // expected-note 2{{template parameter is declared here}}
S<(&n)> s; // expected-warning {{parentheses around address non-type template argument are incompatible with C++98}}
S<(((&n)))> t; // expected-warning {{parentheses around address non-type template argument are incompatible with C++98}}
}
@@ -321,7 +322,7 @@ namespace LiteralUCNs {
// template argument evaluation rules.
#ifndef CXX17COMPAT
namespace NonTypeTemplateArgs {
- template<typename T, T v> struct S {};
+ template<typename T, T v> struct S {}; // expected-note 2{{template parameter is declared here}}
const int k = 5; // expected-note {{here}}
static void f() {} // expected-note {{here}}
S<const int&, k> s1; // expected-warning {{non-type template argument referring to object 'k' with internal linkage is incompatible with C++98}}
@@ -330,8 +331,8 @@ namespace NonTypeTemplateArgs {
namespace NullPointerTemplateArg {
struct A {};
- template<int*> struct X {};
- template<int A::*> struct Y {};
+ template<int*> struct X {}; // expected-note {{template parameter is declared here}}
+ template<int A::*> struct Y {}; // expected-note {{template parameter is declared here}}
X<(int*)0> x; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}}
Y<(int A::*)0> y; // expected-warning {{use of null pointer as non-type template argument is incompatible with C++98}}
}
diff --git a/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp b/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp
index 097ada3..436dfb9 100644
--- a/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp
+++ b/clang/test/SemaCXX/invalid-requirement-requires-expr.cpp
@@ -17,8 +17,7 @@ constexpr bool A<x>::far() {
b.data_member;
requires A<x-1>::far(); // #Invalid
// expected-error@#Invalid {{recursive template instantiation exceeded maximum depth}}
- // expected-note@#Invalid {{in instantiation}}
- // expected-note@#Invalid 2 {{while}}
+ // expected-note@#Invalid 3 {{while}}
// expected-note@#Invalid {{contexts in backtrace}}
// expected-note@#Invalid {{increase recursive template instantiation depth}}
};
diff --git a/clang/test/SemaCXX/invalid-std-initializer-list.cpp b/clang/test/SemaCXX/invalid-std-initializer-list.cpp
index 93246b5..6f8af52 100644
--- a/clang/test/SemaCXX/invalid-std-initializer-list.cpp
+++ b/clang/test/SemaCXX/invalid-std-initializer-list.cpp
@@ -2,7 +2,9 @@
namespace std {
-template<class T, class = T::x> // expected-error 2 {{type 'int' cannot be used prior to '::' because it has no members}}
+template<class T,
+ class = // expected-note 2 {{template parameter is declared here}}
+ T::x> // expected-error 2 {{type 'int' cannot be used prior to '::' because it has no members}}
class initializer_list;
}
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index 8ea8e32..a6803ea 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -447,7 +447,7 @@ struct A {
// expected-error@-1 {{field has incomplete type 'void'}}
};
-template <typename F>
+template <typename F> // cxx03-note {{template parameter is declared here}}
void g(F f) {
auto a = A<decltype(f())>();
// expected-note@-1 {{in instantiation of template class 'PR20731::A<void>' requested here}}
@@ -504,12 +504,14 @@ namespace error_in_transform_prototype {
namespace PR21857 {
template<typename Fn> struct fun : Fn {
+ // cxx03-note@-1 {{template parameter is declared here}}
fun() = default;
using Fn::operator();
};
template<typename Fn> fun<Fn> wrap(Fn fn); // cxx03-warning {{template argument uses unnamed type}}
+ // cxx03-note@-1 {{template parameter is declared here}}
auto x = wrap([](){}); // cxx03-warning {{template argument uses unnamed type}} cxx03-note 2 {{unnamed type used in template argument was declared here}}
- // cxx03-note@-1 {{while substituting deduced template arguments into function template}}
+ // cxx03-note@-1 2{{while substituting deduced template arguments into function template}}
}
namespace PR13987 {
diff --git a/clang/test/SemaCXX/make_integer_seq.cpp b/clang/test/SemaCXX/make_integer_seq.cpp
index 71b7b82..7fca9ed 100644
--- a/clang/test/SemaCXX/make_integer_seq.cpp
+++ b/clang/test/SemaCXX/make_integer_seq.cpp
@@ -48,5 +48,6 @@ using illformed2 = ErrorSeq<int, -5>; // expected-note{{in instantiation}}
template <typename T, T N> void f() {}
__make_integer_seq<f, int, 0> x; // expected-error{{template template parameter must be a class template or type alias template}}
-__make_integer_seq<__make_integer_seq, int, 10> PR28494; // expected-note{{different template parameters}}
+__make_integer_seq<__make_integer_seq, int, 10> PR28494; // expected-note{{template template argument is incompatible}}
// expected-error@make_integer_seq.cpp:* {{template argument for template template parameter must be a class template or type alias template}}
+// expected-note@*:* 3{{template parameter from hidden source: template <class, type-parameter-1-0 ...> class}}
diff --git a/clang/test/SemaCXX/type-trait-common-type.cpp b/clang/test/SemaCXX/type-trait-common-type.cpp
index 8f2b97b..214f946 100644
--- a/clang/test/SemaCXX/type-trait-common-type.cpp
+++ b/clang/test/SemaCXX/type-trait-common-type.cpp
@@ -5,10 +5,12 @@
# error
#endif
-// expected-note@*:* {{template declaration from hidden source: template <template <class ...> class, template <class> class, class, class ...>}}
+// expected-note@*:* {{template parameter from hidden source: template <class ...> class}}
+// expected-note@*:* {{template parameter from hidden source: class ...}}
+// expected-note@*:* 2{{template parameter from hidden source: template <class ...> class}}
void test() {
- __builtin_common_type<> a; // expected-error {{too few template arguments for template '__builtin_common_type'}}
+ __builtin_common_type<> a; // expected-error {{missing template argument for template parameter}}
__builtin_common_type<1> b; // expected-error {{template argument for template template parameter must be a class template or type alias template}}
__builtin_common_type<int, 1> c; // expected-error {{template argument for template template parameter must be a class template or type alias template}}
}
@@ -219,6 +221,7 @@ static_assert(__is_same(common_type_base<int, PrivateConstructor>, empty_type));
// expected-note@+1 {{in instantiation of template type alias 'common_type_base' requested here}}
template<typename A, typename B, typename Res = common_type_base<A, B>>
+// expected-note@-1 {{template parameter is declared here}}
static Res common_type_sfinae();
// expected-note@-1 {{in instantiation of default argument for 'common_type_sfinae<int, InvalidConversion>' required here}}
diff --git a/clang/test/SemaCXX/undefined-internal.cpp b/clang/test/SemaCXX/undefined-internal.cpp
index 9745f09..7f46623 100644
--- a/clang/test/SemaCXX/undefined-internal.cpp
+++ b/clang/test/SemaCXX/undefined-internal.cpp
@@ -209,9 +209,11 @@ namespace OverloadUse {
t<f>(&n, &n); // expected-note {{used here}}
#if __cplusplus < 201103L
// expected-warning@-3 {{non-type template argument referring to function 'f' with internal linkage}}
- // expected-note@-4 {{while substituting explicitly-specified template arguments}}
- // expected-warning@-4 {{non-type template argument referring to function 'f' with internal linkage}}
+ // expected-note@-7 {{template parameter is declared here}}
// expected-note@-5 {{while substituting explicitly-specified template arguments}}
+ // expected-warning@-5 {{non-type template argument referring to function 'f' with internal linkage}}
+ // expected-note@-9 {{template parameter is declared here}}
+ // expected-note@-7 {{while substituting explicitly-specified template arguments}}
#endif
}
}
diff --git a/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp b/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp
index 79c9d33..1fe0916 100644
--- a/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp
+++ b/clang/test/SemaCXX/warn-deprecated-specializations-in-system-headers.cpp
@@ -10,6 +10,7 @@ template <>
struct [[deprecated]] traits<int> {}; // expected-note {{'traits<int>' has been explicitly marked deprecated here}}
template<typename T, typename Trait = traits<T>> // expected-warning {{'traits<int>' is deprecated}}
+ // expected-note@-1 {{template parameter is declared here}}
struct basic_string {};
// should not warn, defined and used in system headers
diff --git a/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl b/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl
index d7c6876..31fdf65 100644
--- a/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/Buffers.hlsl
@@ -8,7 +8,7 @@ typedef vector<double, 3> double3;
// expected-error@+1 {{class template 'Buffer' requires template arguments}}
Buffer BufferErr1;
-// expected-error@+1 {{too few template arguments for class template 'Buffer'}}
+// expected-error@+1 {{missing template argument for template parameter}}
Buffer<> BufferErr2;
// test implicit Buffer concept
@@ -39,7 +39,7 @@ template<typename T> struct TemplatedVector {
// structs not allowed
// expected-error@+4 {{constraints not satisfied for class template 'Buffer'}}
-// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class Buffer}}
+// expected-note@*:* {{template parameter from hidden source: typename element_type}}
// expected-note@*:* {{because 's' does not satisfy '__is_typed_resource_element_compatible'}}
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(s)' evaluated to false}}
Buffer<s> r6;
diff --git a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl
index 361f4303..78a6d5f 100644
--- a/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/RWBuffers.hlsl
@@ -8,7 +8,7 @@ typedef vector<double, 3> double3;
// expected-error@+1 {{class template 'RWBuffer' requires template arguments}}
RWBuffer BufferErr1;
-// expected-error@+1 {{too few template arguments for class template 'RWBuffer'}}
+// expected-error@+1 {{missing template argument for template parameter}}
RWBuffer<> BufferErr2;
// test implicit RWBuffer concept
@@ -39,7 +39,7 @@ template<typename T> struct TemplatedVector {
// structs not allowed
// expected-error@+4 {{constraints not satisfied for class template 'RWBuffer'}}
-// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_typed_resource_element_compatible<element_type> class RWBuffer}}
+// expected-note@*:* {{template parameter from hidden source: typename element_type}}
// expected-note@*:* {{because 's' does not satisfy '__is_typed_resource_element_compatible'}}
// expected-note@*:* {{because '__builtin_hlsl_is_typed_resource_element_compatible(s)' evaluated to false}}
RWBuffer<s> r6;
diff --git a/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl b/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl
index e5b1125..6bb71dd 100644
--- a/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl
+++ b/clang/test/SemaHLSL/BuiltIns/StructuredBuffers.hlsl
@@ -8,8 +8,8 @@ StructuredBuffer<float3> Buff;
// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_structured_resource_element_compatible<element_type> class StructuredBuffer {}}}
StructuredBuffer BufferErr1;
-// expected-error@+2 {{too few template arguments for class template 'StructuredBuffer'}}
-// expected-note@*:* {{template declaration from hidden source: template <typename element_type> requires __is_structured_resource_element_compatible<element_type> class StructuredBuffer {}}}
+// expected-error@+2 {{missing template argument for template parameter}}
+// expected-note@*:* {{template parameter from hidden source: typename element_type}}
StructuredBuffer<> BufferErr2;
// test elements of 0 size
diff --git a/clang/test/SemaObjCXX/parameterized_classes_subst.mm b/clang/test/SemaObjCXX/parameterized_classes_subst.mm
index 4658c3d..728e9d4 100644
--- a/clang/test/SemaObjCXX/parameterized_classes_subst.mm
+++ b/clang/test/SemaObjCXX/parameterized_classes_subst.mm
@@ -408,7 +408,7 @@ void testVariadicInstantiation() {
// --------------------------------------------------------------------------
// Parameterized classes are not templates
// --------------------------------------------------------------------------
-template<template<typename T, typename U> class TT>
+template<template<typename T, typename U> class TT> // expected-note {{template parameter is declared here}}
struct AcceptsTemplateTemplate { };
typedef AcceptsTemplateTemplate<NSMutableDictionary> TemplateTemplateFail1; // expected-error{{template argument for template template parameter must be a class template or type alias template}}
diff --git a/clang/test/SemaTemplate/alias-templates.cpp b/clang/test/SemaTemplate/alias-templates.cpp
index ab5cad7..7ec420a 100644
--- a/clang/test/SemaTemplate/alias-templates.cpp
+++ b/clang/test/SemaTemplate/alias-templates.cpp
@@ -278,12 +278,12 @@ namespace PR31514 {
namespace an_alias_template_is_not_a_class_template {
template<typename T> using Foo = int; // expected-note 3{{here}}
Foo x; // expected-error {{use of alias template 'Foo' requires template arguments}}
- Foo<> y; // expected-error {{too few template arguments for alias template 'Foo'}}
+ Foo<> y; // expected-error {{missing template argument for template parameter}}
int z = Foo(); // expected-error {{use of alias template 'Foo' requires template arguments}}
template<template<typename> class Bar> void f() { // expected-note 3{{here}}
Bar x; // expected-error {{use of template template parameter 'Bar' requires template arguments}}
- Bar<> y; // expected-error {{too few template arguments for template template parameter 'Bar'}}
+ Bar<> y; // expected-error {{missing template argument for template parameter}}
int z = Bar(); // expected-error {{use of template template parameter 'Bar' requires template arguments}}
}
}
@@ -304,7 +304,8 @@ namespace resolved_nttp {
using TB = int (*)(int (*)[1], int (*)[2], int (*)[3]);
template <typename T, int ...M> struct C {
- template <T... N> using Fn = T(int(*...A)[N]);
+ template <T... N> // expected-note {{template parameter is declared here}}
+ using Fn = T(int(*...A)[N]);
Fn<1, M..., 4> *p; // expected-error-re 3{{evaluates to {{[234]}}, which cannot be narrowed to type 'bool'}}
};
using TC = decltype(C<int, 2, 3>::p);
diff --git a/clang/test/SemaTemplate/concepts.cpp b/clang/test/SemaTemplate/concepts.cpp
index 209e7dc..505562a 100644
--- a/clang/test/SemaTemplate/concepts.cpp
+++ b/clang/test/SemaTemplate/concepts.cpp
@@ -1262,7 +1262,8 @@ constexpr bool f(C auto) { // #GH61824_f
C auto x = 0;
// expected-error@#T_Type {{type 'int' cannot be used prior to '::'}} \
-// expected-note@-1 {{in instantiation of default argument}}
+// expected-note@-1 {{in instantiation of default argument}} \
+// expected-note@#T_Type {{template parameter is declared here}}
// This will be fixed when we merge https://github.com/llvm/llvm-project/pull/141776
// Which makes us behave like GCC.
diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp
index 315fa95..81079df 100644
--- a/clang/test/SemaTemplate/cwg2398.cpp
+++ b/clang/test/SemaTemplate/cwg2398.cpp
@@ -264,7 +264,7 @@ namespace classes {
template<class T, class U> struct A {};
template<template<class> class TT> auto f(TT<int> a) { return a; }
- // expected-note@-1 2{{substitution failure: too few template arguments}}
+ // expected-note@-1 2{{no template parameter}}
A<int, float> v1;
A<int, double> v2;
@@ -280,7 +280,7 @@ namespace classes {
static constexpr auto val = E1;
};
template <template <class T3> class TT> void f(TT<int> v) {
- // expected-note@-1 {{substitution failure: too few template arguments}}
+ // expected-note@-1 {{no template parameter}}
static_assert(v.val == 3);
};
void test() {
@@ -313,7 +313,7 @@ namespace classes {
}
template <template <class T2, int V3> class TT2> auto g(TT2<double, 1>) {
- // expected-note@-1 {{too few template arguments for class template 'A'}}
+ // expected-note@-1 {{no template parameter}}
return f(TT2<int, 2>());
}
@@ -347,11 +347,11 @@ namespace packs {
namespace t1 {
template<template<int, int...> class> struct A {};
// expected-error@-1 {{non-type parameter of template template parameter cannot be narrowed from type 'int' to 'char'}}
- // expected-note@-2 {{previous template template parameter is here}}
+ // expected-note@-2 {{template parameter is declared here}}
- template<char> struct B;
+ template<char> struct B; // expected-note {{template parameter is declared here}}
template struct A<B>;
- // expected-note@-1 {{has different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
} // namespace t1
namespace t2 {
template<template<char, int...> class> struct A {};
@@ -361,11 +361,11 @@ namespace packs {
namespace t3 {
template<template<int...> class> struct A {};
// expected-error@-1 {{non-type parameter of template template parameter cannot be narrowed from type 'int' to 'char'}}
- // expected-note@-2 {{previous template template parameter is here}}
+ // expected-note@-2 {{template parameter is declared here}}
- template<char> struct B;
+ template<char> struct B; // expected-note {{template parameter is declared here}}
template struct A<B>;
- // expected-note@-1 {{has different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
} // namespace t3
namespace t4 {
template<template<char...> class> struct A {};
@@ -501,7 +501,7 @@ namespace constraints {
// expected-note@-1 {{similar constraint expressions not considered equivalent}}
namespace t1 {
- template<template<C1, class... T1s> class TT1> // expected-note {{TT1' declared here}}
+ template<template<C1, class... T1s> class TT1> // expected-note {{template parameter is declared here}}
struct A {};
template<D1, class T2> struct B {}; // expected-note {{'B' declared here}}
template struct A<B>;
@@ -513,7 +513,7 @@ namespace constraints {
template struct A<B>;
} // namespace t2
namespace t3 {
- template<template<C1, class... T1s> class TT1> // expected-note {{'TT1' declared here}}
+ template<template<C1, class... T1s> class TT1> // expected-note {{template parameter is declared here}}
struct A {};
template<C2, class T2> struct B {}; // expected-note {{'B' declared here}}
template struct A<B>;
@@ -521,7 +521,7 @@ namespace constraints {
} // namespace t2
namespace t4 {
// FIXME: This should be accepted.
- template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}}
+ template<template<C1... T1s> class TT1> // expected-note {{template parameter is declared here}}
struct A {};
template<C1 T2> struct B {}; // expected-note {{'B' declared here}}
template struct A<B>;
@@ -529,14 +529,14 @@ namespace constraints {
} // namespace t4
namespace t5 {
// FIXME: This should be accepted
- template<template<C2... T1s> class TT1> // expected-note {{'TT1' declared here}}
+ template<template<C2... T1s> class TT1> // expected-note {{template parameter is declared here}}
struct A {};
template<C1 T2> struct B {}; // expected-note {{'B' declared here}}
template struct A<B>;
// expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}}
} // namespace t5
namespace t6 {
- template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}}
+ template<template<C1... T1s> class TT1> // expected-note {{template parameter is declared here}}
struct A {};
template<C2 T2> struct B {}; // expected-note {{'B' declared here}}
template struct A<B>;
@@ -555,14 +555,14 @@ namespace constraints {
template struct A<B>;
} // namespace t8
namespace t9 {
- template<template<C1... T1s> class TT1> // expected-note {{'TT1' declared here}}
+ template<template<C1... T1s> class TT1> // expected-note {{template parameter is declared here}}
struct A {};
template<D1 T2> struct B {}; // expected-note {{'B' declared here}}
template struct A<B>;
// expected-error@-1 {{'B' is more constrained than template template parameter 'TT1'}}
} // namespace t9
namespace t10 {
- template<template<class...> requires C1<int> class TT1> // expected-note {{'TT1' declared here}}
+ template<template<class...> requires C1<int> class TT1> // expected-note {{template parameter is declared here}}
struct A {};
template<class> requires C2<int> struct B {}; // expected-note {{'B' declared here}}
@@ -678,16 +678,16 @@ namespace nttp_inconsistent {
template<class A, A B> struct X {};
// expected-error@-1 {{conflicting deduction 'C' against 'int' for parameter}}
template<template<class C, int D> class TT> struct Y {};
- // expected-note@-1 {{previous template template parameter is here}}
+ // expected-note@-1 {{template parameter is declared here}}
template struct Y<X>;
- // expected-note@-1 {{has different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible with its corresponding template template parameter}}
} // namespace t1
namespace t2 {
template<class A, A B = 0> struct X {};
// expected-error@-1 {{conflicting deduction 'C' against 'int' for parameter}}
template<template<class C> class TT> struct Y {};
- // expected-note@-1 {{previous template template parameter is here}}
+ // expected-note@-1 {{template parameter is declared here}}
template struct Y<X>;
- // expected-note@-1 {{has different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible with its corresponding template template parameter}}
} // namespace t2
} // namespace nttp_inconsistent
diff --git a/clang/test/SemaTemplate/dedup-types-builtin.cpp b/clang/test/SemaTemplate/dedup-types-builtin.cpp
index fe6efd7..8e97894 100644
--- a/clang/test/SemaTemplate/dedup-types-builtin.cpp
+++ b/clang/test/SemaTemplate/dedup-types-builtin.cpp
@@ -134,7 +134,9 @@ constexpr int dedup_params_into_type_list(TypeList<__builtin_dedup_pack<T...>...
static_assert(dedup_params_into_type_list(static_cast<TypeList<int,short,long>*>(nullptr), 1, short(1), 1, 1l, 1l) != 5); // expected-error {{static assertion failed}} \
// expected-note {{expression evaluates}}
-template <class T, __builtin_dedup_pack<T, int>...> // expected-error 2{{expansions of '__builtin_dedup_pack' are not supported here}}
+template <class T, __builtin_dedup_pack<T, int>...>
+// expected-error@-1 2{{expansions of '__builtin_dedup_pack' are not supported here}}
+// expected-note@-2 2{{template parameter is declared here}}
struct InTemplateParams {};
InTemplateParams<int> itp1;
InTemplateParams<int, 1, 2, 3, 4, 5> itp2;
diff --git a/clang/test/SemaTemplate/default-arguments.cpp b/clang/test/SemaTemplate/default-arguments.cpp
index 5ea34c0..fdf666b 100644
--- a/clang/test/SemaTemplate/default-arguments.cpp
+++ b/clang/test/SemaTemplate/default-arguments.cpp
@@ -1,12 +1,12 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
-template<typename T, int N = 2> struct X; // expected-note{{template is declared here}}
+template<typename T, int N = 2> struct X; // expected-note {{template parameter is declared here}}
X<int, 1> *x1;
X<int> *x2;
-X<> *x3; // expected-error{{too few template arguments for class template 'X'}}
+X<> *x3; // expected-error{{missing template argument for template parameter}}
template<typename U = float, int M> struct X;
@@ -20,6 +20,7 @@ template<class T> struct a { };
template<> struct a<int> { static const bool v = true; };
template<class T, bool = a<T>::v> struct p { }; // expected-error {{no member named 'v'}}
+ // expected-note@-1 {{template parameter is declared here}}
template struct p<bool>; // expected-note {{in instantiation of default argument for 'p<bool>' required here}}
template struct p<int>;
@@ -50,12 +51,14 @@ template<typename T> struct X1 { };
template<typename T>
struct X2 {
template<typename U = typename X1<T>::type> // expected-error{{no type named 'type' in 'X1<int>'}} \
- // expected-error{{no type named 'type' in 'X1<char>'}}
- struct Inner1 { }; // expected-note{{template is declared here}}
+ // expected-error{{no type named 'type' in 'X1<char>'}} \
+ // expected-note {{template parameter is declared here}}
+ struct Inner1 { };
template<T Value = X1<T>::value> // expected-error{{no member named 'value' in 'X1<int>'}} \
- // expected-error{{no member named 'value' in 'X1<char>'}}
- struct NonType1 { }; // expected-note{{template is declared here}}
+ // expected-error{{no member named 'value' in 'X1<char>'}} \
+ // expected-note {{template parameter is declared here}}
+ struct NonType1 { };
template<T Value>
struct Inner2 { };
@@ -74,10 +77,10 @@ struct X2 {
X2<int> x2i; // expected-note{{in instantiation of template class 'X2<int>' requested here}}
X2<int>::Inner1<float> x2iif;
-X2<int>::Inner1<> x2bad; // expected-error{{too few template arguments for class template 'Inner1'}}
+X2<int>::Inner1<> x2bad; // expected-error{{missing template argument for template parameter}}
X2<int>::NonType1<'a'> x2_nontype1;
-X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{too few template arguments for class template 'NonType1'}}
+X2<int>::NonType1<> x2_nontype1_bad; // expected-error{{missing template argument for template parameter}}
// Check multi-level substitution into template type arguments
X2<int>::Inner3<float>::VeryInner<> vi;
@@ -112,12 +115,12 @@ template<typename T, template<typename> class X = T::template apply>
int array4[is_same<X4<add_pointer>,
X4<add_pointer, add_pointer::apply> >::value? 1 : -1];
-template<int> struct X5 {};
+template<int> struct X5 {}; // expected-note {{template parameter is declared here}}
template<long long> struct X5b {};
template<typename T,
template<T> class B = X5> // expected-error {{cannot be narrowed from type 'long long' to 'int'}}
- // expected-note@-1 {{has different template parameters}}
- // expected-note@-2 {{previous template template parameter is here}}
+ // expected-note@-1 {{template template argument is incompatible}}
+ // expected-note@-2 {{template parameter is declared here}}
struct X6 {};
X6<int> x6a;
diff --git a/clang/test/SemaTemplate/instantiate-member-pointers.cpp b/clang/test/SemaTemplate/instantiate-member-pointers.cpp
index 8b6c2ef..e4974b2 100644
--- a/clang/test/SemaTemplate/instantiate-member-pointers.cpp
+++ b/clang/test/SemaTemplate/instantiate-member-pointers.cpp
@@ -18,7 +18,7 @@ template<typename T, typename Class>
struct X2 {
T f(Class &obj, T Class::*pm) { // expected-error{{to a reference}} \
// expected-error{{member pointer to void}}
- return obj.*pm;
+ return obj.*pm;
}
};
@@ -40,12 +40,12 @@ typedef int Y::*IntMember;
template<IntMember Member>
struct X4 {
X3<int, Y, Member> member;
-
+
int &getMember(Y& y) { return y.*Member; }
};
-int &get_X4(X4<&Y::x> x4, Y& y) {
- return x4.getMember(y);
+int &get_X4(X4<&Y::x> x4, Y& y) {
+ return x4.getMember(y);
}
template<IntMember Member>
@@ -64,12 +64,12 @@ namespace ValueDepMemberPointer {
template <typename T> void S<T>::instantiate() {
int a[(int)sizeof(T)-42]; // expected-error{{array with a negative size}}
}
- S<int> s;
+ S<int> s;
}
namespace PR18192 {
struct A { struct { int n; }; };
- template<int A::*> struct X {};
+ template<int A::*> struct X {}; // expected-note {{template parameter is declared here}}
constexpr int A::*p = &A::n;
X<p> x; // expected-error{{not a pointer to member constant}}
}
diff --git a/clang/test/SemaTemplate/instantiate-template-template-parm.cpp b/clang/test/SemaTemplate/instantiate-template-template-parm.cpp
index dce30aa2..601049a 100644
--- a/clang/test/SemaTemplate/instantiate-template-template-parm.cpp
+++ b/clang/test/SemaTemplate/instantiate-template-template-parm.cpp
@@ -20,17 +20,17 @@ apply<add_reference, int>::type ir = i;
apply<add_reference, float>::type fr = i; // expected-error{{non-const lvalue reference to type 'float' cannot bind to a value of unrelated type 'int'}}
// Template template parameters
-template<int> struct B;
+template<int> struct B; // expected-note {{template parameter is declared here}}
template<typename T,
template<T Value> class X> // expected-error{{cannot have type 'float'}}
// expected-error@-1 {{cannot be narrowed from type 'long long' to 'int'}}
- // expected-note@-2 {{previous template template parameter is here}}
+ // expected-note@-2 2{{template parameter is declared here}}
struct X0 { };
X0<int, B> x0b1;
X0<float, B> x0b2; // expected-note{{while substituting}}
-X0<long long, B> x0b3; // expected-note {{has different template parameters}}
+X0<long long, B> x0b3; // expected-note {{template template argument is incompatible}}
template<template<int V> class TT>
struct X1 { };
diff --git a/clang/test/SemaTemplate/instantiation-default-1.cpp b/clang/test/SemaTemplate/instantiation-default-1.cpp
index 3e70a21..8ef9f12 100644
--- a/clang/test/SemaTemplate/instantiation-default-1.cpp
+++ b/clang/test/SemaTemplate/instantiation-default-1.cpp
@@ -1,7 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
template<typename T, typename U = const T> struct Def1;
-template<> struct Def1<int> {
+template<> struct Def1<int> {
void foo();
};
@@ -22,9 +22,10 @@ void test_Def1(Def1<int, const int> *d1, Def1<const int, const int> *d2,
template<typename T, // FIXME: bad error message below, needs better location info
typename T2 = const T*> // expected-error{{'T2' declared as a pointer to a reference}}
+ // expected-note@-1 {{template parameter is declared here}}
struct Def2;
-template<> struct Def2<int> {
+template<> struct Def2<int> {
void foo();
};
@@ -40,11 +41,11 @@ template<> struct Def1<const int> { }; // expected-error{{redefinition of 'Def1<
template<typename T, typename T2 = T&> struct Def3;
-template<> struct Def3<int> {
+template<> struct Def3<int> {
void foo();
};
-template<> struct Def3<int&> {
+template<> struct Def3<int&> {
void bar();
};
@@ -83,7 +84,7 @@ template<typename R, typename Arg1, typename Arg2 = Arg1,
typename FuncType = R (*)(Arg1, Arg2)>
struct Def6;
-template<> struct Def6<int, float> {
+template<> struct Def6<int, float> {
void foo();
};
@@ -91,7 +92,7 @@ template<> struct Def6<bool, int[5], float(double, double)> {
void bar();
};
-bool test_Def6(Def6<int, float, float> *d6a,
+bool test_Def6(Def6<int, float, float> *d6a,
Def6<int, float, float, int (*)(float, float)> *d6b,
Def6<bool, int[5], float(double, double),
bool(*)(int*, float(*)(double, double))> *d6c) {
diff --git a/clang/test/SemaTemplate/instantiation-default-2.cpp b/clang/test/SemaTemplate/instantiation-default-2.cpp
index ffa77cf..e5db310 100644
--- a/clang/test/SemaTemplate/instantiation-default-2.cpp
+++ b/clang/test/SemaTemplate/instantiation-default-2.cpp
@@ -4,8 +4,7 @@
template<typename T, T Value> struct Constant;
// FIXME: bad location precxx20-error@-1 {{a non-type template parameter cannot have type 'float'}}
-// expected-note@-2 {{template parameter is declared here}}
-// cxx20-note@-3 {{template parameter is declared here}}
+// expected-note@-2 2{{template parameter is declared here}}
Constant<int, 5> *c1;
diff --git a/clang/test/SemaTemplate/instantiation-dependence.cpp b/clang/test/SemaTemplate/instantiation-dependence.cpp
index 1a97dbf..d98d982 100644
--- a/clang/test/SemaTemplate/instantiation-dependence.cpp
+++ b/clang/test/SemaTemplate/instantiation-dependence.cpp
@@ -17,7 +17,8 @@ namespace PR24076 {
}
template<class T,
- class = void_t<decltype(declval<T>() + 1)>> // expected-error {{invalid operands to binary expression}}
+ class = // expected-note {{template parameter is declared here}}
+ void_t<decltype(declval<T>() + 1)>> // expected-error {{invalid operands to binary expression}}
struct bar {};
bar<s> bar; // expected-note {{in instantiation of}}
diff --git a/clang/test/SemaTemplate/instantiation-depth-subst-2.cpp b/clang/test/SemaTemplate/instantiation-depth-subst-2.cpp
index 2b519e9..66fd1af 100644
--- a/clang/test/SemaTemplate/instantiation-depth-subst-2.cpp
+++ b/clang/test/SemaTemplate/instantiation-depth-subst-2.cpp
@@ -2,5 +2,6 @@
template<int N> struct S { };
template<typename T> S<T() + T()> operator+(T, T); // expected-error {{instantiation exceeded maximum depth}} expected-note 2{{while substituting}}
+// expected-note@-1 {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
S<0> s;
int k = s + s; // expected-note {{while substituting}}
diff --git a/clang/test/SemaTemplate/instantiation-depth-subst.cpp b/clang/test/SemaTemplate/instantiation-depth-subst.cpp
index 062a8ed..17944bc 100644
--- a/clang/test/SemaTemplate/instantiation-depth-subst.cpp
+++ b/clang/test/SemaTemplate/instantiation-depth-subst.cpp
@@ -3,7 +3,8 @@
// PR9793
template<typename T> auto f(T t) -> decltype(f(t)); // \
// expected-error {{recursive template instantiation exceeded maximum depth of 2}} \
-// expected-note 2 {{while substituting}}
+// expected-note 2 {{while substituting}} \
+// expected-note {{use -ftemplate-depth=N to increase recursive template instantiation depth}}
struct S {};
int k = f(S{}); // expected-note {{while substituting}}
diff --git a/clang/test/SemaTemplate/ms-unqualified-base-class.cpp b/clang/test/SemaTemplate/ms-unqualified-base-class.cpp
index 5e926c5..d2b02e5 100644
--- a/clang/test/SemaTemplate/ms-unqualified-base-class.cpp
+++ b/clang/test/SemaTemplate/ms-unqualified-base-class.cpp
@@ -84,7 +84,7 @@ int main() {
return I;
}
-template <typename Type, int TSize> class Vec {}; // expected-note {{template is declared here}}
+template <typename Type, int TSize> class Vec {}; // expected-note {{template parameter is declared here}}
template <int TDim> class Index : public Vec<int, TDim> {
// after-error@+1 {{member initializer 'Vec' does not name a non-static data member or base class}}
@@ -107,7 +107,7 @@ template <typename T> class Wrong : public Vec<T, 4> {
template class Wrong<double>;
template <typename T> class Wrong2 : public Vec<T, 4> {
- Wrong2() : Vec<T>() {} // expected-error {{too few template arguments for class template 'Vec'}}
+ Wrong2() : Vec<T>() {} // expected-error {{missing template argument for template parameter}}
};
template class Wrong2<double>;
diff --git a/clang/test/SemaTemplate/nested-template.cpp b/clang/test/SemaTemplate/nested-template.cpp
index b5da1b1..dbdf605 100644
--- a/clang/test/SemaTemplate/nested-template.cpp
+++ b/clang/test/SemaTemplate/nested-template.cpp
@@ -114,16 +114,16 @@ template<typename T>
struct X2 {
template<template<class U, T Value> class> // expected-error {{cannot have type 'float'}}
// expected-error@-1 {{cannot be narrowed from type 'long long' to 'int'}}
- // expected-note@-2 {{previous template template parameter is here}}
+ // expected-note@-2 {{template parameter is declared here}}
struct Inner { };
};
-template<typename T, int Value>
+template<typename T, int Value> // expected-note {{template parameter is declared here}}
struct X2_arg;
X2<int>::Inner<X2_arg> x2i1;
X2<float> x2a; // expected-note{{instantiation}}
-X2<long long>::Inner<X2_arg> x2i3; // expected-note {{has different template parameters}}
+X2<long long>::Inner<X2_arg> x2i3; // expected-note {{template template argument is incompatible}}
namespace PR10896 {
template<typename TN>
diff --git a/clang/test/SemaTemplate/partial-spec-instantiate.cpp b/clang/test/SemaTemplate/partial-spec-instantiate.cpp
index 0b84df6..f171bf4 100644
--- a/clang/test/SemaTemplate/partial-spec-instantiate.cpp
+++ b/clang/test/SemaTemplate/partial-spec-instantiate.cpp
@@ -42,7 +42,7 @@ namespace WonkyAccess {
}
namespace rdar9169404 {
- template<typename T, T N> struct X { };
+ template<typename T, T N> struct X { }; // #rdar9169404-X
template<bool C> struct X<bool, C> {
typedef int type;
};
@@ -50,6 +50,7 @@ namespace rdar9169404 {
X<bool, -1>::type value;
#if __cplusplus >= 201103L
// expected-error@-2 {{non-type template argument evaluates to -1, which cannot be narrowed to type 'bool'}}
+ // expected-note@#rdar9169404-X {{template parameter is declared here}}
#endif
}
diff --git a/clang/test/SemaTemplate/recovery-crash.cpp b/clang/test/SemaTemplate/recovery-crash.cpp
index 9b106f1..0d8c7e6 100644
--- a/clang/test/SemaTemplate/recovery-crash.cpp
+++ b/clang/test/SemaTemplate/recovery-crash.cpp
@@ -26,13 +26,14 @@ namespace PR16134 {
}
namespace PR16225 {
- template <typename T> void f();
+ template <typename T> void f(); // #PR16225-f
template <typename C> void g(C*) {
struct LocalStruct : UnknownBase<Mumble, C> { }; // expected-error {{use of undeclared identifier 'Mumble'}}
f<LocalStruct>();
#if __cplusplus <= 199711L
// expected-warning@-2 {{template argument uses local type 'LocalStruct'}}
// expected-note@-3 {{while substituting explicitly-specified template arguments}}
+ // expected-note@#PR16225-f {{template parameter is declared here}}
#endif
struct LocalStruct2 : UnknownBase<C> { }; // expected-error {{no template named 'UnknownBase'}}
}
diff --git a/clang/test/SemaTemplate/temp_arg.cpp b/clang/test/SemaTemplate/temp_arg.cpp
index 538056a..9048744 100644
--- a/clang/test/SemaTemplate/temp_arg.cpp
+++ b/clang/test/SemaTemplate/temp_arg.cpp
@@ -1,10 +1,10 @@
// RUN: %clang_cc1 -fsyntax-only -verify=expected,precxx17 %std_cxx98-14 %s
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 %std_cxx17- %s
-template<typename T,
- int I,
- template<typename> class TT>
- class A; // precxx17-note 3 {{template is declared here}} \
- cxx17-note 2 {{template is declared here}} \
+template<typename T,
+ int I,
+ template<typename> class TT> // expected-note {{template parameter is declared here}}
+ class A; // precxx17-note 2 {{template is declared here}} \
+ cxx17-note {{template is declared here}} \
cxx17-note {{candidate template ignored: couldn't infer template argument 'T'}} \
cxx17-note {{implicit deduction guide declared as 'template <typename T, int I, template <typename> class TT> A(A<T, I, TT>) -> A<T, I, TT>'}} \
cxx17-note {{candidate function template not viable: requires 1 argument, but 0 were provided}} \
@@ -15,7 +15,7 @@ template<typename> class X;
A<int, 0, X> * a1;
A<float, 1, X, double> *a2; // expected-error{{too many template arguments for class template 'A'}}
-A<float, 1> *a3; // expected-error{{too few template arguments for class template 'A'}}
+A<float, 1> *a3; // expected-error{{missing template argument for template parameter}}
A a4; // precxx17-error{{use of class template 'A' requires template arguments}} \
cxx17-error{{no viable constructor or deduction guide for deduction of template arguments of 'A'}}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp b/clang/test/SemaTemplate/temp_arg_nontype.cpp
index 7d2a010..e9194fb 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -std=c++98 -Wconversion -verify %s
-template<int N> struct A; // expected-note 5{{template parameter is declared here}}
+template<int N> struct A; // expected-note 6{{template parameter is declared here}}
A<0> *a0;
@@ -42,7 +42,7 @@ double g(double); // expected-note 2{{candidate function}}
int h(int);
float h2(float);
-template<int fp(int)> struct A3; // expected-note 1{{template parameter is declared here}}
+template<int fp(int)> struct A3; // expected-note 2{{template parameter is declared here}}
A3<h> *a14_1;
A3<&h> *a14_2;
A3<f> *a14_3;
@@ -61,7 +61,7 @@ A4<*X_volatile_ptr> *a15_2; // expected-error{{non-type template argument does n
A4<y> *15_3; // expected-error{{non-type template parameter of reference type 'const X &' cannot bind to template argument of type 'struct Y'}} \
// FIXME: expected-error{{expected unqualified-id}}
-template<int (&fr)(int)> struct A5; // expected-note{{template parameter is declared here}}
+template<int (&fr)(int)> struct A5; // expected-note 2{{template parameter is declared here}}
A5<h> *a16_1;
A5<f> *a16_3;
A5<h2> *a16_6; // expected-error{{non-type template parameter of reference type 'int (&)(int)' cannot bind to template argument of type 'float (float)'}}
@@ -86,7 +86,7 @@ A6<&Z::baz> *a17_3; // expected-error-re{{non-type template argument of type 'do
template<int Z::*pm> struct A7; // expected-note{{template parameter is declared here}}
-template<int Z::*pm> struct A7c;
+template<int Z::*pm> struct A7c; // expected-note{{template parameter is declared here}}
A7<&Z::int_member> *a18_1;
A7c<&Z::int_member> *a18_2;
A7<&Z::float_member> *a18_3; // expected-error{{non-type template argument of type 'float Z::*' cannot be converted to a value of type 'int Z::*'}}
@@ -444,7 +444,10 @@ namespace dependent_nested_partial_specialization {
A<Y>::B<int, &n> ay; // expected-error {{undefined}} expected-note {{instantiation of}}
template<template<typename> class X> struct C {
- template<typename T, int N, int M> struct D; // expected-note {{here}}
+ template<typename T, int N,
+ int M // expected-note {{template parameter is declared here}}
+ > struct D;
+ // expected-note@-1 {{template is declared here}}
template<typename T, X<T> N> struct D<T*, N, N + 1> {}; // expected-error {{type of specialized non-type template argument depends on}}
};
C<X>::D<int*, 0, 1> cx;
@@ -494,7 +497,12 @@ namespace dependent_backreference {
Incomplete f(int); // expected-note 2{{here}}
int f(short);
- template<typename T, T Value, int(*)[sizeof(f(Value))]> struct X {}; // expected-error 2{{incomplete}}
+ template<typename T, T Value,
+ int(*)[ // expected-note 2{{template parameter is declared here}}
+ sizeof(f(Value)) // expected-error 2{{incomplete}}
+ ]
+ > struct X {};
+
int arr[sizeof(int)];
// When checking this template-id, we must not treat 'Value' as having type
// 'int'; its type is the dependent type 'T'.
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
index 5752cba..32bb678 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx11.cpp
@@ -30,7 +30,7 @@ namespace Auto {
namespace check_conversion_early {
struct X {};
- template<int> struct A {};
+ template<int> struct A {}; // expected-note {{template parameter is declared here}}
template<X &x> struct A<x> {}; // expected-error {{not implicitly convertible}}
struct Y { constexpr operator int() const { return 0; } };
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
index 9c25e26..55d1d56 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx1z.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
-template<typename T, T val> struct A {}; // expected-note 3{{template parameter is declared here}}
+template<typename T, T val> struct A {}; // expected-note 15{{template parameter is declared here}}
template<typename T, typename U> constexpr bool is_same = false;
template<typename T> constexpr bool is_same<T, T> = true;
@@ -254,8 +254,8 @@ namespace Auto {
}
namespace DecltypeAuto {
- template<auto v> struct A { };
- template<decltype(auto) v> struct DA { };
+ template<auto v> struct A { }; // expected-note {{template parameter is declared here}}
+ template<decltype(auto) v> struct DA { }; // expected-note {{template parameter is declared here}}
template<auto&> struct R { };
auto n = 0; // expected-note + {{declared here}}
@@ -448,7 +448,7 @@ namespace PR42108 {
struct R {};
struct S { constexpr S() {} constexpr S(R) {} };
struct T { constexpr operator S() { return {}; } };
- template <const S &> struct A {}; // expected-note {{template parameter is declared here}}
+ template <const S &> struct A {}; // expected-note 3{{template parameter is declared here}}
void f() {
A<R{}>(); // expected-error {{would bind reference to a temporary}}
A<S{}>(); // expected-error {{reference to temporary object}}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
index 8450ff0..2f029db 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx20.cpp
@@ -16,7 +16,7 @@ union U { int a, b; } u;
int n; // expected-note 1+{{here}}
// pointers to subobjects
-template<int *> struct IntPtr {};
+template<int *> struct IntPtr {}; // expected-note 2{{template parameter is declared here}}
using IPn = IntPtr<&n + 1>;
using IPn = IntPtr<&n + 1>;
@@ -30,7 +30,7 @@ using IP3 = IntPtr<s.n + 3>;
using IP5 = IntPtr<&s.n[5]>; // expected-error {{not a constant expression}} expected-note {{cannot refer to element 5 of array of 3 elements}}
-template<int &> struct IntRef {};
+template<int &> struct IntRef {}; // expected-note 4{{template parameter is declared here}}
using IRn = IntRef<*(&n + 1)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of 'n'}}
using IRn = IntRef<*(&n + 1)>; // expected-error {{not a constant expression}} expected-note {{dereferenced pointer past the end of 'n'}}
@@ -72,20 +72,20 @@ namespace ClassNTTP {
static_assert(&id<A{1,3}> != &id<a>);
int k = id<1>; // expected-error {{no viable conversion from 'int' to 'A'}}
- // expected-note@#ClassNTTP1 {{passing argument to parameter 'a' here}}
+ // expected-note@#ClassNTTP1 {{template parameter is declared here}}
struct B {
constexpr B() {}
constexpr B(int) = delete; // expected-note {{here}}
};
- template<B> struct Q {}; // expected-note {{passing argument to parameter here}}
+ template<B> struct Q {}; // expected-note {{template parameter is declared here}}
Q<1> q; // expected-error {{conversion function from 'int' to 'B' invokes a deleted function}}
struct C {
constexpr C() {}
C(const C&) = delete; // expected-note {{here}}
};
- template<C> struct R {}; // expected-note {{passing argument to parameter here}}
+ template<C> struct R {}; // expected-note {{template parameter is declared here}}
constexpr C c;
R<c> r; // expected-error {{call to deleted constructor}}
}
@@ -228,7 +228,7 @@ namespace UnnamedBitfield {
//
// FIXME: We shouldn't track a value for unnamed bit-fields, nor number
// them when computing field indexes.
- template <A> struct X {};
+ template <A> struct X {}; // expected-note {{template parameter is declared here}}
constexpr A a;
using T = X<a>;
using T = X<A{}>;
@@ -238,7 +238,7 @@ namespace UnnamedBitfield {
}
namespace Temporary {
- template<const int &> struct A {}; // expected-note {{template parameter is declared here}}
+ template<const int &> struct A {}; // expected-note 6{{template parameter is declared here}}
A<0> a0; // expected-error {{conversion from 'int' to 'const int &' in converted constant expression would bind reference to a temporary}}
A<(const int&)1> a1; // expected-error {{reference to temporary object is not allowed in a template argument}}
@@ -254,18 +254,18 @@ namespace Temporary {
X &&x = X{};
A<x.a[3]> a5; // expected-error {{reference to subobject of temporary object}}
- template<const int*> struct B {};
+ template<const int*> struct B {}; // expected-note 3{{template parameter is declared here}}
B<&(int&)(int&&)0> b0; // expected-error {{pointer to temporary object}}
B<&r3> b3; // expected-error {{pointer to temporary object}}
B<&x.a[3]> b5; // expected-error {{pointer to subobject of temporary object}}
struct C { const int *p[2]; };
- template<C> struct D {};
+ template<C> struct D {}; // expected-note {{template parameter is declared here}}
D<C{nullptr, &r3}> d; // expected-error {{pointer to temporary object}}
}
namespace StringLiteral {
- template<decltype(auto)> struct Y {};
+ template<decltype(auto)> struct Y {}; // expected-note 6{{template parameter is declared here}}
Y<&"hello"> y1; // expected-error {{pointer to string literal}}
Y<"hello"> y2; // expected-error {{reference to string literal}}
Y<+"hello"> y3; // expected-error {{pointer to subobject of string literal}}
@@ -278,7 +278,7 @@ namespace StringLiteral {
}
namespace TypeInfo {
- template<decltype(auto)> struct Y {};
+ template<decltype(auto)> struct Y {}; // expected-note 4{{template parameter is declared here}}
Y<&typeid(int)> y1; // expected-error {{pointer to type_info object}}
Y<typeid(int)> y2; // expected-error {{reference to type_info object}}
@@ -289,7 +289,7 @@ namespace TypeInfo {
}
namespace Predefined {
- template<decltype(auto)> struct Y {};
+ template<decltype(auto)> struct Y {}; // expected-note 7{{template parameter is declared here}}
struct A { const char *p; };
struct B { const char &r; };
diff --git a/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp b/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp
index c4ac36e..9ecdd19 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype_cxx2c.cpp
@@ -5,16 +5,16 @@ struct Test {
int b = 42;
};
-template <Test t>
+template <Test t> // expected-note {{template parameter is declared here}}
struct A {
static constexpr auto a = t.a;
static constexpr auto b = t.b;
};
-template <auto N>
+template <auto N> // expected-note {{template parameter is declared here}}
struct Auto {};
-template <typename T, T elem>
+template <typename T, T elem> // expected-note {{template parameter is declared here}}
struct Explicit{};
struct L {};
@@ -57,8 +57,8 @@ void test() {
DefaultParam3<> d3;
}
-template<auto n> struct B { /* ... */ };
-template<int i> struct C { /* ... */ };
+template<auto n> struct B { /* ... */ }; // expected-note 2{{template parameter is declared here}}
+template<int i> struct C { /* ... */ }; // expected-note {{template parameter is declared here}}
C<{ 42 }> c1; // expected-warning {{braces around scalar initializer}}
struct J1 {
@@ -129,6 +129,7 @@ namespace error_on_type_instantiation {
// expected-note@-1 {{candidate function has been explicitly deleted}}
template<class T, decltype(f(T()))> struct X {};
// expected-error@-1 {{call to deleted function 'f'}}
+ // expected-note@-2 {{template parameter is declared here}}
template<class T> void g() { X<T, 0> x; }
// expected-note@-1 {{while substituting prior template arguments into non-type template parameter [with T = int]}}
template void g<int>();
diff --git a/clang/test/SemaTemplate/temp_arg_template.cpp b/clang/test/SemaTemplate/temp_arg_template.cpp
index 73fa57b..b4b442c 100644
--- a/clang/test/SemaTemplate/temp_arg_template.cpp
+++ b/clang/test/SemaTemplate/temp_arg_template.cpp
@@ -2,13 +2,13 @@
// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx17 -std=c++17 %s
template<template<typename T> class X> struct A; // #A
-// expected-note@-1 2{{previous template template parameter is here}}
+// expected-note@-1 3{{template parameter is declared here}}
-template<template<typename T, int I> class X> struct B; // expected-note{{previous template template parameter is here}}
+template<template<typename T, int I> class X> struct B; // expected-note{{template parameter is declared here}}
template<template<int I> class X> struct C;
// expected-error@-1 {{conversion from 'int' to 'const int &' in converted constant expression would bind reference to a temporary}}
-// expected-note@-2 {{previous template template parameter is here}}
+// expected-note@-2 {{template parameter is declared here}}
template<class> struct X; // expected-note {{template is declared here}}
template<int N> struct Y; // expected-note {{template parameter is declared here}}
@@ -18,7 +18,10 @@ template<const int &N> struct Yref; // expected-note {{template parameter is dec
namespace N {
template<class> struct Z;
}
-template<class, class> struct TooMany; // expected-note{{template is declared here}}
+template<
+ class,
+ class> // expected-note {{template parameter is declared here}}
+struct TooMany;
A<X> *a1;
@@ -26,14 +29,14 @@ A<N::Z> *a2;
A< ::N::Z> *a3;
A<Y> *a4; // expected-error@#A {{template argument for non-type template parameter must be an expression}}
- // expected-note@-1 {{different template parameters}}
-A<TooMany> *a5; // expected-error {{too few template arguments for class template 'TooMany'}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
+A<TooMany> *a5; // expected-error@#A {{no template parameter in this template template parameter}}
+ // expected-note@-1 {{template template argument is incompatible}}
B<X> *a6; // expected-error {{too many template arguments for class template 'X'}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
C<Y> *a7;
C<Ylong> *a8;
-C<Yref> *a9; // expected-note {{different template parameters}}
+C<Yref> *a9; // expected-note {{template template argument is incompatible}}
template<typename T> void f(int);
@@ -109,7 +112,7 @@ void foo() {
namespace CheckDependentNonTypeParamTypes {
template<template<typename T, typename U, T v> class X> struct A {
- // expected-note@-1 {{previous template template parameter is here}}
+ // expected-note@-1 2{{template parameter is declared here}}
void f() {
X<int, void*, 3> x;
}
@@ -128,7 +131,7 @@ namespace CheckDependentNonTypeParamTypes {
};
// FIXME: This should probably be rejected, but the rules are at best unclear.
- A<B> ab; // expected-note {{different template parameters}}
+ A<B> ab; // expected-note {{template template argument is incompatible}}
void use() {
ab.f();
@@ -138,6 +141,7 @@ namespace CheckDependentNonTypeParamTypes {
template<class> struct C {
template<class T, T V> struct D {};
+ // expected-note@-1 {{template parameter is declared here}}
using T = D<char, 1234>;
// expected-error@-1 {{evaluates to 1234, which cannot be narrowed to type 'char'}}
};
diff --git a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp
index 60d98a6..2b18a9f 100644
--- a/clang/test/SemaTemplate/temp_arg_template_p0522.cpp
+++ b/clang/test/SemaTemplate/temp_arg_template_p0522.cpp
@@ -1,8 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++20 %s
-// expected-note@temp_arg_template_p0522.cpp:* 1+{{template is declared here}}
// expected-note@temp_arg_template_p0522.cpp:* 1+{{template parameter is declared here}}
-// expected-note@temp_arg_template_p0522.cpp:* 1+{{previous template template parameter is here}}
template<template<int> typename> struct Ti; // #Ti
template<template<int...> typename> struct TPi; // #TPi
@@ -34,14 +32,14 @@ namespace IntParam {
Ti<iDi>,
Ti<Pi>,
Ti<iDt>>;
- using err1 = Ti<ii>; // expected-error {{too few template arguments for class template 'ii'}}
- // expected-note@-1 {{different template parameters}}
- using err2 = Ti<iiPi>; // expected-error {{too few template arguments for class template 'iiPi'}}
- // expected-note@-1 {{different template parameters}}
+ using err1 = Ti<ii>; // expected-error@#Ti {{no template parameter in this template template parameter}}
+ // expected-note@-1 {{template template argument is incompatible}}
+ using err2 = Ti<iiPi>; // expected-error@#Ti {{no template parameter in this template template parameter}}
+ // expected-note@-1 {{template template argument is incompatible}}
using err3 = Ti<t0>; // expected-error@#Ti {{template argument for template type parameter must be a type}}
- // expected-note@-1 {{different template parameters}}
- using err4 = Ti<it>; // expected-error {{too few template arguments for class template 'it'}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
+ using err4 = Ti<it>; // expected-error@#Ti {{no template parameter in this template template parameter}}
+ // expected-note@-1 {{template template argument is incompatible}}
}
// These are accepted by the backwards-compatibility "parameter pack in
@@ -50,11 +48,11 @@ namespace IntPackParam {
using ok = TPi<Pi>;
using ok_compat = Pt<TPi<i>, TPi<iDi>, TPi<ii>, TPi<iiPi>>;
using err1 = TPi<t0>; // expected-error@#TPi {{template argument for template type parameter must be a type}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
using err2 = TPi<iDt>; // expected-error@#TPi {{template argument for template type parameter must be a type}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
using err3 = TPi<it>; // expected-error@#TPi {{template argument for template type parameter must be a type}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
}
namespace IntAndPackParam {
@@ -65,19 +63,19 @@ namespace IntAndPackParam {
namespace DependentType {
using ok = Pt<tT0<int, i>, tT0<int, iDi>>;
- using err1 = tT0<int, ii>; // expected-error {{too few template arguments for class template 'ii'}}
- // expected-note@-1 {{different template parameters}}
+ using err1 = tT0<int, ii>; // expected-error@#tT0 {{no template parameter in this template template parameter}}
+ // expected-note@-1 {{template template argument is incompatible}}
using err2 = tT0<short, i>;
using err2a = tT0<long long, i>; // expected-error@#tT0 {{cannot be narrowed from type 'long long' to 'int'}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
using err2b = tT0<void*, i>; // expected-error@#tT0 {{value of type 'void *' is not implicitly convertible to 'int'}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
using err3 = tT0<short, t0>; // expected-error@#tT0 {{template argument for template type parameter must be a type}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
using ok2 = Tt0<t0>;
using err4 = Tt0<it>; // expected-error@#Tt0 {{template argument for non-type template parameter must be an expression}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
}
namespace Auto {
@@ -94,22 +92,22 @@ namespace Auto {
TInt<Auto> ia;
TInt<AutoPtr> iap; // expected-error@#TInt {{non-type template parameter '' with type 'auto *' has incompatible initializer of type 'int'}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
TInt<DecltypeAuto> ida;
TInt<Int> ii;
TInt<IntPtr> iip; // expected-error@#TInt {{conversion from 'int' to 'int *' is not allowed in a converted constant expression}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
TIntPtr<Auto> ipa;
TIntPtr<AutoPtr> ipap;
TIntPtr<DecltypeAuto> ipda;
TIntPtr<Int> ipi; // expected-error@#TIntPtr {{value of type 'int *' is not implicitly convertible to 'int'}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
TIntPtr<IntPtr> ipip;
TAuto<Auto> aa;
TAuto<AutoPtr> aap; // expected-error@#TAuto {{non-type template parameter '' with type 'auto *' has incompatible initializer of type 'auto'}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
TAuto<Int> ai; // FIXME: ill-formed (?)
TAuto<IntPtr> aip; // FIXME: ill-formed (?)
@@ -131,7 +129,7 @@ namespace Auto {
// parameters.
TDecltypeAuto<Auto> daa;
TDecltypeAuto<AutoPtr> daap; // expected-error@#TDecltypeAuto {{non-type template parameter '' with type 'auto *' has incompatible initializer of type 'decltype(auto)'}}
- // expected-note@-1 {{different template parameters}}
+ // expected-note@-1 {{template template argument is incompatible}}
int n;
template<auto A, decltype(A) B = &n> struct SubstFailure;
@@ -160,11 +158,10 @@ namespace GH101394 {
} // namespace t1
namespace t2 {
template<template<Y> class> struct A {}; // #A
- template<X> struct B; // #B
+ template<X> struct B;
template struct A<B>;
// expected-error@#A {{no viable conversion from 'const Y' to 'X'}}
- // expected-note@-2 {{different template parameters}}
+ // expected-note@-2 {{template template argument is incompatible}}
// expected-note@#X 2{{not viable}}
- // expected-note@#B {{passing argument to parameter here}}
} // namespace t2
} // namespace GH101394
diff --git a/clang/test/SemaTemplate/temp_arg_type.cpp b/clang/test/SemaTemplate/temp_arg_type.cpp
index 392d257..a0d2bc3 100644
--- a/clang/test/SemaTemplate/temp_arg_type.cpp
+++ b/clang/test/SemaTemplate/temp_arg_type.cpp
@@ -1,9 +1,12 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98 -std=c++98 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++1z %s
-template<typename T> class A; // expected-note 2 {{template parameter is declared here}} expected-note{{template is declared here}}
+template<typename T> class A;
+// expected-note@-1 4{{template parameter is declared here}}
+// cxx98-note@-2 2{{template parameter is declared here}}
+// expected-note@-3 {{template is declared here}}
// [temp.arg.type]p1
A<0> *a1; // expected-error{{template argument for template type parameter must be a type}}