[clang] [libcxx] [clang] Preserve Qualifiers and type sugar in TemplateNames (PR #93433)
Kazu Hirata via cfe-commits
cfe-commits at lists.llvm.org
Wed May 29 11:26:21 PDT 2024
https://github.com/kazutakahirata updated https://github.com/llvm/llvm-project/pull/93433
>From 8322ce12520d1d4ab96b58195bd91f62a7b95c06 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Sat, 25 May 2024 13:57:39 -0300
Subject: [PATCH] [clang] Preserve Qualifiers and type sugar in TemplateNames
This patch improves the preservation of qualifiers
and loss of type sugar in TemplateNames.
This problem is analogous to https://reviews.llvm.org/D112374
and this patch takes a very similar approach to that patch,
except the impact here is much lesser.
When a TemplateName was written bare, without qualifications,
we wouldn't produce a QualifiedTemplate which could be used
to disambiguate it from a Canonical TemplateName. This had
effects in the TemplateName printer, which had workarounds
to deal with this, and wouldn't print the TemplateName
as-written in most situations.
There are also some related fixes to help preserve this type
sugar along the way into diagnostics, so that this patch can
be properly tested.
- Fix dropping the template keyword.
- Fix type deduction to preserve sugar in TST TemplateNames.
---
clang/docs/ReleaseNotes.rst | 2 +
clang/include/clang/AST/TemplateName.h | 19 +++---
clang/include/clang/Sema/Sema.h | 3 +
clang/lib/AST/ASTContext.cpp | 16 ++---
clang/lib/AST/DeclTemplate.cpp | 7 +-
clang/lib/AST/ODRHash.cpp | 9 ++-
clang/lib/AST/TemplateBase.cpp | 2 +-
clang/lib/AST/TemplateName.cpp | 64 +++++++++----------
clang/lib/AST/TextNodeDumper.cpp | 4 +-
clang/lib/AST/Type.cpp | 3 +-
clang/lib/AST/TypePrinter.cpp | 4 +-
clang/lib/Sema/SemaDecl.cpp | 15 ++---
clang/lib/Sema/SemaDeclCXX.cpp | 12 ++--
clang/lib/Sema/SemaExpr.cpp | 4 +-
clang/lib/Sema/SemaExprMember.cpp | 3 +-
clang/lib/Sema/SemaTemplate.cpp | 25 +++++---
clang/lib/Sema/SemaTemplateDeduction.cpp | 62 +++++++++++++-----
clang/lib/Sema/SemaType.cpp | 14 ++--
clang/lib/Sema/TreeTransform.h | 8 +--
clang/test/AST/ast-dump-ctad-alias.cpp | 6 +-
clang/test/AST/ast-dump-decl.cpp | 8 +--
clang/test/AST/ast-dump-expr.cpp | 2 +-
clang/test/AST/ast-dump-template-decls.cpp | 6 +-
clang/test/AST/ast-dump-template-name.cpp | 4 +-
clang/test/AST/ast-dump-using-template.cpp | 6 +-
clang/test/CXX/drs/cwg1xx.cpp | 4 +-
.../over.match.oper/p3-2a.cpp | 4 +-
.../temp.deduct/temp.deduct.type/p9-0x.cpp | 4 +-
clang/test/Index/print-type.cpp | 2 +-
clang/test/OpenMP/declare_mapper_messages.cpp | 2 +-
.../Parser/cxx-template-template-recovery.cpp | 4 +-
.../cxx1y-variable-templates_in_class.cpp | 10 +--
clang/test/SemaTemplate/cwg2398.cpp | 2 +-
.../instantiate-requires-expr.cpp | 4 +-
.../nested-implicit-deduction-guides.cpp | 2 +-
clang/unittests/AST/TemplateNameTest.cpp | 40 ++++++++++--
.../map/map.cons/deduct.verify.cpp | 24 +++----
.../multimap/multimap.cons/deduct.verify.cpp | 22 +++----
.../multiset/multiset.cons/deduct.verify.cpp | 10 +--
.../set/set.cons/deduct.verify.cpp | 10 +--
.../priqueue.cons/deduct.verify.cpp | 10 +--
.../queue/queue.cons/deduct.verify.cpp | 6 +-
.../stack/stack.cons/deduct.verify.cpp | 6 +-
.../array/array.cons/deduct.verify.cpp | 2 +-
.../deque/deque.cons/deduct.verify.cpp | 2 +-
.../forwardlist.cons/deduct.verify.cpp | 2 +-
.../list/list.cons/deduct.verify.cpp | 2 +-
.../vector/vector.cons/deduct.verify.cpp | 2 +-
.../unord.map.cnstr/deduct.verify.cpp | 16 ++---
.../unord.multimap.cnstr/deduct.verify.cpp | 16 ++---
.../unord.multiset.cnstr/deduct.verify.cpp | 16 ++---
.../unord.set.cnstr/deduct.verify.cpp | 16 ++---
.../range.adaptors/range.join/ctad.verify.cpp | 2 +-
.../re.regex.construct/deduct.verify.cpp | 4 +-
.../optional.object.ctor/deduct.verify.cpp | 2 +-
55 files changed, 316 insertions(+), 240 deletions(-)
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index e1c6d55eeeacd..44035f48cb3f9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -819,6 +819,8 @@ Bug Fixes to AST Handling
- Clang now properly preserves ``FoundDecls`` within a ``ConceptReference``. (#GH82628)
- The presence of the ``typename`` keyword is now stored in ``TemplateTemplateParmDecl``.
- Fixed malformed AST generated for anonymous union access in templates. (#GH90842)
+- Improved preservation of qualifiers and sugar in `TemplateNames`, including
+ template keyword.
Miscellaneous Bug Fixes
^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h
index b7732e54ba107..876be463c71d0 100644
--- a/clang/include/clang/AST/TemplateName.h
+++ b/clang/include/clang/AST/TemplateName.h
@@ -332,7 +332,7 @@ class TemplateName {
/// unexpanded parameter pack (for C++0x variadic templates).
bool containsUnexpandedParameterPack() const;
- enum class Qualified { None, AsWritten, Fully };
+ enum class Qualified { None, AsWritten };
/// Print the template name.
///
/// \param OS the output stream to which the template name will be
@@ -417,17 +417,18 @@ inline TemplateName TemplateName::getUnderlying() const {
return *this;
}
-/// Represents a template name that was expressed as a
-/// qualified name.
+/// Represents a template name as written in source code.
///
-/// This kind of template name refers to a template name that was
+/// This kind of template name may refer to a template name that was
/// preceded by a nested name specifier, e.g., \c std::vector. Here,
/// the nested name specifier is "std::" and the template name is the
-/// declaration for "vector". The QualifiedTemplateName class is only
-/// used to provide "sugar" for template names that were expressed
-/// with a qualified name, and has no semantic meaning. In this
-/// manner, it is to TemplateName what ElaboratedType is to Type,
-/// providing extra syntactic sugar for downstream clients.
+/// declaration for "vector". It may also have been written with the
+/// 'template' keyword. The QualifiedTemplateName class is only
+/// used to provide "sugar" for template names, so that they can
+/// be differentiated from canonical template names. and has no
+/// semantic meaning. In this manner, it is to TemplateName what
+/// ElaboratedType is to Type, providing extra syntactic sugar
+/// for downstream clients.
class QualifiedTemplateName : public llvm::FoldingSetNode {
friend class ASTContext;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index ec083f7cc09b7..e6296868000c5 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -8988,6 +8988,9 @@ class Sema final : public SemaBase {
const TemplateArgumentListInfo *TemplateArgs);
void diagnoseMissingTemplateArguments(TemplateName Name, SourceLocation Loc);
+ void diagnoseMissingTemplateArguments(const CXXScopeSpec &SS,
+ bool TemplateKeyword, TemplateDecl *TD,
+ SourceLocation Loc);
ExprResult BuildTemplateIdExpr(const CXXScopeSpec &SS,
SourceLocation TemplateKWLoc, LookupResult &R,
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index a2398fef623ea..06780ceba4074 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -5006,9 +5006,6 @@ ASTContext::getTemplateSpecializationType(TemplateName Template,
QualType Underlying) const {
assert(!Template.getAsDependentTemplateName() &&
"No dependent template names here!");
- // Look through qualified template names.
- if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
- Template = QTN->getUnderlyingTemplate();
const auto *TD = Template.getAsTemplateDecl();
bool IsTypeAlias = TD && TD->isTypeAlias();
@@ -5044,10 +5041,6 @@ QualType ASTContext::getCanonicalTemplateSpecializationType(
assert(!Template.getAsDependentTemplateName() &&
"No dependent template names here!");
- // Look through qualified template names.
- if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
- Template = TemplateName(QTN->getUnderlyingTemplate());
-
// Build the canonical template specialization type.
TemplateName CanonTemplate = getCanonicalTemplateName(Template);
bool AnyNonCanonArgs = false;
@@ -5262,10 +5255,12 @@ TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) {
Arg = TemplateArgument(E);
} else {
auto *TTP = cast<TemplateTemplateParmDecl>(Param);
+ TemplateName Name = getQualifiedTemplateName(
+ nullptr, /*TemplateKeyword=*/false, TemplateName(TTP));
if (TTP->isParameterPack())
- Arg = TemplateArgument(TemplateName(TTP), std::optional<unsigned>());
+ Arg = TemplateArgument(Name, std::optional<unsigned>());
else
- Arg = TemplateArgument(TemplateName(TTP));
+ Arg = TemplateArgument(Name);
}
if (Param->isTemplateParameterPack())
@@ -9304,7 +9299,8 @@ TemplateName ASTContext::getAssumedTemplateName(DeclarationName Name) const {
TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
bool TemplateKeyword,
TemplateName Template) const {
- assert(NNS && "Missing nested-name-specifier in qualified template name");
+ assert(Template.getKind() == TemplateName::Template ||
+ Template.getKind() == TemplateName::UsingTemplate);
// FIXME: Canonicalization?
llvm::FoldingSetNodeID ID;
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 95ffd4784641f..d952f7e181848 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -627,9 +627,10 @@ ClassTemplateDecl::getInjectedClassNameSpecialization() {
TemplateParameterList *Params = getTemplateParameters();
SmallVector<TemplateArgument, 16> TemplateArgs;
Context.getInjectedTemplateArgs(Params, TemplateArgs);
- CommonPtr->InjectedClassNameType
- = Context.getTemplateSpecializationType(TemplateName(this),
- TemplateArgs);
+ TemplateName Name = Context.getQualifiedTemplateName(
+ /*NNS=*/nullptr, /*TemplateKeyword=*/false, TemplateName(this));
+ CommonPtr->InjectedClassNameType =
+ Context.getTemplateSpecializationType(Name, TemplateArgs);
return CommonPtr->InjectedClassNameType;
}
diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 246e56231539a..1249531eab09f 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -146,10 +146,17 @@ void ODRHash::AddTemplateName(TemplateName Name) {
case TemplateName::Template:
AddDecl(Name.getAsTemplateDecl());
break;
+ case TemplateName::QualifiedTemplate: {
+ QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName();
+ if (NestedNameSpecifier *NNS = QTN->getQualifier())
+ AddNestedNameSpecifier(NNS);
+ AddBoolean(QTN->hasTemplateKeyword());
+ AddTemplateName(QTN->getUnderlyingTemplate());
+ break;
+ }
// TODO: Support these cases.
case TemplateName::OverloadedTemplate:
case TemplateName::AssumedTemplate:
- case TemplateName::QualifiedTemplate:
case TemplateName::DependentTemplate:
case TemplateName::SubstTemplateTemplateParm:
case TemplateName::SubstTemplateTemplateParmPack:
diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp
index b50daf5fbed6a..6d3c843cfd29e 100644
--- a/clang/lib/AST/TemplateBase.cpp
+++ b/clang/lib/AST/TemplateBase.cpp
@@ -552,7 +552,7 @@ void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
const auto *TTP = cast<TemplateTemplateParmDecl>(TD);
Out << "template-parameter-" << TTP->getDepth() << "-" << TTP->getIndex();
} else {
- TN.print(Out, Policy, TemplateName::Qualified::Fully);
+ TN.print(Out, Policy);
}
break;
}
diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp
index 2f0e4181e9408..3aae998eceeb0 100644
--- a/clang/lib/AST/TemplateName.cpp
+++ b/clang/lib/AST/TemplateName.cpp
@@ -235,8 +235,8 @@ TemplateNameDependence TemplateName::getDependence() const {
auto D = TemplateNameDependence::None;
switch (getKind()) {
case TemplateName::NameKind::QualifiedTemplate:
- D |= toTemplateNameDependence(
- getAsQualifiedTemplateName()->getQualifier()->getDependence());
+ if (NestedNameSpecifier *NNS = getAsQualifiedTemplateName()->getQualifier())
+ D |= toTemplateNameDependence(NNS->getDependence());
break;
case TemplateName::NameKind::DependentTemplate:
D |= toTemplateNameDependence(
@@ -292,9 +292,8 @@ void TemplateName::Profile(llvm::FoldingSetNodeID &ID) {
void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
Qualified Qual) const {
- auto Kind = getKind();
- TemplateDecl *Template = nullptr;
- if (Kind == TemplateName::Template || Kind == TemplateName::UsingTemplate) {
+ if (NameKind Kind = getKind();
+ Kind == TemplateName::Template || Kind == TemplateName::UsingTemplate) {
// After `namespace ns { using std::vector }`, what is the fully-qualified
// name of the UsingTemplateName `vector` within ns?
//
@@ -304,46 +303,43 @@ void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
// Similar to the UsingType behavior, using declarations are used to import
// names more often than to export them, thus using the original name is
// most useful in this case.
- Template = getAsTemplateDecl();
- }
-
- if (Template)
- if (Policy.CleanUglifiedParameters &&
- isa<TemplateTemplateParmDecl>(Template) && Template->getIdentifier())
- OS << Template->getIdentifier()->deuglifiedName();
- else if (Qual == Qualified::Fully &&
- getDependence() !=
- TemplateNameDependenceScope::DependentInstantiation)
- Template->printQualifiedName(OS, Policy);
- else
+ TemplateDecl *Template = getAsTemplateDecl();
+ if (Qual == Qualified::None)
OS << *Template;
- else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
- if (Qual == Qualified::Fully &&
- getDependence() !=
- TemplateNameDependenceScope::DependentInstantiation) {
- QTN->getUnderlyingTemplate().getAsTemplateDecl()->printQualifiedName(
- OS, Policy);
- return;
- }
- if (Qual == Qualified::AsWritten)
- QTN->getQualifier()->print(OS, Policy);
+ else
+ Template->printQualifiedName(OS, Policy);
+ } else if (QualifiedTemplateName *QTN = getAsQualifiedTemplateName()) {
+ if (NestedNameSpecifier *NNS = QTN->getQualifier();
+ Qual != Qualified::None && NNS)
+ NNS->print(OS, Policy);
if (QTN->hasTemplateKeyword())
OS << "template ";
- OS << *QTN->getUnderlyingTemplate().getAsTemplateDecl();
+
+ TemplateName Underlying = QTN->getUnderlyingTemplate();
+ assert(Underlying.getKind() == TemplateName::Template ||
+ Underlying.getKind() == TemplateName::UsingTemplate);
+
+ TemplateDecl *UTD = Underlying.getAsTemplateDecl();
+ if (IdentifierInfo *II = UTD->getIdentifier();
+ Policy.CleanUglifiedParameters && II &&
+ isa<TemplateTemplateParmDecl>(UTD))
+ OS << II->deuglifiedName();
+ else
+ OS << *UTD;
} else if (DependentTemplateName *DTN = getAsDependentTemplateName()) {
- if (Qual == Qualified::AsWritten && DTN->getQualifier())
- DTN->getQualifier()->print(OS, Policy);
+ if (NestedNameSpecifier *NNS = DTN->getQualifier())
+ NNS->print(OS, Policy);
OS << "template ";
if (DTN->isIdentifier())
OS << DTN->getIdentifier()->getName();
else
OS << "operator " << getOperatorSpelling(DTN->getOperator());
- } else if (SubstTemplateTemplateParmStorage *subst
- = getAsSubstTemplateTemplateParm()) {
+ } else if (SubstTemplateTemplateParmStorage *subst =
+ getAsSubstTemplateTemplateParm()) {
subst->getReplacement().print(OS, Policy, Qual);
- } else if (SubstTemplateTemplateParmPackStorage *SubstPack
- = getAsSubstTemplateTemplateParmPack())
+ } else if (SubstTemplateTemplateParmPackStorage *SubstPack =
+ getAsSubstTemplateTemplateParmPack())
OS << *SubstPack->getParameterPack();
else if (AssumedTemplateStorage *Assumed = getAsAssumedTemplateName()) {
Assumed->getDeclName().print(OS, Policy);
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 627f8d3477d4e..a0eedc71ea220 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1989,7 +1989,7 @@ void TextNodeDumper::VisitAutoType(const AutoType *T) {
void TextNodeDumper::VisitDeducedTemplateSpecializationType(
const DeducedTemplateSpecializationType *T) {
- if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
+ if (T->getTemplateName().getAsUsingShadowDecl())
OS << " using";
}
@@ -1997,7 +1997,7 @@ void TextNodeDumper::VisitTemplateSpecializationType(
const TemplateSpecializationType *T) {
if (T->isTypeAlias())
OS << " alias";
- if (T->getTemplateName().getKind() == TemplateName::UsingTemplate)
+ if (T->getTemplateName().getAsUsingShadowDecl())
OS << " using";
OS << " ";
T->getTemplateName().dump(OS);
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 04f105c128872..2097b29b7e0b6 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -4251,7 +4251,8 @@ TemplateSpecializationType::TemplateSpecializationType(
assert((T.getKind() == TemplateName::Template ||
T.getKind() == TemplateName::SubstTemplateTemplateParm ||
T.getKind() == TemplateName::SubstTemplateTemplateParmPack ||
- T.getKind() == TemplateName::UsingTemplate) &&
+ T.getKind() == TemplateName::UsingTemplate ||
+ T.getKind() == TemplateName::QualifiedTemplate) &&
"Unexpected template name for TemplateSpecializationType");
auto *TemplateArgs = reinterpret_cast<TemplateArgument *>(this + 1);
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index 5ed56b367a46a..58d01705d607b 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1586,14 +1586,14 @@ void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
IncludeStrongLifetimeRAII Strong(Policy);
TemplateDecl *TD = T->getTemplateName().getAsTemplateDecl();
- // FIXME: Null TD never excercised in test suite.
+ // FIXME: Null TD never exercised in test suite.
if (FullyQualify && TD) {
if (!Policy.SuppressScope)
AppendScope(TD->getDeclContext(), OS, TD->getDeclName());
OS << TD->getName();
} else {
- T->getTemplateName().print(OS, Policy);
+ T->getTemplateName().print(OS, Policy, TemplateName::Qualified::None);
}
DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 2a87b26f17a2b..e29ddd81a3f88 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -538,8 +538,9 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
} else if (AllowDeducedTemplate) {
if (auto *TD = getAsTypeTemplateDecl(IIDecl)) {
assert(!FoundUsingShadow || FoundUsingShadow->getTargetDecl() == TD);
- TemplateName Template =
- FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD);
+ TemplateName Template = Context.getQualifiedTemplateName(
+ SS ? SS->getScopeRep() : nullptr, /*TemplateKeyword=*/false,
+ FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD));
T = Context.getDeducedTemplateSpecializationType(Template, QualType(),
false);
// Don't wrap in a further UsingType.
@@ -1137,12 +1138,10 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
dyn_cast<UsingShadowDecl>(*Result.begin());
assert(!FoundUsingShadow ||
TD == cast<TemplateDecl>(FoundUsingShadow->getTargetDecl()));
- Template =
- FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD);
- if (SS.isNotEmpty())
- Template = Context.getQualifiedTemplateName(SS.getScopeRep(),
- /*TemplateKeyword=*/false,
- Template);
+ Template = Context.getQualifiedTemplateName(
+ SS.getScopeRep(),
+ /*TemplateKeyword=*/false,
+ FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD));
} else {
// All results were non-template functions. This is a function template
// name.
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 8ab429e2a136e..631fd4e354927 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -11547,12 +11547,12 @@ bool Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
TemplateName SpecifiedName = RetTST.getTypePtr()->getTemplateName();
bool TemplateMatches =
Context.hasSameTemplateName(SpecifiedName, GuidedTemplate);
- auto TKind = SpecifiedName.getKind();
- // A Using TemplateName can't actually be valid (either it's qualified, or
- // we're in the wrong scope). But we have diagnosed these problems
- // already.
- bool SimplyWritten = TKind == TemplateName::Template ||
- TKind == TemplateName::UsingTemplate;
+
+ const QualifiedTemplateName *Qualifiers =
+ SpecifiedName.getAsQualifiedTemplateName();
+ assert(Qualifiers && "expected QualifiedTemplate");
+ bool SimplyWritten = !Qualifiers->hasTemplateKeyword() &&
+ Qualifiers->getQualifier() == nullptr;
if (SimplyWritten && TemplateMatches)
AcceptableReturnType = true;
else {
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index ded4f59833ac0..fb4154757775b 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -3284,10 +3284,10 @@ ExprResult Sema::BuildDeclarationNameExpr(
return CreateRecoveryExpr(NameInfo.getBeginLoc(), NameInfo.getEndLoc(), {});
}
- if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) {
+ if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
// Specifically diagnose references to class templates that are missing
// a template argument list.
- diagnoseMissingTemplateArguments(TemplateName(Template), Loc);
+ diagnoseMissingTemplateArguments(SS, /*TemplateKeyword=*/false, TD, Loc);
return ExprError();
}
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 9aa60204bf29d..3ae1af26d0096 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -1194,7 +1194,8 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
if (VarTemplateDecl *VarTempl = dyn_cast<VarTemplateDecl>(MemberDecl)) {
if (!TemplateArgs) {
- diagnoseMissingTemplateArguments(TemplateName(VarTempl), MemberLoc);
+ diagnoseMissingTemplateArguments(
+ SS, /*TemplateKeyword=*/TemplateKWLoc.isValid(), VarTempl, MemberLoc);
return ExprError();
}
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 39e9dbed0c3e0..3e3ed77de710e 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -292,7 +292,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
Template =
FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD);
assert(!FoundUsingShadow || FoundUsingShadow->getTargetDecl() == TD);
- if (SS.isSet() && !SS.isInvalid()) {
+ if (!SS.isInvalid()) {
NestedNameSpecifier *Qualifier = SS.getScopeRep();
Template = Context.getQualifiedTemplateName(Qualifier, hasTemplateKeyword,
Template);
@@ -342,8 +342,11 @@ bool Sema::isDeductionGuideName(Scope *S, const IdentifierInfo &Name,
if (!TD || !getAsTypeTemplateDecl(TD))
return false;
- if (Template)
- *Template = TemplateTy::make(TemplateName(TD));
+ if (Template) {
+ TemplateName Name = Context.getQualifiedTemplateName(
+ SS.getScopeRep(), /*TemplateKeyword=*/false, TemplateName(TD));
+ *Template = TemplateTy::make(Name);
+ }
return true;
}
@@ -983,10 +986,6 @@ ParsedTemplateArgument Sema::ActOnTemplateTypeArgument(TypeResult ParsedType) {
if (auto DTST = TL.getAs<DeducedTemplateSpecializationTypeLoc>()) {
TemplateName Name = DTST.getTypePtr()->getTemplateName();
- if (SS.isSet())
- Name = Context.getQualifiedTemplateName(SS.getScopeRep(),
- /*HasTemplateKeyword=*/false,
- Name);
ParsedTemplateArgument Result(SS, TemplateTy::make(Name),
DTST.getTemplateNameLoc());
if (EllipsisLoc.isValid())
@@ -5621,6 +5620,15 @@ void Sema::diagnoseMissingTemplateArguments(TemplateName Name,
}
}
+void Sema::diagnoseMissingTemplateArguments(const CXXScopeSpec &SS,
+ bool TemplateKeyword,
+ TemplateDecl *TD,
+ SourceLocation Loc) {
+ TemplateName Name = Context.getQualifiedTemplateName(
+ SS.getScopeRep(), TemplateKeyword, TemplateName(TD));
+ diagnoseMissingTemplateArguments(Name, Loc);
+}
+
ExprResult
Sema::CheckConceptTemplateId(const CXXScopeSpec &SS,
SourceLocation TemplateKWLoc,
@@ -5691,7 +5699,8 @@ ExprResult Sema::BuildTemplateIdExpr(const CXXScopeSpec &SS,
// Non-function templates require a template argument list.
if (auto *TD = R.getAsSingle<TemplateDecl>()) {
if (!TemplateArgs && !isa<FunctionTemplateDecl>(TD)) {
- diagnoseMissingTemplateArguments(TemplateName(TD), R.getNameLoc());
+ diagnoseMissingTemplateArguments(
+ SS, /*TemplateKeyword=*/TemplateKWLoc.isValid(), TD, R.getNameLoc());
return ExprError();
}
}
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index f9ec34163e656..440b8bc60eaab 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -589,7 +589,6 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
// arguments as defaults.
if (auto *TempArg = dyn_cast_or_null<TemplateTemplateParmDecl>(
Arg.getAsTemplateDecl())) {
- assert(Arg.getKind() == TemplateName::Template);
assert(!TempArg->isExpandedParameterPack());
TemplateParameterList *As = TempArg->getTemplateParameters();
@@ -658,6 +657,18 @@ DeduceTemplateArguments(Sema &S, TemplateParameterList *TemplateParams,
/// \returns the result of template argument deduction so far. Note that a
/// "success" result means that template argument deduction has not yet failed,
/// but it may still fail, later, for other reasons.
+
+static const TemplateSpecializationType *getLastTemplateSpecType(QualType QT) {
+ for (const Type *T = QT.getTypePtr(); /**/; /**/) {
+ const TemplateSpecializationType *TST =
+ T->getAs<TemplateSpecializationType>();
+ assert(TST && "Expected a TemplateSpecializationType");
+ if (!TST->isSugared())
+ return TST;
+ T = TST->desugar().getTypePtr();
+ }
+}
+
static TemplateDeductionResult
DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
const QualType P, QualType A,
@@ -666,26 +677,35 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
QualType UP = P;
if (const auto *IP = P->getAs<InjectedClassNameType>())
UP = IP->getInjectedSpecializationType();
- // FIXME: Try to preserve type sugar here, which is hard
- // because of the unresolved template arguments.
- const auto *TP = UP.getCanonicalType()->castAs<TemplateSpecializationType>();
+
+ assert(isa<TemplateSpecializationType>(UP.getCanonicalType()));
+ const TemplateSpecializationType *TP = ::getLastTemplateSpecType(UP);
TemplateName TNP = TP->getTemplateName();
// If the parameter is an alias template, there is nothing to deduce.
if (const auto *TD = TNP.getAsTemplateDecl(); TD && TD->isTypeAlias())
return TemplateDeductionResult::Success;
- ArrayRef<TemplateArgument> PResolved = TP->template_arguments();
+ // FIXME: To preserve sugar, the TST needs to carry sugared resolved
+ // arguments.
+ ArrayRef<TemplateArgument> PResolved =
+ TP->getCanonicalTypeInternal()
+ ->castAs<TemplateSpecializationType>()
+ ->template_arguments();
QualType UA = A;
+ std::optional<NestedNameSpecifier *> NNS;
// Treat an injected-class-name as its underlying template-id.
- if (const auto *Injected = A->getAs<InjectedClassNameType>())
+ if (const auto *Elaborated = A->getAs<ElaboratedType>()) {
+ NNS = Elaborated->getQualifier();
+ } else if (const auto *Injected = A->getAs<InjectedClassNameType>()) {
UA = Injected->getInjectedSpecializationType();
+ NNS = nullptr;
+ }
// Check whether the template argument is a dependent template-id.
- // FIXME: Should not lose sugar here.
- if (const auto *SA =
- dyn_cast<TemplateSpecializationType>(UA.getCanonicalType())) {
+ if (isa<TemplateSpecializationType>(UA.getCanonicalType())) {
+ const TemplateSpecializationType *SA = ::getLastTemplateSpecType(UA);
TemplateName TNA = SA->getTemplateName();
// If the argument is an alias template, there is nothing to deduce.
@@ -698,11 +718,19 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
SA->template_arguments(), Deduced);
Result != TemplateDeductionResult::Success)
return Result;
+
+ // FIXME: To preserve sugar, the TST needs to carry sugared resolved
+ // arguments.
+ ArrayRef<TemplateArgument> AResolved =
+ SA->getCanonicalTypeInternal()
+ ->castAs<TemplateSpecializationType>()
+ ->template_arguments();
+
// Perform template argument deduction on each template
// argument. Ignore any missing/extra arguments, since they could be
// filled in by default arguments.
- return DeduceTemplateArguments(S, TemplateParams, PResolved,
- SA->template_arguments(), Info, Deduced,
+ return DeduceTemplateArguments(S, TemplateParams, PResolved, AResolved,
+ Info, Deduced,
/*NumberOfArgumentsMustMatch=*/false);
}
@@ -718,11 +746,15 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
return TemplateDeductionResult::NonDeducedMismatch;
}
+ TemplateName TNA = TemplateName(SA->getSpecializedTemplate());
+ if (NNS)
+ TNA = S.Context.getQualifiedTemplateName(
+ *NNS, false, TemplateName(SA->getSpecializedTemplate()));
+
// Perform template argument deduction for the template name.
- if (auto Result = DeduceTemplateArguments(
- S, TemplateParams, TP->getTemplateName(),
- TemplateName(SA->getSpecializedTemplate()), Info,
- SA->getTemplateArgs().asArray(), Deduced);
+ if (auto Result =
+ DeduceTemplateArguments(S, TemplateParams, TNP, TNA, Info,
+ SA->getTemplateArgs().asArray(), Deduced);
Result != TemplateDeductionResult::Success)
return Result;
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index ef0b6b701a52c..7cec82c701028 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -6005,12 +6005,16 @@ namespace {
DeclarationNameInfo DNI = DeclarationNameInfo(
TL.getTypePtr()->getTypeConstraintConcept()->getDeclName(),
TemplateId->TemplateNameLoc);
- auto TN = TemplateId->Template.get();
+
+ NamedDecl *FoundDecl;
+ if (auto TN = TemplateId->Template.get();
+ UsingShadowDecl *USD = TN.getAsUsingShadowDecl())
+ FoundDecl = cast<NamedDecl>(USD);
+ else
+ FoundDecl = cast_if_present<NamedDecl>(TN.getAsTemplateDecl());
+
auto *CR = ConceptReference::Create(
- Context, NNS, TemplateId->TemplateKWLoc, DNI,
- /*FoundDecl=*/TN.getKind() == TemplateName::NameKind::UsingTemplate
- ? cast<NamedDecl>(TN.getAsUsingShadowDecl())
- : cast_if_present<NamedDecl>(TN.getAsTemplateDecl()),
+ Context, NNS, TemplateId->TemplateKWLoc, DNI, FoundDecl,
/*NamedDecl=*/TL.getTypePtr()->getTypeConstraintConcept(),
ASTTemplateArgumentListInfo::Create(Context, TemplateArgsInfo));
TL.setConceptReference(CR);
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 765e6177d202d..efba99b85b0fb 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -4605,6 +4605,7 @@ TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
ObjectType, AllowInjectedClassName);
}
+ // FIXME: Try to preserve more of the TemplateName.
if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
TemplateDecl *TransTemplate
= cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
@@ -4612,11 +4613,8 @@ TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
if (!TransTemplate)
return TemplateName();
- if (!getDerived().AlwaysRebuild() &&
- TransTemplate == Template)
- return Name;
-
- return TemplateName(TransTemplate);
+ return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false,
+ TransTemplate);
}
if (SubstTemplateTemplateParmPackStorage *SubstPack
diff --git a/clang/test/AST/ast-dump-ctad-alias.cpp b/clang/test/AST/ast-dump-ctad-alias.cpp
index 9382558393e4c..08a3be5c6b754 100644
--- a/clang/test/AST/ast-dump-ctad-alias.cpp
+++ b/clang/test/AST/ast-dump-ctad-alias.cpp
@@ -29,17 +29,17 @@ Out2<double>::AInner t(1.0);
// CHECK: | `-FunctionTemplateDecl {{.*}} <deduction guide for AInner>
// CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} typename depth 0 index 0 Y
// CHECK-NEXT: | |-BinaryOperator {{.*}} '<dependent type>' '&&'
-// CHECK-NEXT: | | |-UnresolvedLookupExpr {{.*}} '<dependent type>' lvalue (no ADL) = 'Concept'
+// CHECK-NEXT: | | |-UnresolvedLookupExpr {{.*}} '<dependent type>' lvalue (no ADL) = 'Concept'
// CHECK-NEXT: | | | |-TemplateArgument type 'int'
// CHECK-NEXT: | | | | `-BuiltinType {{.*}} 'int'
// CHECK-NEXT: | | | `-TemplateArgument type 'type-parameter-1-0'
// CHECK-NEXT: | | | `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' dependent depth 1 index 0
// CHECK-NEXT: | | `-TypeTraitExpr {{.*}} 'bool' __is_deducible
-// CHECK-NEXT: | | |-DeducedTemplateSpecializationType {{.*}} 'AInner' dependent
+// CHECK-NEXT: | | |-DeducedTemplateSpecializationType {{.*}} 'Out2<double>::AInner' dependent
// CHECK-NEXT: | | `-ElaboratedType {{.*}} 'Inner<type-parameter-1-0>' sugar dependent
// CHECK-NEXT: | | `-TemplateSpecializationType {{.*}} 'Inner<type-parameter-1-0>' dependent Inner
// CHECK-NEXT: | | `-TemplateArgument type 'type-parameter-1-0'
-// CHECK-NEXT: | | `-SubstTemplateTypeParmType {{.*}} 'type-parameter-1-0'
+// CHECK-NEXT: | | `-SubstTemplateTypeParmType {{.*}} 'type-parameter-1-0'
// CHECK-NEXT: | | |-FunctionTemplate {{.*}} '<deduction guide for Inner>'
// CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'type-parameter-1-0' dependent depth 1 index 0
// CHECK-NEXT: | |-CXXDeductionGuideDecl {{.*}} <deduction guide for AInner> 'auto (type-parameter-0-0) -> Inner<type-parameter-0-0>'
diff --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp
index b861ba8be15b5..e84241cee922f 100644
--- a/clang/test/AST/ast-dump-decl.cpp
+++ b/clang/test/AST/ast-dump-decl.cpp
@@ -466,14 +466,14 @@ namespace testClassTemplateDecl {
// CHECK: ClassTemplateDecl 0x{{.+}} <{{.+}}:{{.*}}:3, col:68> col:68 TestTemplateTemplateDefaultType{{$}}
// CHECK-NEXT: |-TemplateTemplateParmDecl 0x{{.+}} <col:12, col:42> col:37 depth 0 index 0 TT{{$}}
// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:21> col:29 typename depth 1 index 0{{$}}
-// CHECK-NEXT: | `-TemplateArgument <col:42> template 'testClassTemplateDecl::TestClassTemplate'{{$}}
+// CHECK-NEXT: | `-TemplateArgument <col:42> template 'TestClassTemplate':'testClassTemplateDecl::TestClassTemplate' qualified{{$}}
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} <line:{{.+}}:3, line:{{.+}}:3> line:{{.+}}:30 TestClassTemplate{{$}}
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} <line:{{.*}}:61, col:68> col:68 struct TestTemplateTemplateDefaultType{{$}}
// CHECK: ClassTemplateDecl 0x{{.+}} prev 0x{{.+}} <{{.+}}:{{.*}}:3, col:82> col:48 TestTemplateTemplateDefaultType{{$}}
// CHECK-NEXT: |-TemplateTemplateParmDecl 0x{{.+}} <col:12, col:37> col:37 depth 0 index 0 TT{{$}}
// CHECK-NEXT: | |-TemplateTypeParmDecl 0x{{.+}} <col:21> col:29 typename depth 1 index 0{{$}}
-// CHECK-NEXT: | `-TemplateArgument <line:{{.*}}:42> template 'testClassTemplateDecl::TestClassTemplate'{{$}}
+// CHECK-NEXT: | `-TemplateArgument <line:{{.*}}:42> template 'TestClassTemplate':'testClassTemplateDecl::TestClassTemplate' qualified{{$}}
// CHECK-NEXT: | |-inherited from TemplateTemplateParm 0x{{.+}} 'TT'{{$}}
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} <line:{{.+}}:3, line:{{.+}}:3> line:{{.+}}:30 TestClassTemplate
// CHECK-NEXT: `-CXXRecordDecl 0x{{.+}} prev 0x{{.+}} <line:{{.*}}:41, col:82> col:48 struct TestTemplateTemplateDefaultType definition{{$}}
@@ -685,7 +685,7 @@ namespace TestTemplateTemplateParmDecl {
// CHECK: FunctionTemplateDecl
// CHECK-NEXT: TemplateTemplateParmDecl{{.*}} T
// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename
-// CHECK-NEXT: TemplateArgument{{.*}} template 'TestTemplateTemplateParmDecl::A'
+// CHECK-NEXT: TemplateArgument{{.*}} template 'A':'TestTemplateTemplateParmDecl::A' qualified{{$}}
// CHECK-NEXT: ClassTemplateDecl {{.*}} A
// CHECK-NEXT: TemplateTemplateParmDecl{{.*}} ... U
// CHECK-NEXT: TemplateTypeParmDecl{{.*}} typename
@@ -718,7 +718,7 @@ namespace TestTemplateArgument {
template<template<typename> class> class testTemplate { };
template class testTemplate<A>;
// CHECK: ClassTemplateSpecializationDecl{{.*}} class testTemplate
- // CHECK: TemplateArgument{{.*}} 'TestTemplateArgument::A'
+ // CHECK: TemplateArgument{{.*}} 'TestTemplateArgument::A'{{$}}
template<template<typename> class ...T> class C {
B<T...> testTemplateExpansion;
diff --git a/clang/test/AST/ast-dump-expr.cpp b/clang/test/AST/ast-dump-expr.cpp
index f9e9ee9d35dde..5da025c229ea3 100644
--- a/clang/test/AST/ast-dump-expr.cpp
+++ b/clang/test/AST/ast-dump-expr.cpp
@@ -233,7 +233,7 @@ void PostfixExpressions(S a, S *p, U<int> *r) {
r->template U<int>::~U();
// CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:26> 'void'
// CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:24> '<bound member function type>' ->~U 0x{{[^ ]*}}
- // CHECK-NEXT: NestedNameSpecifier TypeSpecWithTemplate 'U<int>'
+ // CHECK-NEXT: NestedNameSpecifier TypeSpecWithTemplate 'template U<int>':'U<int>'
// CHECK-NEXT: ImplicitCastExpr
// CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'U<int> *' lvalue ParmVar 0x{{[^ ]*}} 'r' 'U<int> *'
diff --git a/clang/test/AST/ast-dump-template-decls.cpp b/clang/test/AST/ast-dump-template-decls.cpp
index 37f6d8a0472d3..55bded4c77d4b 100644
--- a/clang/test/AST/ast-dump-template-decls.cpp
+++ b/clang/test/AST/ast-dump-template-decls.cpp
@@ -116,7 +116,7 @@ template <class T> struct C {
using type2 = typename C<int>::type1<void>;
// CHECK: TypeAliasDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:42> col:7 type2 'typename C<int>::type1<void>':'void (int)'
// CHECK-NEXT: ElaboratedType 0x{{[^ ]*}} 'typename C<int>::type1<void>' sugar
-// CHECK-NEXT: TemplateSpecializationType 0x{{[^ ]*}} 'type1<void>' sugar alias type1
+// CHECK-NEXT: TemplateSpecializationType 0x{{[^ ]*}} 'type1<void>' sugar alias C<int>::type1
// CHECK-NEXT: TemplateArgument type 'void'
// CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void'
// CHECK-NEXT: FunctionProtoType 0x{{[^ ]*}} 'void (int)' cdecl
@@ -149,7 +149,7 @@ template <typename... T> struct D {
template <typename... U> using B = int(int (*...p)(T, U));
};
using t2 = D<float, char>::B<int, short>;
-// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'B<int, short>' sugar alias B
+// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'B<int, short>' sugar alias D<float, char>::B{{$}}
// CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int (*)(char, short))' cdecl
// CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl
// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... T pack_index 1
@@ -169,7 +169,7 @@ template<template<class C1, class C2 = A<C1>> class D1, class D2> using D = D1<D
template<class E1, class E2> class E {};
using test1 = D<E, int>;
-// CHECK: TypeAliasDecl 0x{{[^ ]*}} <line:{{[1-9]+}}:1, col:23> col:7 test1 'D<subst_default_argument::E, int>':'subst_default_argument::E<int, subst_default_argument::A<int>>'
+// CHECK: TypeAliasDecl 0x{{[^ ]*}} <line:{{[1-9]+}}:1, col:23> col:7 test1 'D<E, int>':'subst_default_argument::E<int, subst_default_argument::A<int>>'
// CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'A<int>' sugar A
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 1 D2
diff --git a/clang/test/AST/ast-dump-template-name.cpp b/clang/test/AST/ast-dump-template-name.cpp
index 39100711b60a1..7972e9f9e9b06 100644
--- a/clang/test/AST/ast-dump-template-name.cpp
+++ b/clang/test/AST/ast-dump-template-name.cpp
@@ -13,7 +13,7 @@ namespace qualified {
// CHECK-NEXT: TypeAliasDecl
// CHECK-NEXT: `-ElaboratedType
// CHECK-NEXT: `-TemplateSpecializationType
-// CHECK-NEXT: |-TemplateArgument template 'qualified::foo::A' qualified{{$}}
+// CHECK-NEXT: |-TemplateArgument template 'foo::A':'qualified::foo::A' qualified{{$}}
// CHECK-NEXT: | |-NestedNameSpecifier Namespace 0x{{.+}} 'foo'{{$}}
// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A{{$}}
@@ -27,7 +27,7 @@ namespace dependent {
// CHECK-NEXT: TypeAliasDecl
// CHECK-NEXT: `-ElaboratedType
// CHECK-NEXT: `-TemplateSpecializationType
-// CHECK-NEXT: |-TemplateArgument template 'template X' dependent{{$}}
+// CHECK-NEXT: |-TemplateArgument template 'T::template X':'type-parameter-0-0::template X' dependent{{$}}
// CHECK-NEXT: | `-NestedNameSpecifier TypeSpec 'T'{{$}}
namespace subst {
diff --git a/clang/test/AST/ast-dump-using-template.cpp b/clang/test/AST/ast-dump-using-template.cpp
index 69b199fd0606c..7731c2ad0231b 100644
--- a/clang/test/AST/ast-dump-using-template.cpp
+++ b/clang/test/AST/ast-dump-using-template.cpp
@@ -26,9 +26,9 @@ using A = S<T>;
template <template <typename> class T> class X {};
using B = X<S>;
// CHECK: TypeAliasDecl
-// CHECK-NEXT: `-ElaboratedType {{.*}} 'X<ns::S>' sugar
-// CHECK-NEXT: `-TemplateSpecializationType {{.*}} 'X<ns::S>' sugar X
-// CHECK-NEXT: |-TemplateArgument template 'ns::S'
+// CHECK-NEXT: `-ElaboratedType {{.*}} 'X<S>' sugar
+// CHECK-NEXT: `-TemplateSpecializationType {{.*}} 'X<S>' sugar X
+// CHECK-NEXT: |-TemplateArgument template 'S'
// CHECK-NEXT: | |-UsingShadowDecl {{.*}} implicit ClassTemplate {{.*}} 'S'
// CHECK-NEXT: | `-target: ClassTemplateDecl {{.*}} S
// CHECK-NEXT: `-RecordType {{.*}} 'X<ns::S>'
diff --git a/clang/test/CXX/drs/cwg1xx.cpp b/clang/test/CXX/drs/cwg1xx.cpp
index a8f9b705a9866..6bc63760f8333 100644
--- a/clang/test/CXX/drs/cwg1xx.cpp
+++ b/clang/test/CXX/drs/cwg1xx.cpp
@@ -518,7 +518,7 @@ namespace cwg136 { // cwg136: 3.4
void q() {
j(A(), A()); // ok, has default argument
}
- extern "C" void k(int, int, int, int); // #cwg136-k
+ extern "C" void k(int, int, int, int); // #cwg136-k
namespace NSA {
struct A {
friend void cwg136::k(int, int, int, int = 0);
@@ -1048,7 +1048,7 @@ namespace cwg176 { // cwg176: 3.1
cwg176::X *p4; // #cwg176-p4
// cxx98-14-error@#cwg176-p4 {{use of class template 'cwg176::X' requires template arguments}}
// cxx98-14-note@#cwg176-X {{template is declared here}}
- // since-cxx17-error@#cwg176-p4 {{use of class template 'X' requires template arguments; argument deduction not allowed in non-static class member}}
+ // since-cxx17-error@#cwg176-p4 {{use of class template 'cwg176::X' requires template arguments; argument deduction not allowed in non-static class member}}
// since-cxx17-note@#cwg176-X {{template is declared here}}
};
}
diff --git a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
index 54dabb4be2c05..a574d31a0925a 100644
--- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
+++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.oper/p3-2a.cpp
@@ -315,7 +315,7 @@ int a1 = 0 == A<1>(); // Should not find 2 as the requires clause does not match
namespace static_operators {
// Verify no crash.
-struct X {
+struct X {
bool operator ==(X const&); // expected-note {{ambiguity is between a regular call}}
// expected-note at -1 {{mark 'operator==' as const or add a matching 'operator!=' to resolve the ambiguity}}
static bool operator !=(X const&, X const&); // expected-error {{overloaded 'operator!=' cannot be a static member function}}
@@ -474,7 +474,7 @@ namespace ns {
template <class T> struct A {};
template <class T> struct B : A<T> {};
-template <class T> bool operator==(B<T>, A<T>); // expected-note {{candidate template ignored: could not match 'B' against 'A'}}
+template <class T> bool operator==(B<T>, A<T>); // expected-note {{candidate template ignored: could not match 'B' against 'ns::A'}}
template <class T> bool operator!=(B<T>, A<T>);
}
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
index 8f135b72546ff..51df1e0b14541 100644
--- a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.type/p9-0x.cpp
@@ -3,7 +3,7 @@
template<typename ...Types> struct tuple;
template<unsigned> struct unsigned_c;
-template<typename T, typename U>
+template<typename T, typename U>
struct is_same {
static const bool value = false;
};
@@ -93,7 +93,7 @@ namespace DeduceNonTypeTemplateArgsInArray {
}
namespace DeduceWithDefaultArgs {
- template<template<typename...> class Container> void f(Container<int>); // expected-note {{deduced type 'X<[...], (default) int>' of 1st parameter does not match adjusted type 'X<[...], double>' of argument [with Container = DeduceWithDefaultArgs::X]}}
+ template<template<typename...> class Container> void f(Container<int>); // expected-note {{deduced type 'X<[...], (default) int>' of 1st parameter does not match adjusted type 'X<[...], double>' of argument [with Container = X]}}
template<typename, typename = int> struct X {};
void g() {
// OK, use default argument for the second template parameter.
diff --git a/clang/test/Index/print-type.cpp b/clang/test/Index/print-type.cpp
index db8559521e29d..8c3d4c254964a 100644
--- a/clang/test/Index/print-type.cpp
+++ b/clang/test/Index/print-type.cpp
@@ -132,7 +132,7 @@ inline namespace InlineNS {}
// CHECK: TypedefDecl=OtherType:26:18 (Definition) [type=outer::inner::Bar::OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
// CHECK: TypedefDecl=ArrayType:27:15 (Definition) [type=outer::inner::Bar::ArrayType] [typekind=Typedef] [canonicaltype=int[5]] [canonicaltypekind=ConstantArray] [isPOD=1]
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
-// CHECK: FieldDecl=baz:28:20 (Definition) [type=Baz<int, 1, outer::Foo>] [typekind=Elaborated] [templateargs/3= [type=int] [typekind=Int]] [canonicaltype=outer::Baz<int, 1, outer::Foo>] [canonicaltypekind=Record] [canonicaltemplateargs/3= [type=int] [typekind=Int]] [isPOD=1]
+// CHECK: FieldDecl=baz:28:20 (Definition) [type=Baz<int, 1, Foo>] [typekind=Elaborated] [templateargs/3= [type=int] [typekind=Int]] [canonicaltype=outer::Baz<int, 1, outer::Foo>] [canonicaltypekind=Record] [canonicaltemplateargs/3= [type=int] [typekind=Int]] [isPOD=1]
// CHECK: TemplateRef=Baz:9:8 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
// CHECK: TemplateRef=Foo:4:8 [type=] [typekind=Invalid] [isPOD=0]
diff --git a/clang/test/OpenMP/declare_mapper_messages.cpp b/clang/test/OpenMP/declare_mapper_messages.cpp
index 95861612a076b..f2101786f6ce0 100644
--- a/clang/test/OpenMP/declare_mapper_messages.cpp
+++ b/clang/test/OpenMP/declare_mapper_messages.cpp
@@ -46,7 +46,7 @@ class stack { // expec
};
#pragma omp declare mapper(default : N1::stack s) map(s.len) // precxx17-error {{use of class template 'N1::stack' requires template arguments}} \
- cxx17-error {{use of class template 'stack' requires template arguments; argument deduction not allowed in function prototype}}
+ cxx17-error {{use of class template 'N1::stack' requires template arguments; argument deduction not allowed in function prototype}}
#pragma omp declare mapper(id1: N1::stack<int> s) map(s.data)
#pragma omp declare mapper(default : S<int> s) map(s.len) // expected-error {{no template named 'S'}}
diff --git a/clang/test/Parser/cxx-template-template-recovery.cpp b/clang/test/Parser/cxx-template-template-recovery.cpp
index 1230c86d924ff..5700b160cd364 100644
--- a/clang/test/Parser/cxx-template-template-recovery.cpp
+++ b/clang/test/Parser/cxx-template-template-recovery.cpp
@@ -29,9 +29,9 @@ static_assert(test<a::b::C2>); // expected-error {{too few template arguments fo
static_assert(test<C3>); // expected-error {{too few template arguments for concept 'C3'}} \
// expected-note@#C3 {{here}}
-static_assert(test<a::V1>); // expected-error {{use of variable template 'V1' requires template arguments}} \
+static_assert(test<a::V1>); // expected-error {{use of variable template 'a::V1' requires template arguments}} \
// expected-note@#V1 {{here}}
-static_assert(test<a::b::V2>); // expected-error {{use of variable template 'V2' requires template arguments}} \
+static_assert(test<a::b::V2>); // expected-error {{use of variable template 'a::b::V2' requires template arguments}} \
// expected-note@#V2 {{here}}
static_assert(test<V3>); // expected-error {{use of variable template 'V3' requires template arguments}} \
// expected-note@#V3 {{here}}
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index af121a8b75d51..f42c812a860d0 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -352,7 +352,7 @@ namespace ns2 {
};
template<class T> template<class U, T N, U M> T&& A<T>::Var = T(N + M);
int *AV = &A<int>().Var<char, 5, 'A'>;
-
+
} //end ns2
} // end ns member_access_is_ok
@@ -372,7 +372,7 @@ struct Something
}
};
-int main() {
+int main() {
Something<Value>{}.foo();
return 0;
}
@@ -384,16 +384,16 @@ namespace dependent_static_var_template {
struct A {
template<int = 0> static int n; // expected-note 2{{here}}
};
- int &r = A::template n; // expected-error {{use of variable template 'n' requires template arguments}}
+ int &r = A::template n; // expected-error {{use of variable template 'A::template n' requires template arguments}}
template<typename T>
- int &f() { return T::template n; } // expected-error {{use of variable template 'n' requires template arguments}}
+ int &f() { return T::template n; } // expected-error {{use of variable template 'A::template n' requires template arguments}}
int &s = f<A>(); // expected-note {{instantiation of}}
namespace B {
template<int = 0> static int n; // expected-note {{here}}
}
- int &t = B::template n; // expected-error {{use of variable template 'n' requires template arguments}}
+ int &t = B::template n; // expected-error {{use of variable template 'B::template n' requires template arguments}}
struct C {
template <class T> static T G;
diff --git a/clang/test/SemaTemplate/cwg2398.cpp b/clang/test/SemaTemplate/cwg2398.cpp
index e3b5e575374d3..45e74cce3a98c 100644
--- a/clang/test/SemaTemplate/cwg2398.cpp
+++ b/clang/test/SemaTemplate/cwg2398.cpp
@@ -4,7 +4,7 @@
namespace issue1 {
template<class T, class U = T> class B {};
template<template<class> class P, class T> void f(P<T>);
- // new-note at -1 {{deduced type 'B<[...], (default) int>' of 1st parameter does not match adjusted type 'B<[...], float>' of argument [with P = issue1::B, T = int]}}
+ // new-note at -1 {{deduced type 'B<[...], (default) int>' of 1st parameter does not match adjusted type 'B<[...], float>' of argument [with P = B, T = int]}}
// old-note at -2 2{{template template argument has different template parameters}}
void g() {
diff --git a/clang/test/SemaTemplate/instantiate-requires-expr.cpp b/clang/test/SemaTemplate/instantiate-requires-expr.cpp
index ba82fc1313fc9..516708bf4c875 100644
--- a/clang/test/SemaTemplate/instantiate-requires-expr.cpp
+++ b/clang/test/SemaTemplate/instantiate-requires-expr.cpp
@@ -72,8 +72,8 @@ namespace type_requirement {
template<typename T> requires
false_v<requires { typename T::template temp<T>; }>
- // expected-note at -1 {{because 'false_v<requires { typename contains_template<int>::temp<contains_template<int> >; }>' evaluated to false}}
- // expected-note at -2 {{because 'false_v<requires { typename contains_template<short>::temp<contains_template<short> >; }>' evaluated to false}}
+ // expected-note at -1 {{because 'false_v<requires { typename contains_template<int>::template temp<contains_template<int> >; }>' evaluated to false}}
+ // expected-note at -2 {{because 'false_v<requires { typename contains_template<short>::template temp<contains_template<short> >; }>' evaluated to false}}
struct r2 {};
using r2i1 = r2<contains_template<int>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<int>]}}
diff --git a/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp b/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp
index f289dc0452868..a4ae046ac5274 100644
--- a/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp
+++ b/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp
@@ -79,7 +79,7 @@ nested_init_list<int>::B nil {1, 2};
using NIL = decltype(nil);
using NIL = nested_init_list<int>::B<int>;
-// expected-error at +1 {{no viable constructor or deduction guide for deduction of template arguments of 'concept_fail'}}
+// expected-error at +1 {{no viable constructor or deduction guide for deduction of template arguments of 'nested_init_list<int>::concept_fail'}}
nested_init_list<int>::concept_fail nil_invalid{1, ""};
// expected-note@#INIT_LIST_INNER_INVALID {{candidate template ignored: substitution failure [with F = const char *]: constraints not satisfied for class template 'concept_fail' [with F = const char *]}}
// expected-note@#INIT_LIST_INNER_INVALID {{candidate function template not viable: requires 1 argument, but 2 were provided}}
diff --git a/clang/unittests/AST/TemplateNameTest.cpp b/clang/unittests/AST/TemplateNameTest.cpp
index fb9061053ea51..444ccfb5c9c81 100644
--- a/clang/unittests/AST/TemplateNameTest.cpp
+++ b/clang/unittests/AST/TemplateNameTest.cpp
@@ -24,6 +24,31 @@ std::string printTemplateName(TemplateName TN, const PrintingPolicy &Policy,
return Out.str();
}
+TEST(TemplateName, PrintTemplate) {
+ std::string Code = R"cpp(
+ namespace std {
+ template <typename> struct vector {};
+ }
+ template<template <typename> class T> class X;
+ using A = X<std::vector>;
+ )cpp";
+ auto AST = tooling::buildASTFromCode(Code);
+ ASTContext &Ctx = AST->getASTContext();
+ // Match the template argument vector in X<std::vector>.
+ auto MatchResults = match(templateArgumentLoc().bind("id"), Ctx);
+ const auto *Template = selectFirst<TemplateArgumentLoc>("id", MatchResults);
+ ASSERT_TRUE(Template);
+
+ TemplateName TN = Template->getArgument().getAsTemplate();
+ EXPECT_EQ(TN.getKind(), TemplateName::QualifiedTemplate);
+ EXPECT_EQ(printTemplateName(TN, Ctx.getPrintingPolicy(),
+ TemplateName::Qualified::AsWritten),
+ "std::vector");
+ EXPECT_EQ(printTemplateName(TN, Ctx.getPrintingPolicy(),
+ TemplateName::Qualified::None),
+ "vector");
+}
+
TEST(TemplateName, PrintUsingTemplate) {
std::string Code = R"cpp(
namespace std {
@@ -44,12 +69,11 @@ TEST(TemplateName, PrintUsingTemplate) {
ASSERT_TRUE(Template);
TemplateName TN = Template->getArgument().getAsTemplate();
- EXPECT_EQ(TN.getKind(), TemplateName::UsingTemplate);
- EXPECT_EQ(TN.getAsUsingShadowDecl()->getTargetDecl(), TN.getAsTemplateDecl());
+ EXPECT_EQ(TN.getKind(), TemplateName::QualifiedTemplate);
+ UsingShadowDecl *USD = TN.getAsUsingShadowDecl();
+ EXPECT_TRUE(USD != nullptr);
+ EXPECT_EQ(USD->getTargetDecl(), TN.getAsTemplateDecl());
- EXPECT_EQ(printTemplateName(TN, Ctx.getPrintingPolicy(),
- TemplateName::Qualified::Fully),
- "std::vector");
EXPECT_EQ(printTemplateName(TN, Ctx.getPrintingPolicy(),
TemplateName::Qualified::AsWritten),
"vector");
@@ -102,7 +126,8 @@ TEST(TemplateName, UsingTemplate) {
const auto *TST =
MatchResults.front().getNodeAs<TemplateSpecializationType>("id");
ASSERT_TRUE(TST);
- EXPECT_EQ(TST->getTemplateName().getKind(), TemplateName::UsingTemplate);
+ EXPECT_EQ(TST->getTemplateName().getKind(), TemplateName::QualifiedTemplate);
+ EXPECT_TRUE(TST->getTemplateName().getAsUsingShadowDecl() != nullptr);
AST = tooling::buildASTFromCodeWithArgs(R"cpp(
namespace std {
@@ -120,7 +145,8 @@ TEST(TemplateName, UsingTemplate) {
const auto *DTST =
MatchResults.front().getNodeAs<DeducedTemplateSpecializationType>("id");
ASSERT_TRUE(DTST);
- EXPECT_EQ(DTST->getTemplateName().getKind(), TemplateName::UsingTemplate);
+ EXPECT_EQ(DTST->getTemplateName().getKind(), TemplateName::QualifiedTemplate);
+ EXPECT_TRUE(DTST->getTemplateName().getAsUsingShadowDecl() != nullptr);
}
} // namespace
diff --git a/libcxx/test/std/containers/associative/map/map.cons/deduct.verify.cpp b/libcxx/test/std/containers/associative/map/map.cons/deduct.verify.cpp
index 70e200cda324f..b314e6fba6964 100644
--- a/libcxx/test/std/containers/associative/map/map.cons/deduct.verify.cpp
+++ b/libcxx/test/std/containers/associative/map/map.cons/deduct.verify.cpp
@@ -42,63 +42,63 @@ int main(int, char**)
{
{
// cannot deduce Key and T from nothing
- std::map m; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ std::map m; // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce Key and T from just (Compare)
std::map m(std::less<int>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce Key and T from just (Compare, Allocator)
std::map m(std::less<int>{}, std::allocator<PC>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce Key and T from just (Allocator)
std::map m(std::allocator<PC>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// refuse to rebind the allocator if Allocator::value_type is not exactly what we expect
const P arr[] = { {1,1L}, {2,2L}, {3,3L} };
std::map m(arr, arr + 3, std::allocator<P>());
- // expected-error-re at map:* {{static assertion failed{{( due to requirement '.*')?}}{{.*}}Allocator::value_type must be same type as value_type}}
+ // expected-error-re at map:*{{static assertion failed{{( due to requirement '.*')?}}{{.*}}Allocator::value_type must be same type as value_type}}
}
{
// cannot convert from some arbitrary unrelated type
NotAnAllocator a;
- std::map m(a); // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ std::map m(a); // expected-error-re{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::map m{ {1,1L}, {2,2L}, {3,3L} };
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::map m({ {1,1L}, {2,2L}, {3,3L} }, std::less<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::map m({ {1,1L}, {2,2L}, {3,3L} }, std::less<int>(), std::allocator<PC>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::map m({ {1,1L}, {2,2L}, {3,3L} }, std::allocator<PC>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// since we have parens, not braces, this deliberately does not find the initializer_list constructor
std::map m(P{1,1L});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
{
// since we have parens, not braces, this deliberately does not find the initializer_list constructor
std::map m(PC{1,1L});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}map'}}
}
return 0;
diff --git a/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct.verify.cpp b/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct.verify.cpp
index 1fda02638ef65..795ac19240031 100644
--- a/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct.verify.cpp
+++ b/libcxx/test/std/containers/associative/multimap/multimap.cons/deduct.verify.cpp
@@ -42,22 +42,22 @@ int main(int, char**)
{
{
// cannot deduce Key and T from nothing
- std::multimap m; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ std::multimap m; // expected-error-re{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce Key and T from just (Compare)
std::multimap m(std::less<int>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce Key and T from just (Compare, Allocator)
std::multimap m(std::less<int>{}, std::allocator<PC>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce Key and T from just (Allocator)
std::multimap m(std::allocator<PC>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// refuse to rebind the allocator if Allocator::value_type is not exactly what we expect
@@ -68,37 +68,37 @@ int main(int, char**)
{
// cannot convert from some arbitrary unrelated type
NotAnAllocator a;
- std::multimap m(a); // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ std::multimap m(a); // expected-error-re{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::multimap m{ {1,1L}, {2,2L}, {3,3L} };
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::multimap m({ {1,1L}, {2,2L}, {3,3L} }, std::less<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::multimap m({ {1,1L}, {2,2L}, {3,3L} }, std::less<int>(), std::allocator<PC>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// cannot deduce that the inner braced things should be std::pair and not something else
std::multimap m({ {1,1L}, {2,2L}, {3,3L} }, std::allocator<PC>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// since we have parens, not braces, this deliberately does not find the initializer_list constructor
std::multimap m(P{1,1L});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
{
// since we have parens, not braces, this deliberately does not find the initializer_list constructor
std::multimap m(PC{1,1L});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multimap'}}
}
return 0;
diff --git a/libcxx/test/std/containers/associative/multiset/multiset.cons/deduct.verify.cpp b/libcxx/test/std/containers/associative/multiset/multiset.cons/deduct.verify.cpp
index 48412e9f4c43b..30dd08b048155 100644
--- a/libcxx/test/std/containers/associative/multiset/multiset.cons/deduct.verify.cpp
+++ b/libcxx/test/std/containers/associative/multiset/multiset.cons/deduct.verify.cpp
@@ -40,29 +40,29 @@ int main(int, char **) {
{
// cannot deduce Key from nothing
std::multiset s;
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multiset'}}
}
{
// cannot deduce Key from just (Compare)
std::multiset s(std::less<int>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multiset'}}
}
{
// cannot deduce Key from just (Compare, Allocator)
std::multiset s(std::less<int>{}, std::allocator<int>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multiset'}}
}
{
// cannot deduce Key from multiset(Allocator)
std::multiset s(std::allocator<int>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multiset'}}
}
{
// since we have parens, not braces, this deliberately does not find the
// initializer_list constructor
NotAnAllocator a;
std::multiset s(a);
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}multiset'}}
}
return 0;
diff --git a/libcxx/test/std/containers/associative/set/set.cons/deduct.verify.cpp b/libcxx/test/std/containers/associative/set/set.cons/deduct.verify.cpp
index 02d2528870e54..6e250f8fa21e6 100644
--- a/libcxx/test/std/containers/associative/set/set.cons/deduct.verify.cpp
+++ b/libcxx/test/std/containers/associative/set/set.cons/deduct.verify.cpp
@@ -40,29 +40,29 @@ int main(int, char **) {
{
// cannot deduce Key from nothing
std::set s;
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}set'}}
}
{
// cannot deduce Key from just (Compare)
std::set s(std::less<int>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}set'}}
}
{
// cannot deduce Key from just (Compare, Allocator)
std::set s(std::less<int>{}, std::allocator<int>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}set'}}
}
{
// cannot deduce Key from just (Allocator)
std::set s(std::allocator<int>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}set'}}
}
{
// since we have parens, not braces, this deliberately does not find the
// initializer_list constructor
NotAnAllocator a;
std::set s(a);
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}set'}}
}
return 0;
diff --git a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.verify.cpp b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.verify.cpp
index 7dd0e256d7e7a..73487597ca56e 100644
--- a/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.verify.cpp
+++ b/libcxx/test/std/containers/container.adaptors/priority.queue/priqueue.cons/deduct.verify.cpp
@@ -22,32 +22,32 @@ int main(int, char**)
{
// queue(Compare, Container, const Alloc);
// The '45' is not an allocator
- std::priority_queue pri(std::greater<int>(), std::deque<int>({1,2,3}), 45); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'priority_queue'}}
+ std::priority_queue pri(std::greater<int>(), std::deque<int>({1,2,3}), 45); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}priority_queue'}}
}
{
// queue(const queue&, const Alloc&);
// The '45' is not an allocator
std::priority_queue<int> source;
- std::priority_queue pri(source, 45); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'priority_queue'}}
+ std::priority_queue pri(source, 45); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}priority_queue'}}
}
{
// priority_queue(Iter, Iter, Comp)
// int is not an iterator
- std::priority_queue pri(15, 17, std::greater<double>()); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'priority_queue'}}
+ std::priority_queue pri(15, 17, std::greater<double>()); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}priority_queue'}}
}
{
// priority_queue(Iter, Iter, Comp, Container)
// float is not an iterator
- std::priority_queue pri(23.f, 2.f, std::greater<float>(), std::deque<float>()); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'priority_queue'}}
+ std::priority_queue pri(23.f, 2.f, std::greater<float>(), std::deque<float>()); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}priority_queue'}}
}
// Test the implicit deduction guides
{
// priority_queue (allocator &)
- std::priority_queue pri((std::allocator<int>())); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'priority_queue'}}
+ std::priority_queue pri((std::allocator<int>())); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}priority_queue'}}
// Note: The extra parens are necessary, since otherwise clang decides it is a function declaration.
// Also, we can't use {} instead of parens, because that constructs a
// stack<allocator<int>, allocator<allocator<int>>>
diff --git a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/deduct.verify.cpp b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/deduct.verify.cpp
index 301acca8c67c6..f85b2cbeb249c 100644
--- a/libcxx/test/std/containers/container.adaptors/queue/queue.cons/deduct.verify.cpp
+++ b/libcxx/test/std/containers/container.adaptors/queue/queue.cons/deduct.verify.cpp
@@ -22,20 +22,20 @@ int main(int, char**)
{
// queue(const Container&, const Alloc&);
// The '45' is not an allocator
- std::queue que(std::list<int>{1,2,3}, 45); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'queue'}}
+ std::queue que(std::list<int>{1,2,3}, 45); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}queue'}}
}
{
// queue(const queue&, const Alloc&);
// The '45' is not an allocator
std::queue<int> source;
- std::queue que(source, 45); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'queue'}}
+ std::queue que(source, 45); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}queue'}}
}
// Test the implicit deduction guides
{
// queue (allocator &)
- std::queue que((std::allocator<int>())); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'queue'}}
+ std::queue que((std::allocator<int>())); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}queue'}}
// Note: The extra parens are necessary, since otherwise clang decides it is a function declaration.
// Also, we can't use {} instead of parens, because that constructs a
// stack<allocator<int>, allocator<allocator<int>>>
diff --git a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/deduct.verify.cpp b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/deduct.verify.cpp
index 55296f4122335..390df86dd0f5a 100644
--- a/libcxx/test/std/containers/container.adaptors/stack/stack.cons/deduct.verify.cpp
+++ b/libcxx/test/std/containers/container.adaptors/stack/stack.cons/deduct.verify.cpp
@@ -28,20 +28,20 @@ int main(int, char**)
{
// stack(const Container&, const Alloc&);
// The '45' is not an allocator
- std::stack stk(std::list<int>({1,2,3}), 45); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'stack'}}
+ std::stack stk(std::list<int>({1,2,3}), 45); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}stack'}}
}
{
// stack(const stack&, const Alloc&);
// The '45' is not an allocator
std::stack<int> source;
- std::stack stk(source, 45); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'stack'}}
+ std::stack stk(source, 45); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}stack'}}
}
// Test the implicit deduction guides
{
// stack (allocator &)
- std::stack stk((std::allocator<int>())); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'stack'}}
+ std::stack stk((std::allocator<int>())); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}stack'}}
// Note: The extra parens are necessary, since otherwise clang decides it is a function declaration.
// Also, we can't use {} instead of parens, because that constructs a
// stack<allocator<int>, allocator<allocator<int>>>
diff --git a/libcxx/test/std/containers/sequences/array/array.cons/deduct.verify.cpp b/libcxx/test/std/containers/sequences/array/array.cons/deduct.verify.cpp
index 1a654e195c7b6..f59b761fad9c9 100644
--- a/libcxx/test/std/containers/sequences/array/array.cons/deduct.verify.cpp
+++ b/libcxx/test/std/containers/sequences/array/array.cons/deduct.verify.cpp
@@ -24,7 +24,7 @@
int main(int, char**)
{
{
- std::array arr{1,2,3L}; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'array'}}
+ std::array arr{1,2,3L}; // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}array'}}
}
return 0;
diff --git a/libcxx/test/std/containers/sequences/deque/deque.cons/deduct.verify.cpp b/libcxx/test/std/containers/sequences/deque/deque.cons/deduct.verify.cpp
index 044669aaec822..f65e230112d90 100644
--- a/libcxx/test/std/containers/sequences/deque/deque.cons/deduct.verify.cpp
+++ b/libcxx/test/std/containers/sequences/deque/deque.cons/deduct.verify.cpp
@@ -29,7 +29,7 @@ int main(int, char**)
// Test the implicit deduction guides
{
// deque (allocator &)
- std::deque deq((std::allocator<int>())); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'deque'}}
+ std::deque deq((std::allocator<int>())); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}deque'}}
// Note: The extra parens are necessary, since otherwise clang decides it is a function declaration.
// Also, we can't use {} instead of parens, because that constructs a
// deque<allocator<int>, allocator<allocator<int>>>
diff --git a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.verify.cpp b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.verify.cpp
index 47c1cdcea0e40..b3c3f73270f32 100644
--- a/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.verify.cpp
+++ b/libcxx/test/std/containers/sequences/forwardlist/forwardlist.cons/deduct.verify.cpp
@@ -29,7 +29,7 @@ int main(int, char**)
// Test the implicit deduction guides
{
// forward_list (allocator &)
- std::forward_list fwl((std::allocator<int>())); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'forward_list'}}
+ std::forward_list fwl((std::allocator<int>())); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}forward_list'}}
// Note: The extra parens are necessary, since otherwise clang decides it is a function declaration.
// Also, we can't use {} instead of parens, because that constructs a
// forward_list<allocator<int>, allocator<allocator<int>>>
diff --git a/libcxx/test/std/containers/sequences/list/list.cons/deduct.verify.cpp b/libcxx/test/std/containers/sequences/list/list.cons/deduct.verify.cpp
index 96d14514456c5..370cd38612ab0 100644
--- a/libcxx/test/std/containers/sequences/list/list.cons/deduct.verify.cpp
+++ b/libcxx/test/std/containers/sequences/list/list.cons/deduct.verify.cpp
@@ -29,7 +29,7 @@ int main(int, char**)
// Test the implicit deduction guides
{
// list (allocator &)
- std::list lst((std::allocator<int>())); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'list'}}
+ std::list lst((std::allocator<int>())); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}list'}}
// Note: The extra parens are necessary, since otherwise clang decides it is a function declaration.
// Also, we can't use {} instead of parens, because that constructs a
// deque<allocator<int>, allocator<allocator<int>>>
diff --git a/libcxx/test/std/containers/sequences/vector/vector.cons/deduct.verify.cpp b/libcxx/test/std/containers/sequences/vector/vector.cons/deduct.verify.cpp
index 2b2242e240a2c..a6fc763050ec6 100644
--- a/libcxx/test/std/containers/sequences/vector/vector.cons/deduct.verify.cpp
+++ b/libcxx/test/std/containers/sequences/vector/vector.cons/deduct.verify.cpp
@@ -25,7 +25,7 @@ int main(int, char**) {
// Test the implicit deduction guides
{
// vector (allocator &)
- // expected-error at +1 {{no viable constructor or deduction guide for deduction of template arguments of 'vector'}}
+ // expected-error-re at +1 {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}vector'}}
std::vector vec(std::allocator< int>{});
}
diff --git a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct.verify.cpp b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct.verify.cpp
index aa7a0580750f7..dc0ffd26813d9 100644
--- a/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct.verify.cpp
+++ b/libcxx/test/std/containers/unord/unord.map/unord.map.cnstr/deduct.verify.cpp
@@ -64,41 +64,41 @@ int main(int, char**)
using P = std::pair<const int, int>;
{
// cannot deduce Key from nothing
- std::unordered_map m; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}}
+ std::unordered_map m; // expected-error-re{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_map'}}
}
{
// cannot deduce Key from just (Size)
- std::unordered_map m(42); // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}}
+ std::unordered_map m(42); // expected-error-re{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_map'}}
}
{
// cannot deduce Key from just (Size, Hash)
std::unordered_map m(42, std::hash<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_map'}}
}
{
// cannot deduce Key from just (Size, Hash, Pred)
std::unordered_map m(42, std::hash<int>(), std::equal_to<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_map'}}
}
{
// cannot deduce Key from just (Size, Hash, Pred, Allocator)
std::unordered_map m(42, std::hash<int>(), std::equal_to<int>(), std::allocator<P>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_map'}}
}
{
// cannot deduce Key from just (Allocator)
std::unordered_map m(std::allocator<P>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_map'}}
}
{
// cannot deduce Key from just (Size, Allocator)
std::unordered_map m(42, std::allocator<P>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_map'}}
}
{
// cannot deduce Key from just (Size, Hash, Allocator)
std::unordered_map m(42, std::hash<int>(), std::allocator<P>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_map'}}
}
return 0;
diff --git a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct.verify.cpp b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct.verify.cpp
index 5e8db678b6e20..efcbbbce0e302 100644
--- a/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct.verify.cpp
+++ b/libcxx/test/std/containers/unord/unord.multimap/unord.multimap.cnstr/deduct.verify.cpp
@@ -64,41 +64,41 @@ int main(int, char**)
using P = std::pair<const int, int>;
{
// cannot deduce Key from nothing
- std::unordered_multimap m; // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}}
+ std::unordered_multimap m; // expected-error-re{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multimap'}}
}
{
// cannot deduce Key from just (Size)
- std::unordered_multimap m(42); // expected-error{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}}
+ std::unordered_multimap m(42); // expected-error-re{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multimap'}}
}
{
// cannot deduce Key from just (Size, Hash)
std::unordered_multimap m(42, std::hash<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multimap'}}
}
{
// cannot deduce Key from just (Size, Hash, Pred)
std::unordered_multimap m(42, std::hash<int>(), std::equal_to<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multimap'}}
}
{
// cannot deduce Key from just (Size, Hash, Pred, Allocator)
std::unordered_multimap m(42, std::hash<int>(), std::equal_to<int>(), std::allocator<P>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multimap'}}
}
{
// cannot deduce Key from just (Allocator)
std::unordered_multimap m(std::allocator<P>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multimap'}}
}
{
// cannot deduce Key from just (Size, Allocator)
std::unordered_multimap m(42, std::allocator<P>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multimap'}}
}
{
// cannot deduce Key from just (Size, Hash, Allocator)
std::unordered_multimap m(42, std::hash<int>(), std::allocator<P>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multimap'}}
}
return 0;
diff --git a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.verify.cpp b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.verify.cpp
index 16dd268f4b08a..8fd7d1d6c20ef 100644
--- a/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.verify.cpp
+++ b/libcxx/test/std/containers/unord/unord.multiset/unord.multiset.cnstr/deduct.verify.cpp
@@ -55,42 +55,42 @@ int main(int, char**)
{
// cannot deduce Key from nothing
std::unordered_multiset s;
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multiset'}}
}
{
// cannot deduce Key from just (Size)
std::unordered_multiset s(42);
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multiset'}}
}
{
// cannot deduce Key from just (Size, Hash)
std::unordered_multiset s(42, std::hash<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multiset'}}
}
{
// cannot deduce Key from just (Size, Hash, Pred)
std::unordered_multiset s(42, std::hash<int>(), std::equal_to<>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multiset'}}
}
{
// cannot deduce Key from just (Size, Hash, Pred, Allocator)
std::unordered_multiset s(42, std::hash<int>(), std::equal_to<>(), std::allocator<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multiset'}}
}
{
// cannot deduce Key from just (Allocator)
std::unordered_multiset s(std::allocator<int>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multiset'}}
}
{
// cannot deduce Key from just (Size, Allocator)
std::unordered_multiset s(42, std::allocator<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multiset'}}
}
{
// cannot deduce Key from just (Size, Hash, Allocator)
std::unordered_multiset s(42, std::hash<short>(), std::allocator<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_multiset'}}
}
return 0;
diff --git a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.verify.cpp b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.verify.cpp
index d6082810216df..26e5f9ae6ce43 100644
--- a/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.verify.cpp
+++ b/libcxx/test/std/containers/unord/unord.set/unord.set.cnstr/deduct.verify.cpp
@@ -55,42 +55,42 @@ int main(int, char**)
{
// cannot deduce Key from nothing
std::unordered_set s;
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_set'}}
}
{
// cannot deduce Key from just (Size)
std::unordered_set s(42);
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_set'}}
}
{
// cannot deduce Key from just (Size, Hash)
std::unordered_set s(42, std::hash<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_set'}}
}
{
// cannot deduce Key from just (Size, Hash, Pred)
std::unordered_set s(42, std::hash<int>(), std::equal_to<>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_set'}}
}
{
// cannot deduce Key from just (Size, Hash, Pred, Allocator)
std::unordered_set s(42, std::hash<int>(), std::equal_to<>(), std::allocator<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_set'}}
}
{
// cannot deduce Key from just (Allocator)
std::unordered_set s(std::allocator<int>{});
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_set'}}
}
{
// cannot deduce Key from just (Size, Allocator)
std::unordered_set s(42, std::allocator<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_set'}}
}
{
// cannot deduce Key from just (Size, Hash, Allocator)
std::unordered_set s(42, std::hash<short>(), std::allocator<int>());
- // expected-error at -1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}}
+ // expected-error-re at -1{{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}unordered_set'}}
}
return 0;
diff --git a/libcxx/test/std/ranges/range.adaptors/range.join/ctad.verify.cpp b/libcxx/test/std/ranges/range.adaptors/range.join/ctad.verify.cpp
index 2c6eea500580d..de0c108e98336 100644
--- a/libcxx/test/std/ranges/range.adaptors/range.join/ctad.verify.cpp
+++ b/libcxx/test/std/ranges/range.adaptors/range.join/ctad.verify.cpp
@@ -27,5 +27,5 @@ struct Range {
void testExplicitCTAD() {
Range<Range<int>> r;
- std::ranges::join_view v = r; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'join_view'}}
+ std::ranges::join_view v = r; // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::ranges::)?}}join_view'}}
}
diff --git a/libcxx/test/std/re/re.regex/re.regex.construct/deduct.verify.cpp b/libcxx/test/std/re/re.regex/re.regex.construct/deduct.verify.cpp
index 593dd9d0ec51d..8ef87cfc6468f 100644
--- a/libcxx/test/std/re/re.regex/re.regex.construct/deduct.verify.cpp
+++ b/libcxx/test/std/re/re.regex/re.regex.construct/deduct.verify.cpp
@@ -27,13 +27,13 @@ int main(int, char**)
{
// basic_regex(ForwardIterator, ForwardIterator)
// <int> is not an iterator
- std::basic_regex re(23, 34); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_regex'}}
+ std::basic_regex re(23, 34); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}basic_regex'}}
}
{
// basic_regex(ForwardIterator, ForwardIterator, flag_type)
// <double> is not an iterator
- std::basic_regex re(23.0, 34.0, std::regex_constants::basic); // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'basic_regex'}}
+ std::basic_regex re(23.0, 34.0, std::regex_constants::basic); // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}basic_regex'}}
}
return 0;
diff --git a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp
index 0c887c683a818..364f9b2e955f0 100644
--- a/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp
+++ b/libcxx/test/std/utilities/optional/optional.object/optional.object.ctor/deduct.verify.cpp
@@ -25,7 +25,7 @@ int main(int, char**)
// Test the implicit deduction guides
{
// optional()
- std::optional opt; // expected-error {{no viable constructor or deduction guide for deduction of template arguments of 'optional'}}
+ std::optional opt; // expected-error-re {{no viable constructor or deduction guide for deduction of template arguments of '{{(std::)?}}optional'}}
}
{
More information about the cfe-commits
mailing list