[llvm-branch-commits] [clang] [clang] Track final substitution for Subst* AST nodes (PR #132748)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Mon Mar 24 07:50:47 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Matheus Izvekov (mizvekov)
<details>
<summary>Changes</summary>
This patch re-adds Subst* nodes for 'Final' substitutions, adding a bit to these nodes to differentiate them from non-Final ones, which for example helps track forward progress in resugaring.
This was originally changed when we added support for sugared substitutions in the template instantiator (https://github.com/llvm/llvm-project/commit/326feaafb0913ec6b21d1d89d09cbdbb40db7503), and later applied to NTTP and default argument substitution (https://github.com/llvm/llvm-project/commit/ab1140874fc6ab8ceb55a470489b80d953e1c6a6) and type alias templates (7f78f99fe5af82361d37adcbd2daa4d04afba13d).
This kind of instantiation is favored for entities which we don't track specializations, like the aforementioned cases because:
* Without tracking specializations, its not possible to (correctly) resugar these later.
* A change to track specialization and adding resugar pass would have been more expensive.
While the node could have been still useful, its removal helped offset the extra costs of the sugared instantiation.
Otherwise, adding them would also necessitate tracking which nodes don't need to be resugared later, which this patch does.
Adding the node back does add a little bit of performance penalty on itself:

0.25% on stage2-clang.
And this will make resugaring a little bit more expensive later when that's upstreamed, since there are more AST nodes to walk, and more AST nodes to produce.
Before:

After:

Which on the current implementation and applications of resugaring transform, is an extra 0.24% on stage2-clang.
Some upstream users reported desirability of keeping these Subst* nodes in all cases, and we had added a special frontend flag to control its removal, which this patch now also removes.
---
Patch is 50.78 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/132748.diff
21 Files Affected:
- (modified) clang/include/clang/AST/ASTContext.h (+9-8)
- (modified) clang/include/clang/AST/ExprCXX.h (+20-5)
- (modified) clang/include/clang/AST/PropertiesBase.td (+2-1)
- (modified) clang/include/clang/AST/TemplateName.h (+12-5)
- (modified) clang/include/clang/AST/Type.h (+14-10)
- (modified) clang/include/clang/AST/TypeProperties.td (+2-2)
- (modified) clang/include/clang/Basic/LangOptions.def (-1)
- (modified) clang/include/clang/Driver/Options.td (-6)
- (modified) clang/lib/AST/ASTContext.cpp (+8-7)
- (modified) clang/lib/AST/ASTImporter.cpp (+5-4)
- (modified) clang/lib/AST/ExprCXX.cpp (+4-2)
- (modified) clang/lib/AST/TemplateName.cpp (+4-2)
- (modified) clang/lib/AST/TextNodeDumper.cpp (+4)
- (modified) clang/lib/AST/Type.cpp (+18-4)
- (modified) clang/lib/Sema/SemaTemplate.cpp (+4-10)
- (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+18-30)
- (modified) clang/lib/Sema/TreeTransform.h (+2-1)
- (removed) clang/test/AST/ast-dump-retain-subst-template-type-parm-type-ast-nodes.cpp (-18)
- (modified) clang/test/AST/ast-dump-template-decls.cpp (+12-6)
- (modified) clang/test/Misc/diag-template-diffing-cxx11.cpp (+37-37)
- (modified) clang/test/SemaTemplate/make_integer_seq.cpp (+6-2)
``````````diff
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 1f7c75559e1e9..2ef8112225767 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);
@@ -2396,10 +2396,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
const IdentifierInfo *Name) const;
TemplateName getDependentTemplateName(NestedNameSpecifier *NNS,
OverloadedOperatorKind Operator) 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/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/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td
index 5f3a885832e2e..416914db2f7c8 100644
--- a/clang/include/clang/AST/PropertiesBase.td
+++ b/clang/include/clang/AST/PropertiesBase.td
@@ -729,8 +729,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 ce97f834bfc1d..313802502f818 100644
--- a/clang/include/clang/AST/TemplateName.h
+++ b/clang/include/clang/AST/TemplateName.h
@@ -413,9 +413,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);
}
@@ -429,10 +431,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;
@@ -442,7 +449,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 3b80f962a3bc6..16fde176fb909 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 {
@@ -6384,7 +6387,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
@@ -6407,6 +6411,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;
@@ -6418,17 +6426,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;
@@ -6475,7 +6478,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/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index 4d89d8a47396a..93f391e99c5ab 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -827,11 +827,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/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 fbd5cf632c350..3f68a55e85d8e 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -3506,12 +3506,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/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 4d2ca9ec1a123..0e3c6535808e0 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -5449,10 +5449,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);
@@ -5462,7 +5462,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);
}
@@ -10130,10 +10130,10 @@ ASTContext::getDependentTemplateName(NestedNameSpecifier *NNS,
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
@@ -10141,7 +10141,7 @@ TemplateName ASTContext::getSubstTemplateTemplateParm(
if (!subst) {
subst = new (*this) SubstTemplateTemplateParmStorage(
- Replacement, AssociatedDecl, Index, PackIndex);
+ Replacement, AssociatedDecl, Index, PackIndex, Final);
SubstTemplateTemplateParms.InsertNode(subst, insertPos);
}
@@ -14243,7 +14243,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 d397c9285ed76..4e27f9d884a83 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(
@@ -8945,7 +8945,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) {
@@ -9958,7 +9959,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/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/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp
index 9e0a7dc2b8cdc..109cc3c4771ee 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 In...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/132748
More information about the llvm-branch-commits
mailing list