diff --git a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp --- a/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp +++ b/clang-tools-extra/clang-tidy/hicpp/ExceptionBaseclassCheck.cpp @@ -52,7 +52,7 @@ diag(BadThrow->getSubExpr()->getBeginLoc(), "type %0 is a template instantiation of %1", DiagnosticIDs::Note) << BadThrow->getSubExpr()->getType() - << Template->getReplacedParameter()->getDecl(); + << Template->getReplacedParameter(); if (const auto *TypeDecl = Result.Nodes.getNodeAs("decl")) diag(TypeDecl->getBeginLoc(), "type defined here", DiagnosticIDs::Note); diff --git a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp --- a/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp +++ b/clang-tools-extra/clang-tidy/performance/UnnecessaryCopyInitialization.cpp @@ -191,12 +191,12 @@ getSubstitutedType(VarType, Context)) { if (const SubstTemplateTypeParmType *InitializerTmplType = getSubstitutedType(InitializerType, Context)) { - return VarTmplType->getReplacedParameter() - ->desugar() - .getCanonicalType() != - InitializerTmplType->getReplacedParameter() - ->desugar() - .getCanonicalType(); + const TemplateTypeParmDecl *VarTTP = VarTmplType->getReplacedParameter(); + const TemplateTypeParmDecl *InitTTP = + InitializerTmplType->getReplacedParameter(); + return (VarTTP->getDepth() != InitTTP->getDepth() || + VarTTP->getIndex() != InitTTP->getIndex() || + VarTTP->isParameterPack() != InitTTP->isParameterPack()); } } return false; diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp --- a/clang-tools-extra/clangd/AST.cpp +++ b/clang-tools-extra/clangd/AST.cpp @@ -727,8 +727,8 @@ if (const auto *SubstType = dyn_cast(PlainType)) { const auto *ReplacedParameter = SubstType->getReplacedParameter(); if (ReplacedParameter->isParameterPack()) { - return dyn_cast( - ReplacedParameter->getCanonicalTypeUnqualified()->getTypePtr()); + return ReplacedParameter->getTypeForDecl() + ->castAs(); } } return nullptr; diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1614,11 +1614,10 @@ QualType getBTFTagAttributedType(const BTFTypeTagAttr *BTFAttr, QualType Wrapped); - QualType getSubstTemplateTypeParmType(const TemplateTypeParmType *Replaced, - QualType Replacement, + QualType getSubstTemplateTypeParmType(QualType Replacement, + Decl *ReplacedDecl, unsigned Index, Optional PackIndex) const; - QualType getSubstTemplateTypeParmPackType( - const TemplateTypeParmType *Replaced, + QualType getSubstTemplateTypeParmPackType(Decl *ReplacedDecl, unsigned Index, const TemplateArgument &ArgPack); QualType diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -389,12 +389,9 @@ void VisitBTFTagAttributedType(const BTFTagAttributedType *T) { Visit(T->getWrappedType()); } - void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { - Visit(T->getReplacedParameter()); - } + void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *) {} void VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) { - Visit(T->getReplacedParameter()); Visit(T->getArgumentPack()); } void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { diff --git a/clang/include/clang/AST/JSONNodeDumper.h b/clang/include/clang/AST/JSONNodeDumper.h --- a/clang/include/clang/AST/JSONNodeDumper.h +++ b/clang/include/clang/AST/JSONNodeDumper.h @@ -221,6 +221,8 @@ void VisitTagType(const TagType *TT); void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT); void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *STTPT); + void + VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T); void VisitAutoType(const AutoType *AT); void VisitTemplateSpecializationType(const TemplateSpecializationType *TST); void VisitInjectedClassNameType(const InjectedClassNameType *ICNT); diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h --- a/clang/include/clang/AST/TextNodeDumper.h +++ b/clang/include/clang/AST/TextNodeDumper.h @@ -318,6 +318,8 @@ void VisitTagType(const TagType *T); void VisitTemplateTypeParmType(const TemplateTypeParmType *T); void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T); + void + VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T); void VisitAutoType(const AutoType *T); void VisitDeducedTemplateSpecializationType( const DeducedTemplateSpecializationType *T); diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -1790,16 +1790,37 @@ unsigned NumArgs; }; + class UsingBitfields { + friend class UsingType; + + unsigned : NumTypeBits; + + /// True if this UsingType has underlying type different from decl. + unsigned hasDifferentUnderlyingType : 1; + }; + + class TypedefBitfields { + friend class TypedefType; + + unsigned : NumTypeBits; + + /// True if this typedef has underlying type different from decl. + unsigned hasDifferentUnderlyingType : 1; + }; + class SubstTemplateTypeParmTypeBitfields { friend class SubstTemplateTypeParmType; unsigned : NumTypeBits; + // The index of the template parameter this substitution represents. + unsigned Index : 16; + /// Represents the index within a pack if this represents a substitution /// from a pack expansion. /// Positive non-zero number represents the index + 1. /// Zero means this is not substituted from an expansion. - unsigned PackIndex; + unsigned PackIndex : 16; }; class SubstTemplateTypeParmPackTypeBitfields { @@ -1807,14 +1828,14 @@ unsigned : NumTypeBits; + // The index of the template parameter this substitution represents. + unsigned Index : 16; + /// The number of template arguments in \c Arguments, which is /// expected to be able to hold at least 1024 according to [implimits]. /// However as this limit is somewhat easy to hit with template /// metaprogramming we'd prefer to keep it as large as possible. - /// At the moment it has been left as a non-bitfield since this type - /// safely fits in 64 bits as an unsigned, so there is no reason to - /// introduce the performance impact of a bitfield. - unsigned NumArgs; + unsigned NumArgs : 16; }; class TemplateSpecializationTypeBitfields { @@ -4984,26 +5005,25 @@ friend class ASTContext; // The original type parameter. - const TemplateTypeParmType *Replaced; + QualType Replacement; - SubstTemplateTypeParmType(const TemplateTypeParmType *Param, QualType Canon, - Optional PackIndex) - : Type(SubstTemplateTypeParm, Canon, Canon->getDependence()), - Replaced(Param) { - SubstTemplateTypeParmTypeBits.PackIndex = PackIndex ? *PackIndex + 1 : 0; - } + // The templated entity which owned the substituted type parameter. + Decl *ReplacedDecl; -public: - /// Gets the template parameter that was substituted for. - const TemplateTypeParmType *getReplacedParameter() const { - return Replaced; - } + SubstTemplateTypeParmType(QualType Replacement, Decl *ReplacedDecl, + unsigned Index, Optional PackIndex); +public: /// Gets the type that was substituted for the template /// parameter. - QualType getReplacementType() const { - return getCanonicalTypeInternal(); - } + QualType getReplacementType() const { return Replacement; } + + /// Gets the template specialization that was substituted. + Decl *getReplacedDecl() const { return ReplacedDecl; } + + const TemplateTypeParmDecl *getReplacedParameter() const; + + unsigned getIndex() const { return SubstTemplateTypeParmTypeBits.Index; } Optional getPackIndex() const { if (SubstTemplateTypeParmTypeBits.PackIndex == 0) @@ -5015,14 +5035,16 @@ QualType desugar() const { return getReplacementType(); } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getReplacedParameter(), getReplacementType(), getPackIndex()); + Profile(ID, getReplacementType(), getReplacedDecl(), getIndex(), + getPackIndex()); } - static void Profile(llvm::FoldingSetNodeID &ID, - const TemplateTypeParmType *Replaced, - QualType Replacement, Optional PackIndex) { - ID.AddPointer(Replaced); + static void Profile(llvm::FoldingSetNodeID &ID, QualType Replacement, + const Decl *ReplacedDecl, unsigned Index, + Optional PackIndex) { + ID.AddPointer(ReplacedDecl); ID.AddPointer(Replacement.getAsOpaquePtr()); + ID.AddInteger(Index); ID.AddInteger(PackIndex ? *PackIndex - 1 : 0); } @@ -5046,24 +5068,26 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode { friend class ASTContext; - /// The original type parameter. - const TemplateTypeParmType *Replaced; - /// A pointer to the set of template arguments that this /// parameter pack is instantiated with. const TemplateArgument *Arguments; - SubstTemplateTypeParmPackType(const TemplateTypeParmType *Param, - QualType Canon, + // The template specialization which owned the substituted type parameter. + Decl *ReplacedDecl; + + SubstTemplateTypeParmPackType(QualType Canon, Decl *ReplacedDecl, + unsigned Index, const TemplateArgument &ArgPack); public: - IdentifierInfo *getIdentifier() const { return Replaced->getIdentifier(); } + IdentifierInfo *getIdentifier() const; - /// Gets the template parameter that was substituted for. - const TemplateTypeParmType *getReplacedParameter() const { - return Replaced; - } + /// Gets the template specialization that was substituted. + Decl *getReplacedDecl() const { return ReplacedDecl; } + + const TemplateTypeParmDecl *getReplacedParameter() const; + + unsigned getIndex() const { return SubstTemplateTypeParmPackTypeBits.Index; } unsigned getNumArgs() const { return SubstTemplateTypeParmPackTypeBits.NumArgs; @@ -5075,9 +5099,8 @@ TemplateArgument getArgumentPack() const; void Profile(llvm::FoldingSetNodeID &ID); - static void Profile(llvm::FoldingSetNodeID &ID, - const TemplateTypeParmType *Replaced, - const TemplateArgument &ArgPack); + static void Profile(llvm::FoldingSetNodeID &ID, const Decl *ReplacedDecl, + unsigned Index, const TemplateArgument &ArgPack); static bool classof(const Type *T) { return T->getTypeClass() == SubstTemplateTypeParmPack; diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td --- a/clang/include/clang/AST/TypeProperties.td +++ b/clang/include/clang/AST/TypeProperties.td @@ -728,21 +728,22 @@ } let Class = SubstTemplateTypeParmType in { - def : Property<"replacedParameter", QualType> { - let Read = [{ QualType(node->getReplacedParameter(), 0) }]; - } def : Property<"replacementType", QualType> { let Read = [{ node->getReplacementType() }]; } + def : Property<"replacedDecl", DeclRef> { + let Read = [{ node->getReplacedDecl() }]; + } + def : Property<"Index", UInt32> { + let Read = [{ node->getIndex() }]; + } def : Property<"PackIndex", Optional> { let Read = [{ node->getPackIndex() }]; } def : Creator<[{ - // The call to getCanonicalType here existed in ASTReader.cpp, too. return ctx.getSubstTemplateTypeParmType( - cast(replacedParameter), - ctx.getCanonicalType(replacementType), PackIndex); + replacementType, replacedDecl, Index, PackIndex); }]>; } @@ -761,8 +762,11 @@ } let Class = SubstTemplateTypeParmPackType in { - def : Property<"replacedParameter", QualType> { - let Read = [{ QualType(node->getReplacedParameter(), 0) }]; + def : Property<"replacedDecl", DeclRef> { + let Read = [{ node->getReplacedDecl() }]; + } + def : Property<"Index", UInt32> { + let Read = [{ node->getIndex() }]; } def : Property<"replacementPack", TemplateArgument> { let Read = [{ node->getArgumentPack() }]; @@ -770,8 +774,7 @@ def : Creator<[{ return ctx.getSubstTemplateTypeParmPackType( - cast(replacedParameter), - replacementPack); + replacedDecl, Index, replacementPack); }]>; } diff --git a/clang/include/clang/Sema/Template.h b/clang/include/clang/Sema/Template.h --- a/clang/include/clang/Sema/Template.h +++ b/clang/include/clang/Sema/Template.h @@ -74,13 +74,20 @@ /// template argument list (17) at depth 1. class MultiLevelTemplateArgumentList { /// The template argument list at a certain template depth + using ArgList = ArrayRef; - using ArgListsIterator = SmallVector::iterator; - using ConstArgListsIterator = SmallVector::const_iterator; + struct ArgumentListLevel { + Decl *ReplacedDecl; + ArgList Args; + }; + using ContainerType = SmallVector; + + using ArgListsIterator = ContainerType::iterator; + using ConstArgListsIterator = ContainerType::const_iterator; /// The template argument lists, stored from the innermost template /// argument list (first) to the outermost template argument list (last). - SmallVector TemplateArgumentLists; + ContainerType TemplateArgumentLists; /// The number of outer levels of template arguments that are not /// being substituted. @@ -94,9 +101,8 @@ MultiLevelTemplateArgumentList() = default; /// Construct a single-level template argument list. - explicit - MultiLevelTemplateArgumentList(const TemplateArgumentList &TemplateArgs) { - addOuterTemplateArguments(&TemplateArgs); + explicit MultiLevelTemplateArgumentList(Decl *D, ArgList Args) { + addOuterTemplateArguments(D, Args); } void setKind(TemplateSubstitutionKind K) { Kind = K; } @@ -126,7 +132,7 @@ // Determine the number of substituted args at 'Depth'. unsigned getNumSubsitutedArgs(unsigned Depth) const { assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); - return TemplateArgumentLists[getNumLevels() - Depth - 1].size(); + return TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size(); } unsigned getNumRetainedOuterLevels() const { @@ -146,8 +152,14 @@ /// Retrieve the template argument at a given depth and index. const TemplateArgument &operator()(unsigned Depth, unsigned Index) const { assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); - assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); - return TemplateArgumentLists[getNumLevels() - Depth - 1][Index]; + assert(Index < + TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size()); + return TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index]; + } + + Decl *getReplacedDecl(unsigned Depth) const { + assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); + return TemplateArgumentLists[getNumLevels() - Depth - 1].ReplacedDecl; } /// Determine whether there is a non-NULL template argument at the @@ -160,15 +172,16 @@ if (Depth < NumRetainedOuterLevels) return false; - if (Index >= TemplateArgumentLists[getNumLevels() - Depth - 1].size()) + if (Index >= + TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size()) return false; return !(*this)(Depth, Index).isNull(); } bool isAnyArgInstantiationDependent() const { - for (ArgList List : TemplateArgumentLists) - for (const TemplateArgument &TA : List) + for (ArgumentListLevel ListLevel : TemplateArgumentLists) + for (const TemplateArgument &TA : ListLevel.Args) if (TA.isInstantiationDependent()) return true; return false; @@ -178,25 +191,34 @@ void setArgument(unsigned Depth, unsigned Index, TemplateArgument Arg) { assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels()); - assert(Index < TemplateArgumentLists[getNumLevels() - Depth - 1].size()); - const_cast( - TemplateArgumentLists[getNumLevels() - Depth - 1][Index]) - = Arg; + assert(Index < + TemplateArgumentLists[getNumLevels() - Depth - 1].Args.size()); + const_cast( + TemplateArgumentLists[getNumLevels() - Depth - 1].Args[Index]) = Arg; } - /// Add a new outermost level to the multi-level template argument + /// Add a new outmost level to the multi-level template argument /// list. - void addOuterTemplateArguments(const TemplateArgumentList *TemplateArgs) { - addOuterTemplateArguments(ArgList(TemplateArgs->data(), - TemplateArgs->size())); + void addOuterTemplateArguments(Decl *ReplacedDecl, ArgList Args) { + assert(!NumRetainedOuterLevels && + "substituted args outside retained args?"); + assert(getKind() == TemplateSubstitutionKind::Specialization); + assert(ReplacedDecl != nullptr || Args.size() == 0); + TemplateArgumentLists.push_back( + {ReplacedDecl ? ReplacedDecl->getCanonicalDecl() : nullptr, Args}); } - /// Add a new outmost level to the multi-level template argument - /// list. void addOuterTemplateArguments(ArgList Args) { assert(!NumRetainedOuterLevels && "substituted args outside retained args?"); - TemplateArgumentLists.push_back(Args); + assert(getKind() == TemplateSubstitutionKind::Rewrite); + TemplateArgumentLists.push_back({nullptr, Args}); + } + + void addOuterTemplateArguments(llvm::NoneType) { + assert(!NumRetainedOuterLevels && + "substituted args outside retained args?"); + TemplateArgumentLists.push_back({}); } /// Replaces the current 'innermost' level with the provided argument list. @@ -204,7 +226,7 @@ /// list from the AST, but then add the deduced innermost list. void replaceInnermostTemplateArguments(ArgList Args) { assert(TemplateArgumentLists.size() > 0 && "Replacing in an empty list?"); - TemplateArgumentLists[0] = Args; + TemplateArgumentLists[0].Args = Args; } /// Add an outermost level that we are not substituting. We have no @@ -219,11 +241,11 @@ /// Retrieve the innermost template argument list. const ArgList &getInnermost() const { - return TemplateArgumentLists.front(); + return TemplateArgumentLists.front().Args; } /// Retrieve the outermost template argument list. const ArgList &getOutermost() const { - return TemplateArgumentLists.back(); + return TemplateArgumentLists.back().Args; } ArgListsIterator begin() { return TemplateArgumentLists.begin(); } ConstArgListsIterator begin() const { diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -4747,21 +4747,19 @@ /// Retrieve a substitution-result type. QualType -ASTContext::getSubstTemplateTypeParmType(const TemplateTypeParmType *Parm, - QualType Replacement, +ASTContext::getSubstTemplateTypeParmType(QualType Replacement, + Decl *ReplacedDecl, unsigned Index, Optional PackIndex) const { - assert(Replacement.isCanonical() - && "replacement types must always be canonical"); - llvm::FoldingSetNodeID ID; - SubstTemplateTypeParmType::Profile(ID, Parm, Replacement, PackIndex); + SubstTemplateTypeParmType::Profile(ID, Replacement, ReplacedDecl, Index, + PackIndex); void *InsertPos = nullptr; - SubstTemplateTypeParmType *SubstParm - = SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); + SubstTemplateTypeParmType *SubstParm = + SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos); if (!SubstParm) { SubstParm = new (*this, TypeAlignment) - SubstTemplateTypeParmType(Parm, Replacement, PackIndex); + SubstTemplateTypeParmType(Replacement, ReplacedDecl, Index, PackIndex); Types.push_back(SubstParm); SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos); } @@ -4770,34 +4768,32 @@ } /// Retrieve a -QualType ASTContext::getSubstTemplateTypeParmPackType( - const TemplateTypeParmType *Parm, - const TemplateArgument &ArgPack) { +QualType +ASTContext::getSubstTemplateTypeParmPackType(Decl *ReplacedDecl, unsigned Index, + const TemplateArgument &ArgPack) { #ifndef NDEBUG for (const auto &P : ArgPack.pack_elements()) { - assert(P.getKind() == TemplateArgument::Type &&"Pack contains a non-type"); + assert(P.getKind() == TemplateArgument::Type && "Pack contains a non-type"); assert(P.getAsType().isCanonical() && "Pack contains non-canonical type"); } #endif llvm::FoldingSetNodeID ID; - SubstTemplateTypeParmPackType::Profile(ID, Parm, ArgPack); + SubstTemplateTypeParmPackType::Profile(ID, ReplacedDecl, Index, ArgPack); void *InsertPos = nullptr; - if (SubstTemplateTypeParmPackType *SubstParm - = SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos)) + if (SubstTemplateTypeParmPackType *SubstParm = + SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos)) return QualType(SubstParm, 0); QualType Canon; - if (!Parm->isCanonicalUnqualified()) { - Canon = getCanonicalType(QualType(Parm, 0)); - Canon = getSubstTemplateTypeParmPackType(cast(Canon), - ArgPack); + if (!ReplacedDecl->isCanonicalDecl()) { + Canon = getSubstTemplateTypeParmPackType(ReplacedDecl->getCanonicalDecl(), + Index, ArgPack); SubstTemplateTypeParmPackTypes.FindNodeOrInsertPos(ID, InsertPos); } - auto *SubstParm - = new (*this, TypeAlignment) SubstTemplateTypeParmPackType(Parm, Canon, - ArgPack); + auto *SubstParm = new (*this, TypeAlignment) + SubstTemplateTypeParmPackType(Canon, ReplacedDecl, Index, ArgPack); Types.push_back(SubstParm); SubstTemplateTypeParmPackTypes.InsertNode(SubstParm, InsertPos); return QualType(SubstParm, 0); @@ -12777,16 +12773,15 @@ case Type::SubstTemplateTypeParm: { const auto *SX = cast(X), *SY = cast(Y); + unsigned Index = SX->getIndex(); auto PackIndex = SX->getPackIndex(); - if (PackIndex != SY->getPackIndex()) + if (Index != SY->getIndex() || PackIndex != SY->getPackIndex()) return QualType(); - - const TemplateTypeParmType *PX = SX->getReplacedParameter(); - if (PX != SY->getReplacedParameter()) + Decl *CD = ::getCommonDecl(SX->getReplacedDecl(), SY->getReplacedDecl()); + if (!CD) return QualType(); - - return Ctx.getSubstTemplateTypeParmType( - PX, Ctx.getQualifiedType(Underlying), PackIndex); + return Ctx.getSubstTemplateTypeParmType(Ctx.getQualifiedType(Underlying), + CD, Index, PackIndex); } case Type::ObjCTypeParam: // FIXME: Try to merge these. diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -1520,8 +1520,7 @@ ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmType( const SubstTemplateTypeParmType *T) { - Expected ReplacedOrErr = - import(T->getReplacedParameter()); + Expected ReplacedOrErr = import(T->getReplacedDecl()); if (!ReplacedOrErr) return ReplacedOrErr.takeError(); @@ -1530,14 +1529,13 @@ return ToReplacementTypeOrErr.takeError(); return Importer.getToContext().getSubstTemplateTypeParmType( - *ReplacedOrErr, ToReplacementTypeOrErr->getCanonicalType(), + *ToReplacementTypeOrErr, *ReplacedOrErr, T->getIndex(), T->getPackIndex()); } ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmPackType( const SubstTemplateTypeParmPackType *T) { - Expected ReplacedOrErr = - import(T->getReplacedParameter()); + Expected ReplacedOrErr = import(T->getReplacedDecl()); if (!ReplacedOrErr) return ReplacedOrErr.takeError(); @@ -1546,7 +1544,7 @@ return ToArgumentPack.takeError(); return Importer.getToContext().getSubstTemplateTypeParmPackType( - *ReplacedOrErr, *ToArgumentPack); + *ReplacedOrErr, T->getIndex(), *ToArgumentPack); } ExpectedType ASTNodeImporter::VisitTemplateSpecializationType( @@ -3747,6 +3745,10 @@ } } + // If it is a template, import all related things. + if (Error Err = ImportTemplateInformation(D, ToFunction)) + return std::move(Err); + if (D->doesThisDeclarationHaveABody()) { Error Err = ImportFunctionDeclBody(D, ToFunction); @@ -3768,10 +3770,6 @@ // FIXME: Other bits to merge? - // If it is a template, import all related things. - if (Error Err = ImportTemplateInformation(D, ToFunction)) - return std::move(Err); - addDeclToContexts(D, ToFunction); if (auto *FromCXXMethod = dyn_cast(D)) @@ -5991,6 +5989,30 @@ D2->setTemplateSpecializationKind(D->getTemplateSpecializationKind()); + if (auto P = D->getInstantiatedFrom()) { + if (auto *CTD = P.dyn_cast()) { + if (auto CTDorErr = import(CTD)) + D2->setInstantiationOf(*CTDorErr); + } else { + auto *CTPSD = cast(P); + auto CTPSDOrErr = import(CTPSD); + if (!CTPSDOrErr) + return CTPSDOrErr.takeError(); + const TemplateArgumentList &DArgs = D->getTemplateInstantiationArgs(); + SmallVector D2ArgsVec(DArgs.size()); + for (unsigned I = 0; I < DArgs.size(); ++I) { + const TemplateArgument &DArg = DArgs[I]; + if (auto ArgOrErr = import(DArg)) + D2ArgsVec[I] = *ArgOrErr; + else + return ArgOrErr.takeError(); + } + D2->setInstantiationOf( + *CTPSDOrErr, + TemplateArgumentList::CreateCopy(Importer.getToContext(), D2ArgsVec)); + } + } + if (D->isCompleteDefinition()) if (Error Err = ImportDefinition(D, D2)) return std::move(Err); @@ -6154,15 +6176,6 @@ } } } else { - // Import the type. - QualType T; - if (Error Err = importInto(T, D->getType())) - return std::move(Err); - - auto TInfoOrErr = import(D->getTypeSourceInfo()); - if (!TInfoOrErr) - return TInfoOrErr.takeError(); - TemplateArgumentListInfo ToTAInfo; if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo()) { if (Error Err = ImportTemplateArgumentListInfo(*Args, ToTAInfo)) @@ -6187,7 +6200,7 @@ PartVarSpecDecl *ToPartial; if (GetImportedOrCreateDecl(ToPartial, D, Importer.getToContext(), DC, *BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr, - VarTemplate, T, *TInfoOrErr, + VarTemplate, QualType(), nullptr, D->getStorageClass(), TemplateArgs, ArgInfos)) return ToPartial; @@ -6208,11 +6221,21 @@ } else { // Full specialization if (GetImportedOrCreateDecl(D2, D, Importer.getToContext(), DC, *BeginLocOrErr, *IdLocOrErr, VarTemplate, - T, *TInfoOrErr, - D->getStorageClass(), TemplateArgs)) + QualType(), nullptr, D->getStorageClass(), + TemplateArgs)) return D2; } + QualType T; + if (Error Err = importInto(T, D->getType())) + return std::move(Err); + D2->setType(T); + + auto TInfoOrErr = import(D->getTypeSourceInfo()); + if (!TInfoOrErr) + return TInfoOrErr.takeError(); + D2->setTypeSourceInfo(*TInfoOrErr); + if (D->getPointOfInstantiation().isValid()) { if (ExpectedSLoc POIOrErr = import(D->getPointOfInstantiation())) D2->setPointOfInstantiation(*POIOrErr); diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp --- a/clang/lib/AST/ASTStructuralEquivalence.cpp +++ b/clang/lib/AST/ASTStructuralEquivalence.cpp @@ -1055,13 +1055,13 @@ case Type::SubstTemplateTypeParm: { const auto *Subst1 = cast(T1); const auto *Subst2 = cast(T2); - if (!IsStructurallyEquivalent(Context, - QualType(Subst1->getReplacedParameter(), 0), - QualType(Subst2->getReplacedParameter(), 0))) - return false; if (!IsStructurallyEquivalent(Context, Subst1->getReplacementType(), Subst2->getReplacementType())) return false; + if (Subst1->getReplacedDecl() != Subst2->getReplacedDecl()) + return false; + if (Subst1->getIndex() != Subst2->getIndex()) + return false; if (Subst1->getPackIndex() != Subst2->getPackIndex()) return false; break; @@ -1070,9 +1070,9 @@ case Type::SubstTemplateTypeParmPack: { const auto *Subst1 = cast(T1); const auto *Subst2 = cast(T2); - if (!IsStructurallyEquivalent(Context, - QualType(Subst1->getReplacedParameter(), 0), - QualType(Subst2->getReplacedParameter(), 0))) + if (Subst1->getReplacedDecl() != Subst2->getReplacedDecl()) + return false; + if (Subst1->getIndex() != Subst2->getIndex()) return false; if (!IsStructurallyEquivalent(Context, Subst1->getArgumentPack(), Subst2->getArgumentPack())) diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp --- a/clang/lib/AST/JSONNodeDumper.cpp +++ b/clang/lib/AST/JSONNodeDumper.cpp @@ -682,10 +682,16 @@ void JSONNodeDumper::VisitSubstTemplateTypeParmType( const SubstTemplateTypeParmType *STTPT) { + JOS.attribute("index", STTPT->getIndex()); if (auto PackIndex = STTPT->getPackIndex()) JOS.attribute("pack_index", *PackIndex); } +void JSONNodeDumper::VisitSubstTemplateTypeParmPackType( + const SubstTemplateTypeParmPackType *T) { + JOS.attribute("index", T->getIndex()); +} + void JSONNodeDumper::VisitAutoType(const AutoType *AT) { JOS.attribute("undeduced", !AT->isDeduced()); switch (AT->getKeyword()) { diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp --- a/clang/lib/AST/ODRHash.cpp +++ b/clang/lib/AST/ODRHash.cpp @@ -671,7 +671,7 @@ } } - void AddDecl(Decl *D) { + void AddDecl(const Decl *D) { Hash.AddBoolean(D); if (D) { Hash.AddDecl(D); @@ -995,13 +995,13 @@ void VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) { - AddType(T->getReplacedParameter()); + AddDecl(T->getReplacedDecl()); Hash.AddTemplateArgument(T->getArgumentPack()); VisitType(T); } void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { - AddType(T->getReplacedParameter()); + AddDecl(T->getReplacedDecl()); AddQualType(T->getReplacementType()); VisitType(T); } diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp --- a/clang/lib/AST/TextNodeDumper.cpp +++ b/clang/lib/AST/TextNodeDumper.cpp @@ -1570,10 +1570,18 @@ void TextNodeDumper::VisitSubstTemplateTypeParmType( const SubstTemplateTypeParmType *T) { + dumpDeclRef(T->getReplacedDecl()); + VisitTemplateTypeParmDecl(T->getReplacedParameter()); if (auto PackIndex = T->getPackIndex()) OS << " pack_index " << *PackIndex; } +void TextNodeDumper::VisitSubstTemplateTypeParmPackType( + const SubstTemplateTypeParmPackType *T) { + dumpDeclRef(T->getReplacedDecl()); + VisitTemplateTypeParmDecl(T->getReplacedParameter()); +} + void TextNodeDumper::VisitAutoType(const AutoType *T) { if (T->isDecltypeAuto()) OS << " decltype(auto)"; diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -1166,8 +1166,9 @@ == T->getReplacementType().getAsOpaquePtr()) return QualType(T, 0); - return Ctx.getSubstTemplateTypeParmType(T->getReplacedParameter(), - replacementType, T->getPackIndex()); + return Ctx.getSubstTemplateTypeParmType(replacementType, + T->getReplacedDecl(), T->getIndex(), + T->getPackIndex()); } // FIXME: Non-trivial to implement, but important for C++ @@ -3649,14 +3650,104 @@ return isCanonicalUnqualified() ? nullptr : getDecl()->getIdentifier(); } +static const TemplateParameterList * +getReplacedTemplateParameterList(const Decl *D) { + switch (D->getKind()) { + case Decl::Kind::ClassTemplate: + return cast(D)->getTemplateParameters(); + case Decl::Kind::ClassTemplateSpecialization: { + const auto *CTSD = cast(D); + auto P = CTSD->getSpecializedTemplateOrPartial(); + if (const auto *CTPSD = + P.dyn_cast()) + return CTPSD->getTemplateParameters(); + return cast(P)->getTemplateParameters(); + } + case Decl::Kind::ClassTemplatePartialSpecialization: + return cast(D) + ->getTemplateParameters(); + case Decl::Kind::TypeAliasTemplate: + return cast(D)->getTemplateParameters(); + case Decl::Kind::BuiltinTemplate: + return cast(D)->getTemplateParameters(); + case Decl::Kind::CXXConversion: + case Decl::Kind::CXXConstructor: + case Decl::Kind::CXXDestructor: + case Decl::Kind::CXXMethod: + case Decl::Kind::Function: + return cast(D) + ->getTemplateSpecializationInfo() + ->getTemplate() + ->getTemplateParameters(); + case Decl::Kind::FunctionTemplate: + return cast(D)->getTemplateParameters(); + case Decl::Kind::VarTemplate: + return cast(D)->getTemplateParameters(); + case Decl::Kind::VarTemplateSpecialization: { + const auto *VTSD = cast(D); + auto P = VTSD->getSpecializedTemplateOrPartial(); + if (const auto *VTPSD = + P.dyn_cast()) + return VTPSD->getTemplateParameters(); + return cast(P)->getTemplateParameters(); + } + case Decl::Kind::VarTemplatePartialSpecialization: + return cast(D) + ->getTemplateParameters(); + case Decl::Kind::TemplateTemplateParm: + return cast(D)->getTemplateParameters(); + case Decl::Kind::Concept: + return cast(D)->getTemplateParameters(); + default: + llvm_unreachable("Unhandled templated declaration kind"); + } +} + +static const TemplateTypeParmDecl *getReplacedParameter(const Decl *D, + unsigned Index) { + if (const auto *TTP = dyn_cast(D)) + return TTP; + return cast( + getReplacedTemplateParameterList(D)->getParam(Index)); +} + +SubstTemplateTypeParmType::SubstTemplateTypeParmType( + QualType Replacement, Decl *ReplacedDecl, unsigned Index, + Optional PackIndex) + : Type(SubstTemplateTypeParm, Replacement.getCanonicalType(), + Replacement->getDependence()), + Replacement(Replacement), ReplacedDecl(ReplacedDecl) { + SubstTemplateTypeParmTypeBits.Index = Index; + SubstTemplateTypeParmTypeBits.PackIndex = PackIndex ? *PackIndex + 1 : 0; + assert(ReplacedDecl != nullptr); + assert(getReplacedParameter() != nullptr); +} + +const TemplateTypeParmDecl * +SubstTemplateTypeParmType::getReplacedParameter() const { + return ::getReplacedParameter(getReplacedDecl(), getIndex()); +} + SubstTemplateTypeParmPackType::SubstTemplateTypeParmPackType( - const TemplateTypeParmType *Param, QualType Canon, + QualType Canon, Decl *ReplacedDecl, unsigned Index, const TemplateArgument &ArgPack) : Type(SubstTemplateTypeParmPack, Canon, TypeDependence::DependentInstantiation | TypeDependence::UnexpandedPack), - Replaced(Param), Arguments(ArgPack.pack_begin()) { + Arguments(ArgPack.pack_begin()), ReplacedDecl(ReplacedDecl) { + SubstTemplateTypeParmPackTypeBits.Index = Index; SubstTemplateTypeParmPackTypeBits.NumArgs = ArgPack.pack_size(); + assert(ReplacedDecl != nullptr); + assert(getReplacedParameter() != nullptr); +} + +const TemplateTypeParmDecl * +SubstTemplateTypeParmPackType::getReplacedParameter() const { + return ::getReplacedParameter(getReplacedDecl(), getIndex()); +} + +IdentifierInfo *SubstTemplateTypeParmPackType::getIdentifier() const { + return getReplacedParameter()->getIdentifier(); } TemplateArgument SubstTemplateTypeParmPackType::getArgumentPack() const { @@ -3664,13 +3755,15 @@ } void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getReplacedParameter(), getArgumentPack()); + Profile(ID, getReplacedDecl(), getIndex(), getArgumentPack()); } void SubstTemplateTypeParmPackType::Profile(llvm::FoldingSetNodeID &ID, - const TemplateTypeParmType *Replaced, + const Decl *ReplacedDecl, + unsigned Index, const TemplateArgument &ArgPack) { - ID.AddPointer(Replaced); + ID.AddPointer(ReplacedDecl); + ID.AddInteger(Index); ID.AddInteger(ArgPack.pack_size()); for (const auto &P : ArgPack.pack_elements()) ID.AddPointer(P.getAsType().getAsOpaquePtr()); diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp --- a/clang/lib/AST/TypePrinter.cpp +++ b/clang/lib/AST/TypePrinter.cpp @@ -1470,14 +1470,27 @@ const SubstTemplateTypeParmPackType *T, raw_ostream &OS) { IncludeStrongLifetimeRAII Strong(Policy); - printTemplateTypeParmBefore(T->getReplacedParameter(), OS); + if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) { + if (D && D->isImplicit()) { + if (auto *TC = D->getTypeConstraint()) { + TC->print(OS, Policy); + OS << ' '; + } + OS << "auto"; + } else if (IdentifierInfo *Id = D->getIdentifier()) + OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName() + : Id->getName()); + else + OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex(); + + spaceBeforePlaceHolder(OS); + } } void TypePrinter::printSubstTemplateTypeParmPackAfter( const SubstTemplateTypeParmPackType *T, raw_ostream &OS) { IncludeStrongLifetimeRAII Strong(Policy); - printTemplateTypeParmAfter(T->getReplacedParameter(), OS); } void TypePrinter::printTemplateId(const TemplateSpecializationType *T, diff --git a/clang/lib/Sema/SemaConcept.cpp b/clang/lib/Sema/SemaConcept.cpp --- a/clang/lib/Sema/SemaConcept.cpp +++ b/clang/lib/Sema/SemaConcept.cpp @@ -327,8 +327,9 @@ // has no access to the MultiLevelTemplateArgumentList, so this has to happen // here. llvm::SmallVector FlattenedArgs; - for (ArrayRef List : TemplateArgsLists) - FlattenedArgs.insert(FlattenedArgs.end(), List.begin(), List.end()); + for (auto List : TemplateArgsLists) + FlattenedArgs.insert(FlattenedArgs.end(), List.Args.begin(), + List.Args.end()); llvm::FoldingSetNodeID ID; ConstraintSatisfaction::Profile(ID, Context, Template, FlattenedArgs); @@ -435,7 +436,7 @@ MultiLevelTemplateArgumentList MLTAL; // FIXME: This will be replaced with some logic to get all the template // arguments when we switch to deferred template instantiation. - MLTAL.addOuterTemplateArguments(TemplateArgs); + MLTAL.addOuterTemplateArguments(Decl, TemplateArgs); // If this is not an explicit specialization - we need to get the instantiated // version of the template arguments and add them to scope for the @@ -447,7 +448,7 @@ if (Inst.isInvalid()) return true; MultiLevelTemplateArgumentList MLTAL( - *Decl->getTemplateSpecializationArgs()); + Decl, Decl->getTemplateSpecializationArgs()->asArray()); if (addInstantiatedParametersToScope( Decl, Decl->getPrimaryTemplate()->getTemplatedDecl(), Scope, MLTAL)) return true; @@ -749,7 +750,7 @@ AtomicConstraint &Atomic = *N.getAtomicConstraint(); TemplateArgumentListInfo SubstArgs; MultiLevelTemplateArgumentList MLTAL; - MLTAL.addOuterTemplateArguments(TemplateArgs); + MLTAL.addOuterTemplateArguments(Concept, TemplateArgs); if (!Atomic.ParameterMapping) { llvm::SmallBitVector OccurringIndices(TemplateParams->size()); S.MarkUsedTemplateParameters(Atomic.ConstraintExpr, /*OnlyDeduced=*/false, diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp --- a/clang/lib/Sema/SemaExprCXX.cpp +++ b/clang/lib/Sema/SemaExprCXX.cpp @@ -8907,13 +8907,13 @@ Context.getReferenceQualifiedType(E).getCanonicalType(); llvm::SmallVector Args; Args.push_back(TemplateArgument(MatchedType)); + + auto *Param = cast(TPL->getParam(0)); + TemplateArgumentList TAL(TemplateArgumentList::OnStack, Args); - MultiLevelTemplateArgumentList MLTAL(TAL); - for (unsigned I = 0; I < TPL->getDepth(); ++I) - MLTAL.addOuterRetainedLevel(); - Expr *IDC = - cast(TPL->getParam(0))->getTypeConstraint() - ->getImmediatelyDeclaredConstraint(); + MultiLevelTemplateArgumentList MLTAL(Param, TAL.asArray()); + MLTAL.addOuterRetainedLevels(TPL->getDepth()); + Expr *IDC = Param->getTypeConstraint()->getImmediatelyDeclaredConstraint(); ExprResult Constraint = SubstExpr(IDC, MLTAL); if (Constraint.isInvalid()) { Status = concepts::ExprRequirement::SS_ExprSubstitutionFailure; diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp --- a/clang/lib/Sema/SemaTemplate.cpp +++ b/clang/lib/Sema/SemaTemplate.cpp @@ -3760,7 +3760,8 @@ // Only substitute for the innermost template argument list. MultiLevelTemplateArgumentList TemplateArgLists; - TemplateArgLists.addOuterTemplateArguments(&StackTemplateArgs); + TemplateArgLists.addOuterTemplateArguments(Template, + StackTemplateArgs.asArray()); TemplateArgLists.addOuterRetainedLevels( AliasTemplate->getTemplateParameters()->getDepth()); @@ -3882,7 +3883,7 @@ InstantiatingTemplate Inst(*this, TemplateLoc, Decl); if (!Inst.isInvalid()) { MultiLevelTemplateArgumentList TemplateArgLists; - TemplateArgLists.addOuterTemplateArguments(Converted); + TemplateArgLists.addOuterTemplateArguments(Template, Converted); InstantiateAttrsForDecl(TemplateArgLists, ClassTemplate->getTemplatedDecl(), Decl); } @@ -4751,7 +4752,7 @@ TemplateSpecializationType::anyDependentTemplateArguments(*TemplateArgs, Converted); MultiLevelTemplateArgumentList MLTAL; - MLTAL.addOuterTemplateArguments(Converted); + MLTAL.addOuterTemplateArguments(NamedConcept, Converted); LocalInstantiationScope Scope(*this); if (!AreArgsDependent && CheckConstraintSatisfaction( @@ -5161,8 +5162,8 @@ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted); // Only substitute for the innermost template argument list. - MultiLevelTemplateArgumentList TemplateArgLists; - TemplateArgLists.addOuterTemplateArguments(&TemplateArgs); + MultiLevelTemplateArgumentList TemplateArgLists(Template, + TemplateArgs.asArray()); for (unsigned i = 0, e = Param->getDepth(); i != e; ++i) TemplateArgLists.addOuterTemplateArguments(None); @@ -5217,8 +5218,8 @@ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted); // Only substitute for the innermost template argument list. - MultiLevelTemplateArgumentList TemplateArgLists; - TemplateArgLists.addOuterTemplateArguments(&TemplateArgs); + MultiLevelTemplateArgumentList TemplateArgLists(Template, + TemplateArgs.asArray()); for (unsigned i = 0, e = Param->getDepth(); i != e; ++i) TemplateArgLists.addOuterTemplateArguments(None); @@ -5270,8 +5271,8 @@ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted); // Only substitute for the innermost template argument list. - MultiLevelTemplateArgumentList TemplateArgLists; - TemplateArgLists.addOuterTemplateArguments(&TemplateArgs); + MultiLevelTemplateArgumentList TemplateArgLists(Template, + TemplateArgs.asArray()); for (unsigned i = 0, e = Param->getDepth(); i != e; ++i) TemplateArgLists.addOuterTemplateArguments(None); @@ -5455,18 +5456,15 @@ TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted); + MultiLevelTemplateArgumentList MLTAL(Template, TemplateArgs.asArray()); // If the parameter is a pack expansion, expand this slice of the pack. if (auto *PET = NTTPType->getAs()) { Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(*this, ArgumentPackIndex); - NTTPType = SubstType(PET->getPattern(), - MultiLevelTemplateArgumentList(TemplateArgs), - NTTP->getLocation(), + NTTPType = SubstType(PET->getPattern(), MLTAL, NTTP->getLocation(), NTTP->getDeclName()); } else { - NTTPType = SubstType(NTTPType, - MultiLevelTemplateArgumentList(TemplateArgs), - NTTP->getLocation(), + NTTPType = SubstType(NTTPType, MLTAL, NTTP->getLocation(), NTTP->getDeclName()); } @@ -5609,15 +5607,15 @@ { // Set up a template instantiation context. LocalInstantiationScope Scope(*this); - InstantiatingTemplate Inst(*this, TemplateLoc, Template, - TempParm, Converted, - SourceRange(TemplateLoc, RAngleLoc)); + InstantiatingTemplate Inst(*this, TemplateLoc, Template, TempParm, + Converted, SourceRange(TemplateLoc, RAngleLoc)); if (Inst.isInvalid()) return true; TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Converted); - Params = SubstTemplateParams(Params, CurContext, - MultiLevelTemplateArgumentList(TemplateArgs)); + Params = SubstTemplateParams( + Params, CurContext, + MultiLevelTemplateArgumentList(Template, TemplateArgs.asArray())); if (!Params) return true; } @@ -5976,7 +5974,7 @@ // FIXME: This will be changed a bit once deferred concept instantiation is // implemented. MultiLevelTemplateArgumentList MLTAL; - MLTAL.addOuterTemplateArguments(Converted); + MLTAL.addOuterTemplateArguments(Template, Converted); if (EnsureTemplateArgumentListConstraints( Template, MLTAL, SourceRange(TemplateLoc, TemplateArgs.getRAngleLoc()))) { diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp --- a/clang/lib/Sema/SemaTemplateDeduction.cpp +++ b/clang/lib/Sema/SemaTemplateDeduction.cpp @@ -2633,7 +2633,7 @@ if (PackedArgsBuilder.empty()) { LocalInstantiationScope Scope(S); TemplateArgumentList TemplateArgs(TemplateArgumentList::OnStack, Output); - MultiLevelTemplateArgumentList Args(TemplateArgs); + MultiLevelTemplateArgumentList Args(Template, TemplateArgs.asArray()); if (auto *NTTP = dyn_cast(Param)) { Sema::InstantiatingTemplate Inst(S, Template->getLocation(), Template, @@ -2805,7 +2805,7 @@ // FIXME: This will change quite a bit once deferred concept instantiation is // implemented. MultiLevelTemplateArgumentList MLTAL; - MLTAL.addOuterTemplateArguments(DeducedArgs); + MLTAL.addOuterTemplateArguments(Template, DeducedArgs); if (S.CheckConstraintSatisfaction(Template, AssociatedConstraints, MLTAL, Info.getLocation(), @@ -2860,9 +2860,10 @@ TemplateArgumentListInfo InstArgs(PartialTemplArgInfo->LAngleLoc, PartialTemplArgInfo->RAngleLoc); - if (S.SubstTemplateArguments( - PartialTemplArgInfo->arguments(), - MultiLevelTemplateArgumentList(*DeducedArgumentList), InstArgs)) { + if (S.SubstTemplateArguments(PartialTemplArgInfo->arguments(), + MultiLevelTemplateArgumentList( + Partial, DeducedArgumentList->asArray()), + InstArgs)) { unsigned ArgIdx = InstArgs.size(), ParamIdx = ArgIdx; if (ParamIdx >= Partial->getTemplateParameters()->size()) ParamIdx = Partial->getTemplateParameters()->size() - 1; @@ -3198,7 +3199,8 @@ if (Proto->hasTrailingReturn()) { if (SubstParmTypes(Function->getLocation(), Function->parameters(), Proto->getExtParameterInfosOrNull(), - MultiLevelTemplateArgumentList(*ExplicitArgumentList), + MultiLevelTemplateArgumentList( + FunctionTemplate, ExplicitArgumentList->asArray()), ParamTypes, /*params*/ nullptr, ExtParamInfos)) return TDK_SubstitutionFailure; } @@ -3224,7 +3226,8 @@ ResultType = SubstType(Proto->getReturnType(), - MultiLevelTemplateArgumentList(*ExplicitArgumentList), + MultiLevelTemplateArgumentList( + FunctionTemplate, ExplicitArgumentList->asArray()), Function->getTypeSpecStartLoc(), Function->getDeclName()); if (ResultType.isNull() || Trap.hasErrorOccurred()) return TDK_SubstitutionFailure; @@ -3242,7 +3245,8 @@ if (!Proto->hasTrailingReturn() && SubstParmTypes(Function->getLocation(), Function->parameters(), Proto->getExtParameterInfosOrNull(), - MultiLevelTemplateArgumentList(*ExplicitArgumentList), + MultiLevelTemplateArgumentList( + FunctionTemplate, ExplicitArgumentList->asArray()), ParamTypes, /*params*/ nullptr, ExtParamInfos)) return TDK_SubstitutionFailure; @@ -3257,7 +3261,8 @@ if (getLangOpts().CPlusPlus17 && SubstExceptionSpec( Function->getLocation(), EPI.ExceptionSpec, ExceptionStorage, - MultiLevelTemplateArgumentList(*ExplicitArgumentList))) + MultiLevelTemplateArgumentList(FunctionTemplate, + ExplicitArgumentList->asArray()))) return TDK_SubstitutionFailure; *FunctionType = BuildFunctionType(ResultType, ParamTypes, @@ -3497,7 +3502,8 @@ DeclContext *Owner = FunctionTemplate->getDeclContext(); if (FunctionTemplate->getFriendObjectKind()) Owner = FunctionTemplate->getLexicalDeclContext(); - MultiLevelTemplateArgumentList SubstArgs(*DeducedArgumentList); + MultiLevelTemplateArgumentList SubstArgs(FunctionTemplate, + DeducedArgumentList->asArray()); Specialization = cast_or_null( SubstDecl(FunctionTemplate->getTemplatedDecl(), Owner, SubstArgs)); if (!Specialization || Specialization->isInvalidDecl()) @@ -4554,7 +4560,7 @@ /*PartialTemplateArgs=*/false, Converted)) return true; MultiLevelTemplateArgumentList MLTAL; - MLTAL.addOuterTemplateArguments(Converted); + MLTAL.addOuterTemplateArguments(Concept, Converted); if (S.CheckConstraintSatisfaction(Concept, {Concept->getConstraintExpr()}, MLTAL, TypeLoc.getLocalSourceRange(), Satisfaction)) @@ -5798,9 +5804,8 @@ case Type::SubstTemplateTypeParmPack: { const SubstTemplateTypeParmPackType *Subst = cast(T); - MarkUsedTemplateParameters(Ctx, - QualType(Subst->getReplacedParameter(), 0), - OnlyDeduced, Depth, Used); + if (Subst->getReplacedParameter()->getDepth() == Depth) + Used[Subst->getIndex()] = true; MarkUsedTemplateParameters(Ctx, Subst->getArgumentPack(), OnlyDeduced, Depth, Used); break; diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -64,7 +64,8 @@ MultiLevelTemplateArgumentList Result; if (Innermost) - Result.addOuterTemplateArguments(Innermost); + Result.addOuterTemplateArguments(const_cast(D), + Innermost->asArray()); const auto *Ctx = dyn_cast(D); if (!Ctx) { @@ -80,8 +81,6 @@ !isa(Spec)) return Result; - Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs()); - // If this variable template specialization was instantiated from a // specialized member that is a variable template, we're done. assert(Spec->getSpecializedTemplate() && "No variable template?"); @@ -90,10 +89,14 @@ = Spec->getSpecializedTemplateOrPartial(); if (VarTemplatePartialSpecializationDecl *Partial = Specialized.dyn_cast()) { + Result.addOuterTemplateArguments( + Partial, Spec->getTemplateInstantiationArgs().asArray()); if (Partial->isMemberSpecialization()) return Result; } else { VarTemplateDecl *Tmpl = Specialized.get(); + Result.addOuterTemplateArguments( + Tmpl, Spec->getTemplateInstantiationArgs().asArray()); if (Tmpl->isMemberSpecialization()) return Result; } @@ -123,7 +126,9 @@ !isa(Spec)) break; - Result.addOuterTemplateArguments(&Spec->getTemplateInstantiationArgs()); + Result.addOuterTemplateArguments( + const_cast(Spec), + Spec->getTemplateInstantiationArgs().asArray()); // If this class template specialization was instantiated from a // specialized member that is a class template, we're done. @@ -146,7 +151,8 @@ } else if (const TemplateArgumentList *TemplateArgs = Function->getTemplateSpecializationArgs()) { // Add the template arguments for this specialization. - Result.addOuterTemplateArguments(TemplateArgs); + Result.addOuterTemplateArguments(const_cast(Function), + TemplateArgs->asArray()); // If this function was instantiated from a specialized member that is // a function template, we're done. @@ -1778,6 +1784,9 @@ TemplateInstantiator::TransformTemplateTypeParmType(TypeLocBuilder &TLB, TemplateTypeParmTypeLoc TL) { const TemplateTypeParmType *T = TL.getTypePtr(); + TemplateTypeParmDecl *NewTTPDecl = cast_or_null( + TransformDecl(TL.getNameLoc(), T->getDecl())); + if (T->getDepth() < TemplateArgs.getNumLevels()) { // Replace the template type parameter with its corresponding // template argument. @@ -1813,6 +1822,8 @@ return NewT; } + Decl *ReplacedDecl = TemplateArgs.getReplacedDecl(T->getDepth()); + Optional PackIndex; if (T->isParameterPack()) { assert(Arg.getKind() == TemplateArgument::Pack && @@ -1822,8 +1833,8 @@ // We have the template argument pack, but we're not expanding the // enclosing pack expansion yet. Just save the template argument // pack for later substitution. - QualType Result - = getSema().Context.getSubstTemplateTypeParmPackType(T, Arg); + QualType Result = getSema().Context.getSubstTemplateTypeParmPackType( + ReplacedDecl, T->getIndex(), Arg); SubstTemplateTypeParmPackTypeLoc NewTL = TLB.push(Result); NewTL.setNameLoc(TL.getNameLoc()); @@ -1841,7 +1852,7 @@ // TODO: only do this uniquing once, at the start of instantiation. QualType Result = getSema().Context.getSubstTemplateTypeParmType( - T, Replacement, PackIndex); + Replacement, ReplacedDecl, T->getIndex(), PackIndex); SubstTemplateTypeParmTypeLoc NewTL = TLB.push(Result); NewTL.setNameLoc(TL.getNameLoc()); @@ -1852,11 +1863,6 @@ // the template parameter list of a member template inside the // template we are instantiating). Create a new template type // parameter with the template "level" reduced by one. - TemplateTypeParmDecl *NewTTPDecl = nullptr; - if (TemplateTypeParmDecl *OldTTPDecl = T->getDecl()) - NewTTPDecl = cast_or_null( - TransformDecl(TL.getNameLoc(), OldTTPDecl)); - QualType Result = getSema().Context.getTemplateTypeParmType( T->getDepth() - TemplateArgs.getNumSubstitutedLevels(), T->getIndex(), T->isParameterPack(), NewTTPDecl); @@ -1865,26 +1871,32 @@ return Result; } -QualType -TemplateInstantiator::TransformSubstTemplateTypeParmPackType( - TypeLocBuilder &TLB, - SubstTemplateTypeParmPackTypeLoc TL) { +QualType TemplateInstantiator::TransformSubstTemplateTypeParmPackType( + TypeLocBuilder &TLB, SubstTemplateTypeParmPackTypeLoc TL) { + const SubstTemplateTypeParmPackType *T = TL.getTypePtr(); + + Decl *NewReplaced = TransformDecl(TL.getNameLoc(), T->getReplacedDecl()); + if (getSema().ArgumentPackSubstitutionIndex == -1) { // We aren't expanding the parameter pack, so just return ourselves. - SubstTemplateTypeParmPackTypeLoc NewTL - = TLB.push(TL.getType()); + QualType Result = TL.getType(); + if (NewReplaced != T->getReplacedDecl()) + Result = getSema().Context.getSubstTemplateTypeParmPackType( + NewReplaced, T->getIndex(), T->getArgumentPack()); + SubstTemplateTypeParmPackTypeLoc NewTL = + TLB.push(Result); NewTL.setNameLoc(TL.getNameLoc()); - return TL.getType(); + return Result; } - TemplateArgument Arg = TL.getTypePtr()->getArgumentPack(); - Arg = getPackSubstitutedTemplateArgument(getSema(), Arg); + TemplateArgument Arg = + getPackSubstitutedTemplateArgument(getSema(), T->getArgumentPack()); QualType Result = getSema().Context.getSubstTemplateTypeParmType( - TL.getTypePtr()->getReplacedParameter(), Arg.getAsType(), + Arg.getAsType(), NewReplaced, T->getIndex(), getSema().ArgumentPackSubstitutionIndex); - SubstTemplateTypeParmTypeLoc NewTL - = TLB.push(Result); + SubstTemplateTypeParmTypeLoc NewTL = + TLB.push(Result); NewTL.setNameLoc(TL.getNameLoc()); return Result; } diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4767,7 +4767,7 @@ return nullptr; ContextRAII SavedContext(*this, FD); - MultiLevelTemplateArgumentList MArgs(*Args); + MultiLevelTemplateArgumentList MArgs(FTD, Args->asArray()); return cast_or_null(SubstDecl(FD, FD->getParent(), MArgs)); } @@ -5113,9 +5113,6 @@ if (Inst.isInvalid()) return nullptr; - MultiLevelTemplateArgumentList TemplateArgLists; - TemplateArgLists.addOuterTemplateArguments(&TemplateArgList); - // Instantiate the first declaration of the variable template: for a partial // specialization of a static data member template, the first declaration may // or may not be the declaration in the class; if it's in the class, we want @@ -5134,7 +5131,8 @@ if (!IsMemberSpec) FromVar = FromVar->getFirstDecl(); - MultiLevelTemplateArgumentList MultiLevelList(TemplateArgList); + MultiLevelTemplateArgumentList MultiLevelList(VarTemplate, + TemplateArgList.asArray()); TemplateDeclInstantiator Instantiator(*this, FromVar->getDeclContext(), MultiLevelList); diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -4854,8 +4854,8 @@ Replacement = SemaRef.Context.getQualifiedType( Replacement.getUnqualifiedType(), Qs); T = SemaRef.Context.getSubstTemplateTypeParmType( - SubstTypeParam->getReplacedParameter(), Replacement, - SubstTypeParam->getPackIndex()); + Replacement, SubstTypeParam->getReplacedDecl(), + SubstTypeParam->getIndex(), SubstTypeParam->getPackIndex()); } else if ((AutoTy = dyn_cast(T)) && AutoTy->isDeduced()) { // 'auto' types behave the same way as template parameters. QualType Deduced = AutoTy->getDeducedType(); @@ -6402,6 +6402,9 @@ SubstTemplateTypeParmTypeLoc TL) { const SubstTemplateTypeParmType *T = TL.getTypePtr(); + Decl *NewReplaced = + getDerived().TransformDecl(TL.getNameLoc(), T->getReplacedDecl()); + // Substitute into the replacement type, which itself might involve something // that needs to be transformed. This only tends to occur with default // template arguments of template template parameters. @@ -6413,7 +6416,7 @@ // Always canonicalize the replacement type. Replacement = SemaRef.Context.getCanonicalType(Replacement); QualType Result = SemaRef.Context.getSubstTemplateTypeParmType( - T->getReplacedParameter(), Replacement, T->getPackIndex()); + Replacement, NewReplaced, T->getIndex(), T->getPackIndex()); // Propagate type-source information. SubstTemplateTypeParmTypeLoc NewTL diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp --- a/clang/lib/Serialization/ASTReaderDecl.cpp +++ b/clang/lib/Serialization/ASTReaderDecl.cpp @@ -2390,8 +2390,6 @@ ASTDeclReader::RedeclarableResult ASTDeclReader::VisitVarTemplateSpecializationDeclImpl( VarTemplateSpecializationDecl *D) { - RedeclarableResult Redecl = VisitVarDeclImpl(D); - ASTContext &C = Reader.getContext(); if (Decl *InstD = readDecl()) { if (auto *VTD = dyn_cast(InstD)) { @@ -2428,6 +2426,8 @@ D->SpecializationKind = (TemplateSpecializationKind)Record.readInt(); D->IsCompleteDefinition = Record.readInt(); + RedeclarableResult Redecl = VisitVarDeclImpl(D); + bool writtenAsCanonicalDecl = Record.readInt(); if (writtenAsCanonicalDecl) { auto *CanonPattern = readDeclAs(); diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp --- a/clang/lib/Serialization/ASTWriterDecl.cpp +++ b/clang/lib/Serialization/ASTWriterDecl.cpp @@ -1607,8 +1607,6 @@ VarTemplateSpecializationDecl *D) { RegisterTemplateSpecialization(D->getSpecializedTemplate(), D); - VisitVarDecl(D); - llvm::PointerUnion InstFrom = D->getSpecializedTemplateOrPartial(); if (Decl *InstFromD = InstFrom.dyn_cast()) { @@ -1629,6 +1627,9 @@ Record.AddSourceLocation(D->getPointOfInstantiation()); Record.push_back(D->getSpecializationKind()); Record.push_back(D->IsCompleteDefinition); + + VisitVarDecl(D); + Record.push_back(D->isCanonicalDecl()); if (D->isCanonicalDecl()) { diff --git a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/MismatchedIteratorChecker.cpp @@ -176,8 +176,10 @@ const auto *Param = Func->getParamDecl(J); const auto *ParamType = Param->getType()->getAs(); - if (!ParamType || - ParamType->getReplacedParameter()->getDecl() != TPDecl) + if (!ParamType) + continue; + const TemplateTypeParmDecl *D = ParamType->getReplacedParameter(); + if (D != TPDecl) continue; if (LHS.isUndef()) { LHS = Call.getArgSVal(J); diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_reference.cpp b/clang/test/AST/ast-dump-openmp-begin-declare-variant_reference.cpp --- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_reference.cpp +++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_reference.cpp @@ -122,9 +122,8 @@ // CHECK-NEXT: | | | `-BuiltinType [[ADDR_8:0x[a-z0-9]*]] 'float' // CHECK-NEXT: | | |-CXXRecordDecl [[ADDR_9:0x[a-z0-9]*]] col:29 implicit struct remove_reference // CHECK-NEXT: | | `-TypedefDecl [[ADDR_10:0x[a-z0-9]*]] col:67 referenced type 'float':'float' -// CHECK-NEXT: | | `-SubstTemplateTypeParmType [[ADDR_11:0x[a-z0-9]*]] 'float' sugar -// CHECK-NEXT: | | |-TemplateTypeParmType [[ADDR_12:0x[a-z0-9]*]] '_Tp' dependent depth 0 index 0 -// CHECK-NEXT: | | | `-TemplateTypeParm [[ADDR_13:0x[a-z0-9]*]] '_Tp' +// CHECK-NEXT: | | `-SubstTemplateTypeParmType [[ADDR_11:0x[a-z0-9]*]] 'float' sugar class depth 0 index 0 _Tp +// CHECK-NEXT: | | |-ClassTemplateSpecialization [[ADDR_6]] 'remove_reference' // CHECK-NEXT: | | `-BuiltinType [[ADDR_8]] 'float' // CHECK-NEXT: | `-ClassTemplateSpecializationDecl [[ADDR_14:0x[a-z0-9]*]] col:29 struct remove_reference definition // CHECK-NEXT: | |-DefinitionData pass_in_registers empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init @@ -139,9 +138,8 @@ // CHECK-NEXT: | | `-BuiltinType [[ADDR_16:0x[a-z0-9]*]] 'short' // CHECK-NEXT: | |-CXXRecordDecl [[ADDR_17:0x[a-z0-9]*]] col:29 implicit struct remove_reference // CHECK-NEXT: | `-TypedefDecl [[ADDR_18:0x[a-z0-9]*]] col:67 referenced type 'short':'short' -// CHECK-NEXT: | `-SubstTemplateTypeParmType [[ADDR_19:0x[a-z0-9]*]] 'short' sugar -// CHECK-NEXT: | |-TemplateTypeParmType [[ADDR_12]] '_Tp' dependent depth 0 index 0 -// CHECK-NEXT: | | `-TemplateTypeParm [[ADDR_13]] '_Tp' +// CHECK-NEXT: | `-SubstTemplateTypeParmType [[ADDR_19:0x[a-z0-9]*]] 'short' sugar class depth 0 index 0 _Tp +// CHECK-NEXT: | |-ClassTemplateSpecialization [[ADDR_14]] 'remove_reference' // CHECK-NEXT: | `-BuiltinType [[ADDR_16]] 'short' // CHECK-NEXT: |-ClassTemplatePartialSpecializationDecl [[ADDR_20:0x[a-z0-9]*]] col:29 struct remove_reference definition // CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init @@ -154,10 +152,10 @@ // CHECK-NEXT: | |-TemplateArgument type 'type-parameter-0-0 &' // CHECK-NEXT: | | `-LValueReferenceType [[ADDR_21:0x[a-z0-9]*]] 'type-parameter-0-0 &' dependent // CHECK-NEXT: | | `-TemplateTypeParmType [[ADDR_22:0x[a-z0-9]*]] 'type-parameter-0-0' dependent depth 0 index 0 -// CHECK-NEXT: | |-TemplateTypeParmDecl [[ADDR_13]] col:17 referenced class depth 0 index 0 _Tp +// CHECK-NEXT: | |-TemplateTypeParmDecl [[ADDR_13:0x[a-z0-9]*]] col:17 referenced class depth 0 index 0 _Tp // CHECK-NEXT: | |-CXXRecordDecl [[ADDR_23:0x[a-z0-9]*]] col:29 implicit struct remove_reference // CHECK-NEXT: | `-TypedefDecl [[ADDR_24:0x[a-z0-9]*]] col:67 type '_Tp' -// CHECK-NEXT: | `-TemplateTypeParmType [[ADDR_12]] '_Tp' dependent depth 0 index 0 +// CHECK-NEXT: | `-TemplateTypeParmType [[ADDR_12:0x[a-z0-9]*]] '_Tp' dependent depth 0 index 0 // CHECK-NEXT: | `-TemplateTypeParm [[ADDR_13]] '_Tp' // CHECK-NEXT: |-ClassTemplatePartialSpecializationDecl [[ADDR_25:0x[a-z0-9]*]] col:29 struct remove_reference definition // CHECK-NEXT: | |-DefinitionData empty aggregate standard_layout trivially_copyable pod trivial literal has_constexpr_non_copy_move_ctor can_const_default_init @@ -197,9 +195,8 @@ // CHECK-NEXT: | | | `-ElaboratedType [[ADDR_47:0x[a-z0-9]*]] 'typename remove_reference::type' sugar // CHECK-NEXT: | | | `-TypedefType [[ADDR_48:0x[a-z0-9]*]] 'remove_reference::type' sugar // CHECK-NEXT: | | | |-Typedef [[ADDR_10]] 'type' -// CHECK-NEXT: | | | `-SubstTemplateTypeParmType [[ADDR_11]] 'float' sugar -// CHECK-NEXT: | | | |-TemplateTypeParmType [[ADDR_12]] '_Tp' dependent depth 0 index 0 -// CHECK-NEXT: | | | | `-TemplateTypeParm [[ADDR_13]] '_Tp' +// CHECK-NEXT: | | | `-SubstTemplateTypeParmType [[ADDR_11]] 'float' sugar class depth 0 index 0 _Tp +// CHECK-NEXT: | | | |-ClassTemplateSpecialization [[ADDR_6]] 'remove_reference' // CHECK-NEXT: | | | `-BuiltinType [[ADDR_8]] 'float' // CHECK-NEXT: | | `-ReturnStmt [[ADDR_49:0x[a-z0-9]*]] // CHECK-NEXT: | | `-CXXStaticCastExpr [[ADDR_50:0x[a-z0-9]*]] '_Up':'float' xvalue static_cast<_Up &&> @@ -215,9 +212,8 @@ // CHECK-NEXT: | | `-ElaboratedType [[ADDR_57:0x[a-z0-9]*]] 'typename remove_reference::type' sugar // CHECK-NEXT: | | `-TypedefType [[ADDR_58:0x[a-z0-9]*]] 'remove_reference::type' sugar // CHECK-NEXT: | | |-Typedef [[ADDR_18]] 'type' -// CHECK-NEXT: | | `-SubstTemplateTypeParmType [[ADDR_19]] 'short' sugar -// CHECK-NEXT: | | |-TemplateTypeParmType [[ADDR_12]] '_Tp' dependent depth 0 index 0 -// CHECK-NEXT: | | | `-TemplateTypeParm [[ADDR_13]] '_Tp' +// CHECK-NEXT: | | `-SubstTemplateTypeParmType [[ADDR_19]] 'short' sugar class depth 0 index 0 _Tp +// CHECK-NEXT: | | |-ClassTemplateSpecialization [[ADDR_14]] 'remove_reference' // CHECK-NEXT: | | `-BuiltinType [[ADDR_16]] 'short' // CHECK-NEXT: | `-ReturnStmt [[ADDR_59:0x[a-z0-9]*]] // CHECK-NEXT: | `-CXXStaticCastExpr [[ADDR_60:0x[a-z0-9]*]] '_Up':'short' xvalue static_cast<_Up &&> diff --git a/clang/test/AST/ast-dump-template-decls.cpp b/clang/test/AST/ast-dump-template-decls.cpp --- a/clang/test/AST/ast-dump-template-decls.cpp +++ b/clang/test/AST/ast-dump-template-decls.cpp @@ -120,12 +120,12 @@ // CHECK-NEXT: TemplateArgument type 'void' // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void' // CHECK-NEXT: FunctionProtoType 0x{{[^ ]*}} 'void (int)' cdecl -// CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'void' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent depth 0 index 0 -// CHECK-NEXT: TemplateTypeParm 0x{{[^ ]*}} 'U' +// CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'void' sugar class depth 0 index 0 U +// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'type1' // CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'void' -// CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent depth 0 index 0 +// CHECK-NEXT: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar class depth 0 index 0 T +// CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'C' +// CHECK-NEXT: BuiltinType 0x{{[^ ]*}} 'int' } // namespace PR55886 namespace PR56099 { @@ -136,14 +136,14 @@ }; using t1 = foo::bind; // CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'Y' sugar Y -// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar pack_index 0 -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack -// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar pack_index 1 -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack -// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar pack_index 2 -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack -// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar pack_index 3 -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'Bs' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar typename depth 0 index 0 ... Bs pack_index 0 +// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z' +// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... Bs pack_index 1 +// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z' +// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar typename depth 0 index 0 ... Bs pack_index 2 +// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z' +// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar typename depth 0 index 0 ... Bs pack_index 3 +// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'Z' template struct D { template using B = int(int (*...p)(T, U)); @@ -152,13 +152,13 @@ // CHECK: TemplateSpecializationType 0x{{[^ ]*}} 'B' sugar alias B // CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (int (*)(float, int), int (*)(char, short))' cdecl // CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (float, int)' cdecl -// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar pack_index 0 -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack -// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar pack_index 0 -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'float' sugar typename depth 0 index 0 ... T pack_index 0 +// CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'D' +// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'int' sugar typename depth 0 index 0 ... U pack_index 0 +// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'B' // CHECK: FunctionProtoType 0x{{[^ ]*}} 'int (char, short)' cdecl -// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar pack_index 1 -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack -// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar pack_index 1 -// CHECK-NEXT: TemplateTypeParmType 0x{{[^ ]*}} 'U' dependent contains_unexpanded_pack depth 0 index 0 pack +// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'char' sugar typename depth 0 index 0 ... T pack_index 1 +// CHECK-NEXT: ClassTemplateSpecialization 0x{{[^ ]*}} 'D' +// CHECK: SubstTemplateTypeParmType 0x{{[^ ]*}} 'short' sugar typename depth 0 index 0 ... U pack_index 1 +// CHECK-NEXT: TypeAliasTemplate 0x{{[^ ]*}} 'B' } // namespace PR56099 diff --git a/clang/test/AST/deduction-guides.cpp b/clang/test/AST/deduction-guides.cpp --- a/clang/test/AST/deduction-guides.cpp +++ b/clang/test/AST/deduction-guides.cpp @@ -67,9 +67,8 @@ // CHECK-NEXT: ElaboratedType {{.*}} 'typename Derived::type_alias' sugar // CHECK-NEXT: TypedefType {{.*}} 'PR48177::Base::type_alias' sugar // CHECK-NEXT: TypeAlias {{.*}} 'type_alias' -// CHECK-NEXT: SubstTemplateTypeParmType {{.*}} 'int' sugar -// CHECK-NEXT: TemplateTypeParmType {{.*}} 'A' -// CHECK-NEXT: TemplateTypeParm {{.*}} 'A' +// CHECK-NEXT: SubstTemplateTypeParmType {{.*}} 'int' sugar class depth 0 index 0 A +// CHECK-NEXT: ClassTemplateSpecialization {{.*}} 'Base' // CHECK-NEXT: BuiltinType {{.*}} 'int' // CHECK: CXXDeductionGuideDecl {{.*}} implicit 'auto (Derived &&, const typename Derived::type_alias &) -> Derived' diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp --- a/clang/test/SemaTemplate/deduction-guide.cpp +++ b/clang/test/SemaTemplate/deduction-guide.cpp @@ -156,9 +156,8 @@ // CHECK: |-BuiltinType {{.*}} 'int' // CHECK: |-TemplateTypeParmType {{.*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack // CHECK: | `-TemplateTypeParm {{.*}} 'T' -// CHECK: `-SubstTemplateTypeParmPackType {{.*}} 'U' dependent contains_unexpanded_pack -// CHECK: |-TemplateTypeParmType {{.*}} 'U' dependent contains_unexpanded_pack depth 1 index 0 pack -// CHECK: | `-TemplateTypeParm {{.*}} 'U' +// CHECK: `-SubstTemplateTypeParmPackType {{.*}} 'U' dependent contains_unexpanded_pack typename depth 1 index 0 ... U +// CHECK: |-TypeAliasTemplate {{.*}} 'B' // CHECK: `-TemplateArgument pack // CHECK: |-TemplateArgument type 'type-parameter-0-1' // CHECK-NOT: Subst diff --git a/libcxx/DELETE.ME b/libcxx/DELETE.ME --- a/libcxx/DELETE.ME +++ b/libcxx/DELETE.ME @@ -1,3 +1,4 @@ D111283 D111509 D130308 +D131858