https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/132748
>From b50ea7d744280bdfb97f0abaeb10d088d502e81a Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <mizve...@gmail.com> Date: Sat, 22 Mar 2025 16:03:04 -0300 Subject: [PATCH 1/4] [clang] Track final substitution for SubstTemplateTemplateParm nodes --- clang/include/clang/AST/ASTContext.h | 9 +++++---- clang/include/clang/AST/PropertiesBase.td | 3 ++- clang/include/clang/AST/TemplateName.h | 17 ++++++++++++----- clang/include/clang/AST/Type.h | 3 ++- clang/lib/AST/ASTContext.cpp | 6 +++--- clang/lib/AST/ASTImporter.cpp | 2 +- clang/lib/AST/TemplateName.cpp | 6 ++++-- clang/lib/AST/TextNodeDumper.cpp | 2 ++ clang/lib/Sema/SemaTemplateInstantiate.cpp | 8 ++------ 9 files changed, 33 insertions(+), 23 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index a24f30815e6b9..fca41fbe38812 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -2393,10 +2393,11 @@ class ASTContext : public RefCountedBase<ASTContext> { TemplateName getDependentTemplateName(const DependentTemplateStorage &Name) const; - TemplateName - getSubstTemplateTemplateParm(TemplateName replacement, Decl *AssociatedDecl, - unsigned Index, - std::optional<unsigned> PackIndex) const; + TemplateName getSubstTemplateTemplateParm(TemplateName replacement, + Decl *AssociatedDecl, + unsigned Index, + std::optional<unsigned> PackIndex, + bool Final) const; TemplateName getSubstTemplateTemplateParmPack(const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index, diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td index 5171555008ac9..0e360de16fdd6 100644 --- a/clang/include/clang/AST/PropertiesBase.td +++ b/clang/include/clang/AST/PropertiesBase.td @@ -730,8 +730,9 @@ let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParm"> in { def : Property<"packIndex", Optional<UInt32>> { let Read = [{ parm->getPackIndex() }]; } + def : Property<"final", Bool> { let Read = [{ parm->getFinal() }]; } def : Creator<[{ - return ctx.getSubstTemplateTemplateParm(replacement, associatedDecl, index, packIndex); + return ctx.getSubstTemplateTemplateParm(replacement, associatedDecl, index, packIndex, final); }]>; } let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParmPack"> in { diff --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h index 1a56133b72d6e..ece2afcfa72ab 100644 --- a/clang/include/clang/AST/TemplateName.h +++ b/clang/include/clang/AST/TemplateName.h @@ -414,9 +414,11 @@ class SubstTemplateTemplateParmStorage SubstTemplateTemplateParmStorage(TemplateName Replacement, Decl *AssociatedDecl, unsigned Index, - std::optional<unsigned> PackIndex) + std::optional<unsigned> PackIndex, + bool Final) : UncommonTemplateNameStorage(SubstTemplateTemplateParm, Index, - PackIndex ? *PackIndex + 1 : 0), + ((PackIndex ? *PackIndex + 1 : 0) << 1) | + Final), Replacement(Replacement), AssociatedDecl(AssociatedDecl) { assert(AssociatedDecl != nullptr); } @@ -430,10 +432,15 @@ class SubstTemplateTemplateParmStorage /// This should match the result of `getParameter()->getIndex()`. unsigned getIndex() const { return Bits.Index; } + // This substitution is Final, which means the substitution is fully + // sugared: it doesn't need to be resugared later. + bool getFinal() const { return Bits.Data & 1; } + std::optional<unsigned> getPackIndex() const { - if (Bits.Data == 0) + auto Data = Bits.Data >> 1; + if (Data == 0) return std::nullopt; - return Bits.Data - 1; + return Data - 1; } TemplateTemplateParmDecl *getParameter() const; @@ -443,7 +450,7 @@ class SubstTemplateTemplateParmStorage static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Replacement, Decl *AssociatedDecl, unsigned Index, - std::optional<unsigned> PackIndex); + std::optional<unsigned> PackIndex, bool Final); }; class DeducedTemplateStorage : public UncommonTemplateNameStorage, diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index cfd417068abb7..4f33215fd9724 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -6488,7 +6488,8 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode { /// This should match the result of `getReplacedParameter()->getIndex()`. unsigned getIndex() const { return SubstTemplateTypeParmPackTypeBits.Index; } - // When true the substitution will be 'Final' (subst node won't be placed). + // This substitution will be Final, which means the substitution will be fully + // sugared: it doesn't need to be resugared later. bool getFinal() const; unsigned getNumArgs() const { diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 552b5823add36..a012232b38475 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -10090,10 +10090,10 @@ ASTContext::getDependentTemplateName(const DependentTemplateStorage &S) const { TemplateName ASTContext::getSubstTemplateTemplateParm( TemplateName Replacement, Decl *AssociatedDecl, unsigned Index, - std::optional<unsigned> PackIndex) const { + std::optional<unsigned> PackIndex, bool Final) const { llvm::FoldingSetNodeID ID; SubstTemplateTemplateParmStorage::Profile(ID, Replacement, AssociatedDecl, - Index, PackIndex); + Index, PackIndex, Final); void *insertPos = nullptr; SubstTemplateTemplateParmStorage *subst @@ -10101,7 +10101,7 @@ TemplateName ASTContext::getSubstTemplateTemplateParm( if (!subst) { subst = new (*this) SubstTemplateTemplateParmStorage( - Replacement, AssociatedDecl, Index, PackIndex); + Replacement, AssociatedDecl, Index, PackIndex, Final); SubstTemplateTemplateParms.InsertNode(subst, insertPos); } diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 81acb013b0f7d..2ddb120a78a62 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -9932,7 +9932,7 @@ Expected<TemplateName> ASTImporter::Import(TemplateName From) { return ToContext.getSubstTemplateTemplateParm( *ReplacementOrErr, *AssociatedDeclOrErr, Subst->getIndex(), - Subst->getPackIndex()); + Subst->getPackIndex(), Subst->getFinal()); } case TemplateName::SubstTemplateTemplateParmPack: { diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp index 031b58123fc99..f8ba5a24c7519 100644 --- a/clang/lib/AST/TemplateName.cpp +++ b/clang/lib/AST/TemplateName.cpp @@ -77,16 +77,18 @@ SubstTemplateTemplateParmStorage::getParameter() const { } void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, Replacement, getAssociatedDecl(), getIndex(), getPackIndex()); + Profile(ID, Replacement, getAssociatedDecl(), getIndex(), getPackIndex(), + getFinal()); } void SubstTemplateTemplateParmStorage::Profile( llvm::FoldingSetNodeID &ID, TemplateName Replacement, Decl *AssociatedDecl, - unsigned Index, std::optional<unsigned> PackIndex) { + unsigned Index, std::optional<unsigned> PackIndex, bool Final) { Replacement.Profile(ID); ID.AddPointer(AssociatedDecl); ID.AddInteger(Index); ID.AddInteger(PackIndex ? *PackIndex + 1 : 0); + ID.AddBoolean(Final); } SubstTemplateTemplateParmPackStorage::SubstTemplateTemplateParmPackStorage( diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 1fe6f2c722acf..84847b9081503 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1298,6 +1298,8 @@ void TextNodeDumper::dumpBareTemplateName(TemplateName TN) { OS << " index " << STS->getIndex(); if (std::optional<unsigned int> PackIndex = STS->getPackIndex()) OS << " pack_index " << *PackIndex; + if (STS->getFinal()) + OS << " final"; if (const TemplateTemplateParmDecl *P = STS->getParameter()) AddChild("parameter", [=] { Visit(P); }); dumpDeclRef(STS->getAssociatedDecl(), "associated"); diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 9f5ca9dca8e89..1a8894ce50532 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2083,10 +2083,8 @@ TemplateName TemplateInstantiator::TransformTemplateName( TemplateName Template = Arg.getAsTemplate(); assert(!Template.isNull() && "Null template template argument"); - if (Final) - return Template; return getSema().Context.getSubstTemplateTemplateParm( - Template, AssociatedDecl, TTP->getIndex(), PackIndex); + Template, AssociatedDecl, TTP->getIndex(), PackIndex, Final); } } @@ -2098,11 +2096,9 @@ TemplateName TemplateInstantiator::TransformTemplateName( TemplateArgument Pack = SubstPack->getArgumentPack(); TemplateName Template = getPackSubstitutedTemplateArgument(getSema(), Pack).getAsTemplate(); - if (SubstPack->getFinal()) - return Template; return getSema().Context.getSubstTemplateTemplateParm( Template, SubstPack->getAssociatedDecl(), SubstPack->getIndex(), - getPackIndex(Pack)); + getPackIndex(Pack), SubstPack->getFinal()); } return inherited::TransformTemplateName(SS, Name, NameLoc, ObjectType, >From 6745c23c07594b0220593ff9cd2154660b2f2b08 Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <mizve...@gmail.com> Date: Sat, 22 Mar 2025 16:35:39 -0300 Subject: [PATCH 2/4] [clang] Track final substitution for SubstNonTypeTemplateParmExpr nodes --- clang/include/clang/AST/ExprCXX.h | 25 ++++++++++++---- clang/lib/AST/ASTImporter.cpp | 3 +- clang/lib/AST/ExprCXX.cpp | 6 ++-- clang/lib/Sema/SemaTemplate.cpp | 2 +- clang/lib/Sema/SemaTemplateInstantiate.cpp | 34 ++++++++++------------ 5 files changed, 42 insertions(+), 28 deletions(-) diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h index 223d74993e9e6..028ee82718d50 100644 --- a/clang/include/clang/AST/ExprCXX.h +++ b/clang/include/clang/AST/ExprCXX.h @@ -4514,7 +4514,9 @@ class SubstNonTypeTemplateParmExpr : public Expr { llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndRef; unsigned Index : 15; - unsigned PackIndex : 16; + unsigned PackIndex : 15; + LLVM_PREFERRED_TYPE(bool) + unsigned Final : 1; explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty) : Expr(SubstNonTypeTemplateParmExprClass, Empty) {} @@ -4523,11 +4525,12 @@ class SubstNonTypeTemplateParmExpr : public Expr { SubstNonTypeTemplateParmExpr(QualType Ty, ExprValueKind ValueKind, SourceLocation Loc, Expr *Replacement, Decl *AssociatedDecl, unsigned Index, - std::optional<unsigned> PackIndex, bool RefParam) + std::optional<unsigned> PackIndex, bool RefParam, + bool Final) : Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary), Replacement(Replacement), AssociatedDeclAndRef(AssociatedDecl, RefParam), Index(Index), - PackIndex(PackIndex ? *PackIndex + 1 : 0) { + PackIndex(PackIndex ? *PackIndex + 1 : 0), Final(Final) { assert(AssociatedDecl != nullptr); SubstNonTypeTemplateParmExprBits.NameLoc = Loc; setDependence(computeDependence(this)); @@ -4555,6 +4558,10 @@ class SubstNonTypeTemplateParmExpr : public Expr { return PackIndex - 1; } + // This substitution is Final, which means the substitution is fully + // sugared: it doesn't need to be resugared later. + bool getFinal() const { return Final; } + NonTypeTemplateParmDecl *getParameter() const; bool isReferenceParameter() const { return AssociatedDeclAndRef.getInt(); } @@ -4598,7 +4605,10 @@ class SubstNonTypeTemplateParmPackExpr : public Expr { const TemplateArgument *Arguments; /// The number of template arguments in \c Arguments. - unsigned NumArguments : 16; + unsigned NumArguments : 15; + + LLVM_PREFERRED_TYPE(bool) + unsigned Final : 1; unsigned Index : 16; @@ -4612,7 +4622,8 @@ class SubstNonTypeTemplateParmPackExpr : public Expr { SubstNonTypeTemplateParmPackExpr(QualType T, ExprValueKind ValueKind, SourceLocation NameLoc, const TemplateArgument &ArgPack, - Decl *AssociatedDecl, unsigned Index); + Decl *AssociatedDecl, unsigned Index, + bool Final); /// A template-like entity which owns the whole pattern being substituted. /// This will own a set of template parameters. @@ -4622,6 +4633,10 @@ class SubstNonTypeTemplateParmPackExpr : public Expr { /// This should match the result of `getParameterPack()->getIndex()`. unsigned getIndex() const { return Index; } + // This substitution will be Final, which means the substitution will be fully + // sugared: it doesn't need to be resugared later. + bool getFinal() const { return Final; } + /// Retrieve the non-type template parameter pack being substituted. NonTypeTemplateParmDecl *getParameterPack() const; diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 2ddb120a78a62..51925ab51e4cd 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -8937,7 +8937,8 @@ ExpectedStmt ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr( return new (Importer.getToContext()) SubstNonTypeTemplateParmExpr( ToType, E->getValueKind(), ToExprLoc, ToReplacement, ToAssociatedDecl, - E->getIndex(), E->getPackIndex(), E->isReferenceParameter()); + E->getIndex(), E->getPackIndex(), E->isReferenceParameter(), + E->getFinal()); } ExpectedStmt ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) { diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp index a000e988e6834..a0bc50c449d82 100644 --- a/clang/lib/AST/ExprCXX.cpp +++ b/clang/lib/AST/ExprCXX.cpp @@ -1760,10 +1760,12 @@ QualType SubstNonTypeTemplateParmExpr::getParameterType( SubstNonTypeTemplateParmPackExpr::SubstNonTypeTemplateParmPackExpr( QualType T, ExprValueKind ValueKind, SourceLocation NameLoc, - const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index) + const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index, + bool Final) : Expr(SubstNonTypeTemplateParmPackExprClass, T, ValueKind, OK_Ordinary), AssociatedDecl(AssociatedDecl), Arguments(ArgPack.pack_begin()), - NumArguments(ArgPack.pack_size()), Index(Index), NameLoc(NameLoc) { + NumArguments(ArgPack.pack_size()), Final(Final), Index(Index), + NameLoc(NameLoc) { assert(AssociatedDecl != nullptr); setDependence(ExprDependence::TypeValueInstantiation | ExprDependence::UnexpandedPack); diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index eace9b87a5bfe..f2f49ce347236 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -7567,7 +7567,7 @@ ExprResult Sema::BuildExpressionFromDeclTemplateArgument( ParamType->getPointeeType(), RefExpr.get()->getValueKind(), RefExpr.get()->getExprLoc(), RefExpr.get(), VD, NTTP->getIndex(), /*PackIndex=*/std::nullopt, - /*RefParam=*/true); + /*RefParam=*/true, /*Final=*/true); } } } diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 1a8894ce50532..4b9d97cc7d97a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -1865,11 +1865,10 @@ namespace { Sema::ExtParameterInfoBuilder &PInfos); private: - ExprResult - transformNonTypeTemplateParmRef(Decl *AssociatedDecl, - const NonTypeTemplateParmDecl *parm, - SourceLocation loc, TemplateArgument arg, - std::optional<unsigned> PackIndex); + ExprResult transformNonTypeTemplateParmRef( + Decl *AssociatedDecl, const NonTypeTemplateParmDecl *parm, + SourceLocation loc, TemplateArgument arg, + std::optional<unsigned> PackIndex, bool Final); }; } @@ -2140,7 +2139,8 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E, return Arg.getAsExpr(); } - auto [AssociatedDecl, _] = TemplateArgs.getAssociatedDecl(NTTP->getDepth()); + auto [AssociatedDecl, Final] = + TemplateArgs.getAssociatedDecl(NTTP->getDepth()); std::optional<unsigned> PackIndex; if (NTTP->isParameterPack()) { assert(Arg.getKind() == TemplateArgument::Pack && @@ -2159,17 +2159,15 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E, QualType ExprType = TargetType.getNonLValueExprType(SemaRef.Context); if (TargetType->isRecordType()) ExprType.addConst(); - // FIXME: Pass in Final. return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr( ExprType, TargetType->isReferenceType() ? VK_LValue : VK_PRValue, - E->getLocation(), Arg, AssociatedDecl, NTTP->getPosition()); + E->getLocation(), Arg, AssociatedDecl, NTTP->getPosition(), Final); } PackIndex = getPackIndex(Arg); Arg = getPackSubstitutedTemplateArgument(getSema(), Arg); } - // FIXME: Don't put subst node on Final replacement. return transformNonTypeTemplateParmRef(AssociatedDecl, NTTP, E->getLocation(), - Arg, PackIndex); + Arg, PackIndex, Final); } const AnnotateAttr * @@ -2264,8 +2262,8 @@ TemplateInstantiator::TransformOpenACCRoutineDeclAttr( ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef( Decl *AssociatedDecl, const NonTypeTemplateParmDecl *parm, - SourceLocation loc, TemplateArgument arg, - std::optional<unsigned> PackIndex) { + SourceLocation loc, TemplateArgument arg, std::optional<unsigned> PackIndex, + bool Final) { ExprResult result; // Determine the substituted parameter type. We can usually infer this from @@ -2331,10 +2329,9 @@ ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef( return ExprError(); Expr *resultExpr = result.get(); - // FIXME: Don't put subst node on final replacement. return new (SemaRef.Context) SubstNonTypeTemplateParmExpr( resultExpr->getType(), resultExpr->getValueKind(), loc, resultExpr, - AssociatedDecl, parm->getIndex(), PackIndex, refParam); + AssociatedDecl, parm->getIndex(), PackIndex, refParam, Final); } ExprResult @@ -2347,10 +2344,9 @@ TemplateInstantiator::TransformSubstNonTypeTemplateParmPackExpr( TemplateArgument Pack = E->getArgumentPack(); TemplateArgument Arg = getPackSubstitutedTemplateArgument(getSema(), Pack); - // FIXME: Don't put subst node on final replacement. return transformNonTypeTemplateParmRef( E->getAssociatedDecl(), E->getParameterPack(), - E->getParameterPackLocation(), Arg, getPackIndex(Pack)); + E->getParameterPackLocation(), Arg, getPackIndex(Pack), E->getFinal()); } ExprResult @@ -2392,9 +2388,9 @@ TemplateInstantiator::TransformSubstNonTypeTemplateParmExpr( /*PartialOrderingTTP=*/false, Sema::CTAK_Specified) .isInvalid()) return true; - return transformNonTypeTemplateParmRef(E->getAssociatedDecl(), - E->getParameter(), E->getExprLoc(), - SugaredConverted, E->getPackIndex()); + return transformNonTypeTemplateParmRef( + E->getAssociatedDecl(), E->getParameter(), E->getExprLoc(), + SugaredConverted, E->getPackIndex(), E->getFinal()); } ExprResult TemplateInstantiator::RebuildVarDeclRefExpr(ValueDecl *PD, >From 789dfa29b83f37c473b2c07311cde804c3d74ac1 Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <mizve...@gmail.com> Date: Sun, 23 Mar 2025 17:45:40 -0300 Subject: [PATCH 3/4] [clang] Track final substitution for SubstTemplateTypeParmType nodes --- clang/include/clang/AST/ASTContext.h | 8 +++---- clang/include/clang/AST/Type.h | 21 ++++++++++-------- clang/include/clang/AST/TypeProperties.td | 4 ++-- clang/lib/AST/ASTContext.cpp | 9 ++++---- clang/lib/AST/ASTImporter.cpp | 4 ++-- clang/lib/AST/TextNodeDumper.cpp | 2 ++ clang/lib/AST/Type.cpp | 22 +++++++++++++++---- clang/lib/Sema/SemaTemplateInstantiate.cpp | 6 +---- clang/lib/Sema/TreeTransform.h | 3 ++- clang/test/AST/ast-dump-template-decls.cpp | 18 ++++++++++----- .../test/Misc/diag-template-diffing-cxx11.cpp | 4 ++-- clang/test/SemaTemplate/make_integer_seq.cpp | 8 +++++-- 12 files changed, 68 insertions(+), 41 deletions(-) diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index fca41fbe38812..b3010fa888fa4 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1795,10 +1795,10 @@ class ASTContext : public RefCountedBase<ASTContext> { QualType Wrapped, QualType Contained, const HLSLAttributedResourceType::Attributes &Attrs); - QualType - getSubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl, - unsigned Index, - std::optional<unsigned> PackIndex) const; + QualType getSubstTemplateTypeParmType(QualType Replacement, + Decl *AssociatedDecl, unsigned Index, + std::optional<unsigned> PackIndex, + bool Final) const; QualType getSubstTemplateTypeParmPackType(Decl *AssociatedDecl, unsigned Index, bool Final, const TemplateArgument &ArgPack); diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 4f33215fd9724..86ae335452980 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2158,12 +2158,15 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { // The index of the template parameter this substitution represents. unsigned Index : 15; + LLVM_PREFERRED_TYPE(bool) + unsigned Final : 1; + /// Represents the index within a pack if this represents a substitution /// from a pack expansion. This index starts at the end of the pack and /// increments towards the beginning. /// Positive non-zero number represents the index + 1. /// Zero means this is not substituted from an expansion. - unsigned PackIndex : 16; + unsigned PackIndex : 15; }; class SubstTemplateTypeParmPackTypeBitfields { @@ -6397,7 +6400,8 @@ class SubstTemplateTypeParmType final Decl *AssociatedDecl; SubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl, - unsigned Index, std::optional<unsigned> PackIndex); + unsigned Index, std::optional<unsigned> PackIndex, + bool Final); public: /// Gets the type that was substituted for the template @@ -6420,6 +6424,10 @@ class SubstTemplateTypeParmType final /// This should match the result of `getReplacedParameter()->getIndex()`. unsigned getIndex() const { return SubstTemplateTypeParmTypeBits.Index; } + // This substitution is Final, which means the substitution is fully + // sugared: it doesn't need to be resugared later. + unsigned getFinal() const { return SubstTemplateTypeParmTypeBits.Final; } + std::optional<unsigned> getPackIndex() const { if (SubstTemplateTypeParmTypeBits.PackIndex == 0) return std::nullopt; @@ -6431,17 +6439,12 @@ class SubstTemplateTypeParmType final void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, getReplacementType(), getAssociatedDecl(), getIndex(), - getPackIndex()); + getPackIndex(), getFinal()); } static void Profile(llvm::FoldingSetNodeID &ID, QualType Replacement, const Decl *AssociatedDecl, unsigned Index, - std::optional<unsigned> PackIndex) { - Replacement.Profile(ID); - ID.AddPointer(AssociatedDecl); - ID.AddInteger(Index); - ID.AddInteger(PackIndex ? *PackIndex - 1 : 0); - } + std::optional<unsigned> PackIndex, bool Final); static bool classof(const Type *T) { return T->getTypeClass() == SubstTemplateTypeParm; diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td index 391fd26a086f7..477106a152188 100644 --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -842,11 +842,11 @@ let Class = SubstTemplateTypeParmType in { def : Property<"PackIndex", Optional<UInt32>> { let Read = [{ node->getPackIndex() }]; } + def : Property<"Final", Bool> { let Read = [{ node->getFinal() }]; } - // The call to getCanonicalType here existed in ASTReader.cpp, too. def : Creator<[{ return ctx.getSubstTemplateTypeParmType( - replacementType, associatedDecl, Index, PackIndex); + replacementType, associatedDecl, Index, PackIndex, Final); }]>; } diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index a012232b38475..0270a8e012849 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -5447,10 +5447,10 @@ QualType ASTContext::getHLSLAttributedResourceType( /// Retrieve a substitution-result type. QualType ASTContext::getSubstTemplateTypeParmType( QualType Replacement, Decl *AssociatedDecl, unsigned Index, - std::optional<unsigned> PackIndex) const { + std::optional<unsigned> PackIndex, bool Final) const { llvm::FoldingSetNodeID ID; SubstTemplateTypeParmType::Profile(ID, Replacement, AssociatedDecl, Index, - PackIndex); + PackIndex, Final); void *InsertPos = nullptr; SubstTemplateTypeParmType *SubstParm = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); @@ -5460,7 +5460,7 @@ QualType ASTContext::getSubstTemplateTypeParmType( !Replacement.isCanonical()), alignof(SubstTemplateTypeParmType)); SubstParm = new (Mem) SubstTemplateTypeParmType(Replacement, AssociatedDecl, - Index, PackIndex); + Index, PackIndex, Final); Types.push_back(SubstParm); SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos); } @@ -14202,7 +14202,8 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X, if (PackIndex != SY->getPackIndex()) return QualType(); return Ctx.getSubstTemplateTypeParmType(Ctx.getQualifiedType(Underlying), - CD, Index, PackIndex); + CD, Index, PackIndex, + SX->getFinal() && SY->getFinal()); } case Type::ObjCTypeParam: // FIXME: Try to merge these. diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 51925ab51e4cd..893160e8f5ba9 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -1631,8 +1631,8 @@ ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmType( return ToReplacementTypeOrErr.takeError(); return Importer.getToContext().getSubstTemplateTypeParmType( - *ToReplacementTypeOrErr, *ReplacedOrErr, T->getIndex(), - T->getPackIndex()); + *ToReplacementTypeOrErr, *ReplacedOrErr, T->getIndex(), T->getPackIndex(), + T->getFinal()); } ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmPackType( diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp index 84847b9081503..d35b2f5d9ab6d 100644 --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -2126,6 +2126,8 @@ void TextNodeDumper::VisitSubstTemplateTypeParmType( VisitTemplateTypeParmDecl(T->getReplacedParameter()); if (auto PackIndex = T->getPackIndex()) OS << " pack_index " << *PackIndex; + if (T->getFinal()) + OS << " final"; } void TextNodeDumper::VisitSubstTemplateTypeParmPackType( diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index 667ffc0e599a6..4669bf5541493 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1294,9 +1294,9 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> { == T->getReplacementType().getAsOpaquePtr()) return QualType(T, 0); - return Ctx.getSubstTemplateTypeParmType(replacementType, - T->getAssociatedDecl(), - T->getIndex(), T->getPackIndex()); + return Ctx.getSubstTemplateTypeParmType( + replacementType, T->getAssociatedDecl(), T->getIndex(), + T->getPackIndex(), T->getFinal()); } // FIXME: Non-trivial to implement, but important for C++ @@ -4263,7 +4263,7 @@ static const TemplateTypeParmDecl *getReplacedParameter(Decl *D, SubstTemplateTypeParmType::SubstTemplateTypeParmType( QualType Replacement, Decl *AssociatedDecl, unsigned Index, - std::optional<unsigned> PackIndex) + std::optional<unsigned> PackIndex, bool Final) : Type(SubstTemplateTypeParm, Replacement.getCanonicalType(), Replacement->getDependence()), AssociatedDecl(AssociatedDecl) { @@ -4273,6 +4273,7 @@ SubstTemplateTypeParmType::SubstTemplateTypeParmType( *getTrailingObjects<QualType>() = Replacement; SubstTemplateTypeParmTypeBits.Index = Index; + SubstTemplateTypeParmTypeBits.Final = Final; SubstTemplateTypeParmTypeBits.PackIndex = PackIndex ? *PackIndex + 1 : 0; assert(AssociatedDecl != nullptr); } @@ -4282,6 +4283,19 @@ SubstTemplateTypeParmType::getReplacedParameter() const { return ::getReplacedParameter(getAssociatedDecl(), getIndex()); } +void SubstTemplateTypeParmType::Profile(llvm::FoldingSetNodeID &ID, + QualType Replacement, + const Decl *AssociatedDecl, + unsigned Index, + std::optional<unsigned> PackIndex, + bool Final) { + Replacement.Profile(ID); + ID.AddPointer(AssociatedDecl); + ID.AddInteger(Index); + ID.AddInteger(PackIndex ? *PackIndex - 1 : 0); + ID.AddBoolean(Final); +} + SubstTemplateTypeParmPackType::SubstTemplateTypeParmPackType( QualType Canon, Decl *AssociatedDecl, unsigned Index, bool Final, const TemplateArgument &ArgPack) diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index 4b9d97cc7d97a..d835b3b06893d 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -2546,13 +2546,9 @@ QualType TemplateInstantiator::BuildSubstTemplateTypeParmType( SemaRef.Context.getQualifiedType(Replacement.getUnqualifiedType(), RQs); } - if (Final) { - TLB.pushTrivial(SemaRef.Context, Replacement, NameLoc); - return Replacement; - } // TODO: only do this uniquing once, at the start of instantiation. QualType Result = getSema().Context.getSubstTemplateTypeParmType( - Replacement, AssociatedDecl, Index, PackIndex); + Replacement, AssociatedDecl, Index, PackIndex, Final); SubstTemplateTypeParmTypeLoc NewTL = TLB.push<SubstTemplateTypeParmTypeLoc>(Result); NewTL.setNameLoc(NameLoc); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index e455b225d7f49..51f361cb46279 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -7076,7 +7076,8 @@ QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmType( return QualType(); QualType Result = SemaRef.Context.getSubstTemplateTypeParmType( - Replacement, NewReplaced, T->getIndex(), T->getPackIndex()); + Replacement, NewReplaced, T->getIndex(), T->getPackIndex(), + T->getFinal()); // Propagate type-source information. SubstTemplateTypeParmTypeLoc NewTL diff --git a/clang/test/AST/ast-dump-template-decls.cpp b/clang/test/AST/ast-dump-template-decls.cpp index 9f578e5afe561..d5228d4667304 100644 --- a/clang/test/AST/ast-dump-template-decls.cpp +++ b/clang/test/AST/ast-dump-template-decls.cpp @@ -123,6 +123,8 @@ using type2 = typename C<int>::type1<void>; // CHECK-NEXT: TemplateArgument type 'void' // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void' // CHECK-NEXT: FunctionProtoType 0x{{[^ ]*}} 'void (int)' cdecl +// CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'void' sugar class depth 0 index 0 U final +// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'type1' // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void' // CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 0 T // CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'C' @@ -139,14 +141,14 @@ template struct D<float, char>::bind<int, short>; // CHECK: TypeAliasDecl 0x{{[^ ]*}} <line:{{[1-9]+}}:5, col:45> col:11 bound_type 'int (int (*)(float, int), int (*)(char, short))' // 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 +// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... T pack_index 1{{$}} // CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'D' -// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar typename depth 0 index 0 ... U pack_index 1 +// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar typename depth 0 index 0 ... U pack_index 1{{$}} // CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'bind' // CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (char, short)' cdecl -// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar typename depth 0 index 0 ... T pack_index 0 +// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar typename depth 0 index 0 ... T pack_index 0{{$}} // CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'D' -// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar typename depth 0 index 0 ... U pack_index 0 +// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar typename depth 0 index 0 ... U pack_index 0{{$}} // CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'bind' } // namespace PR56099 @@ -156,12 +158,16 @@ 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<E, int>':'subst_default_argument::E<int, subst_default_argument::A<int>>' +// CHECK: TypeAliasDecl 0x{{[^ ]*}} <line:{{[0-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 // CHECK-NEXT: |-name: 'A':'subst_default_argument::A' qualified // CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A // CHECK-NEXT: |-TemplateArgument type 'int' -// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int' +// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 0 E1 final +// CHECK-NEXT: | |-ClassTemplate 0x{{[^ ]*}} 'E' +// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 1 D2 final +// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[^ ]*}} 'D' +// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int' // CHECK-NEXT: `-RecordType 0x{{[^ ]*}} 'subst_default_argument::A<int>' // CHECK-NEXT: `-ClassTemplateSpecialization 0x{{[^ ]*}} 'A' } // namespace subst_default_argument diff --git a/clang/test/Misc/diag-template-diffing-cxx11.cpp b/clang/test/Misc/diag-template-diffing-cxx11.cpp index ae4fa524e4e44..c62bffe2b458d 100644 --- a/clang/test/Misc/diag-template-diffing-cxx11.cpp +++ b/clang/test/Misc/diag-template-diffing-cxx11.cpp @@ -265,14 +265,14 @@ int k9 = f9(V9<double>()); // CHECK-ELIDE-TREE: S9< // CHECK-ELIDE-TREE: [2 * ...], // CHECK-ELIDE-TREE: U9< -// CHECK-ELIDE-TREE: [(no qualifiers) != const] double>> +// CHECK-ELIDE-TREE: [double != const double]>> // CHECK-NOELIDE-TREE: no matching function for call to 'f9' // CHECK-NOELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument // CHECK-NOELIDE-TREE: S9< // CHECK-NOELIDE-TREE: int, // CHECK-NOELIDE-TREE: char, // CHECK-NOELIDE-TREE: U9< -// CHECK-NOELIDE-TREE: [(no qualifiers) != const] double>> +// CHECK-NOELIDE-TREE: [double != const double]>> template<typename ...A> class class_types {}; void set10(class_types<int, int>) {} diff --git a/clang/test/SemaTemplate/make_integer_seq.cpp b/clang/test/SemaTemplate/make_integer_seq.cpp index 71e34c5e0e7df..7ca7b55b49964 100644 --- a/clang/test/SemaTemplate/make_integer_seq.cpp +++ b/clang/test/SemaTemplate/make_integer_seq.cpp @@ -48,7 +48,9 @@ using test2 = B<int, 1>; // CHECK-NEXT: |-TemplateArgument template 'A' // CHECK-NEXT: | `-ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:41> col:38 A // CHECK-NEXT: |-TemplateArgument type 'int' -// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int' +// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar class depth 0 index 0 B1 final +// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[0-9A-Fa-f]+}} 'B' +// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int' // CHECK-NEXT: |-TemplateArgument expr '1' // CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:64> 'int' // CHECK-NEXT: | |-value: Int 1 @@ -59,7 +61,9 @@ using test2 = B<int, 1>; // CHECK-NEXT: |-name: 'A' qualified // CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A // CHECK-NEXT: |-TemplateArgument type 'int' -// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int' +// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar class depth 0 index 0 B1 final +// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[0-9A-Fa-f]+}} 'B' +// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int' // CHECK-NEXT: |-TemplateArgument expr '0' // CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:64> 'int' // CHECK-NEXT: | |-value: Int 0 >From 40bf77daca5aacc41bccb12646bf198d0784a312 Mon Sep 17 00:00:00 2001 From: Matheus Izvekov <mizve...@gmail.com> Date: Sun, 23 Mar 2025 17:51:59 -0300 Subject: [PATCH 4/4] Revert "[clang] Add frontend flag to enable support for broken external resugarers (#103219)" This reverts commit 661dda9df13c65ce021407bb726b558c7a414731. --- clang/include/clang/Basic/LangOptions.def | 1 - clang/include/clang/Driver/Options.td | 6 ------ clang/lib/Sema/SemaTemplate.cpp | 12 +++--------- ...subst-template-type-parm-type-ast-nodes.cpp | 18 ------------------ 4 files changed, 3 insertions(+), 34 deletions(-) delete mode 100644 clang/test/AST/ast-dump-retain-subst-template-type-parm-type-ast-nodes.cpp diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def index 3879cc7942877..930c1c06d1a76 100644 --- a/clang/include/clang/Basic/LangOptions.def +++ b/clang/include/clang/Basic/LangOptions.def @@ -161,7 +161,6 @@ LANGOPT(Coroutines , 1, 0, "C++20 coroutines") LANGOPT(CoroAlignedAllocation, 1, 0, "prefer Aligned Allocation according to P2014 Option 2") LANGOPT(DllExportInlines , 1, 1, "dllexported classes dllexport inline methods") LANGOPT(ExperimentalLibrary, 1, 0, "enable unstable and experimental library features") -LANGOPT(RetainSubstTemplateTypeParmTypeAstNodes, 1, 0, "retain SubstTemplateTypeParmType nodes in the AST's representation of alias template specializations") LANGOPT(PointerAuthIntrinsics, 1, 0, "pointer authentication intrinsics") LANGOPT(PointerAuthCalls , 1, 0, "function pointer authentication") diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 89cb03cc33b98..c3ba3a88992c5 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3508,12 +3508,6 @@ defm application_extension : BoolFOption<"application-extension", PosFlag<SetTrue, [], [ClangOption, CC1Option], "Restrict code to those available for App Extensions">, NegFlag<SetFalse>>; -defm retain_subst_template_type_parm_type_ast_nodes : BoolFOption<"retain-subst-template-type-parm-type-ast-nodes", - LangOpts<"RetainSubstTemplateTypeParmTypeAstNodes">, DefaultFalse, - PosFlag<SetTrue, [], [CC1Option], "Enable">, - NegFlag<SetFalse, [], [], "Disable">, - BothFlags<[], [], " retain SubstTemplateTypeParmType nodes in the AST's representation" - " of alias template specializations">>; defm sized_deallocation : BoolFOption<"sized-deallocation", LangOpts<"SizedDeallocation">, Default<cpp14.KeyPath>, PosFlag<SetTrue, [], [], "Enable C++14 sized global deallocation functions">, diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp index f2f49ce347236..85f4234957d9d 100644 --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3531,16 +3531,10 @@ QualType Sema::CheckTemplateIdType(TemplateName Name, if (Pattern->isInvalidDecl()) return QualType(); - // Only substitute for the innermost template argument list. NOTE: Some - // external resugarers rely on leaving a Subst* node here. Make the - // substitution non-final in that case. Note that these external resugarers - // will still miss some information in this representation, because we don't - // provide enough context in the Subst* nodes in order to tell different - // template type alias specializations apart. + // Only substitute for the innermost template argument list. MultiLevelTemplateArgumentList TemplateArgLists; - TemplateArgLists.addOuterTemplateArguments( - Template, CTAI.SugaredConverted, - /*Final=*/!getLangOpts().RetainSubstTemplateTypeParmTypeAstNodes); + TemplateArgLists.addOuterTemplateArguments(Template, CTAI.SugaredConverted, + /*Final=*/true); TemplateArgLists.addOuterRetainedLevels( AliasTemplate->getTemplateParameters()->getDepth()); diff --git a/clang/test/AST/ast-dump-retain-subst-template-type-parm-type-ast-nodes.cpp b/clang/test/AST/ast-dump-retain-subst-template-type-parm-type-ast-nodes.cpp deleted file mode 100644 index 97dc983e2436c..0000000000000 --- a/clang/test/AST/ast-dump-retain-subst-template-type-parm-type-ast-nodes.cpp +++ /dev/null @@ -1,18 +0,0 @@ -// RUN: %clang_cc1 -fsyntax-only -fretain-subst-template-type-parm-type-ast-nodes -ast-dump -ast-dump-filter=dump %s | FileCheck -strict-whitespace %s - -namespace t1 { -template<class T> using X = T; -using dump = X<int>; - -// CHECK-LABEL: Dumping t1::dump: -// CHECK-NEXT: TypeAliasDecl -// CHECK-NEXT: `-ElaboratedType -// CHECK-NEXT: `-TemplateSpecializationType -// CHECK-NEXT: |-name: 'X':'t1::X' qualified -// CHECK-NEXT: | `-TypeAliasTemplateDecl -// CHECK-NEXT: |-TemplateArgument -// CHECK-NEXT: | `-BuiltinType {{.+}} 'int' -// CHECK-NEXT: `-SubstTemplateTypeParmType 0x{{[0-9a-f]+}} 'int' sugar class depth 0 index 0 T -// CHECK-NEXT: |-TypeAliasTemplate {{.+}} 'X' -// CHECK-NEXT: `-BuiltinType {{.+}} 'int' -} // namespace t1 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits