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 <mizve...@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@-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@-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@-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@-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@-1 {{because 'false_v<requires { typename contains_template<int>::temp<contains_template<int> >; }>' evaluated to false}} - // expected-note@-2 {{because 'false_v<requires { typename contains_template<short>::temp<contains_template<short> >; }>' evaluated to false}} + // expected-note@-1 {{because 'false_v<requires { typename contains_template<int>::template temp<contains_template<int> >; }>' evaluated to false}} + // expected-note@-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@+1 {{no viable constructor or deduction guide for deduction of template arguments of 'concept_fail'}} +// expected-error@+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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}} + // expected-error-re@-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@map:* {{static assertion failed{{( due to requirement '.*')?}}{{.*}}Allocator::value_type must be same type as value_type}} + // expected-error-re@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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'set'}} + // expected-error-re@-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@+1 {{no viable constructor or deduction guide for deduction of template arguments of 'vector'}} + // expected-error-re@+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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_map'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multimap'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_multiset'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}} + // expected-error-re@-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@-1{{no viable constructor or deduction guide for deduction of template arguments of 'unordered_set'}} + // expected-error-re@-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'}} } { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits