Skip to content

Commit f302f35

Browse files
authored
[clang] Track final substitution for Subst* AST nodes (#132748)
1 parent 990a086 commit f302f35

19 files changed

+146
-119
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1795,10 +1795,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
17951795
QualType Wrapped, QualType Contained,
17961796
const HLSLAttributedResourceType::Attributes &Attrs);
17971797

1798-
QualType
1799-
getSubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl,
1800-
unsigned Index,
1801-
std::optional<unsigned> PackIndex) const;
1798+
QualType getSubstTemplateTypeParmType(QualType Replacement,
1799+
Decl *AssociatedDecl, unsigned Index,
1800+
std::optional<unsigned> PackIndex,
1801+
bool Final) const;
18021802
QualType getSubstTemplateTypeParmPackType(Decl *AssociatedDecl,
18031803
unsigned Index, bool Final,
18041804
const TemplateArgument &ArgPack);
@@ -2393,10 +2393,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
23932393
TemplateName
23942394
getDependentTemplateName(const DependentTemplateStorage &Name) const;
23952395

2396-
TemplateName
2397-
getSubstTemplateTemplateParm(TemplateName replacement, Decl *AssociatedDecl,
2398-
unsigned Index,
2399-
std::optional<unsigned> PackIndex) const;
2396+
TemplateName getSubstTemplateTemplateParm(TemplateName replacement,
2397+
Decl *AssociatedDecl,
2398+
unsigned Index,
2399+
std::optional<unsigned> PackIndex,
2400+
bool Final) const;
24002401
TemplateName getSubstTemplateTemplateParmPack(const TemplateArgument &ArgPack,
24012402
Decl *AssociatedDecl,
24022403
unsigned Index,

clang/include/clang/AST/ExprCXX.h

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4514,7 +4514,9 @@ class SubstNonTypeTemplateParmExpr : public Expr {
45144514
llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndRef;
45154515

45164516
unsigned Index : 15;
4517-
unsigned PackIndex : 16;
4517+
unsigned PackIndex : 15;
4518+
LLVM_PREFERRED_TYPE(bool)
4519+
unsigned Final : 1;
45184520

45194521
explicit SubstNonTypeTemplateParmExpr(EmptyShell Empty)
45204522
: Expr(SubstNonTypeTemplateParmExprClass, Empty) {}
@@ -4523,11 +4525,12 @@ class SubstNonTypeTemplateParmExpr : public Expr {
45234525
SubstNonTypeTemplateParmExpr(QualType Ty, ExprValueKind ValueKind,
45244526
SourceLocation Loc, Expr *Replacement,
45254527
Decl *AssociatedDecl, unsigned Index,
4526-
std::optional<unsigned> PackIndex, bool RefParam)
4528+
std::optional<unsigned> PackIndex, bool RefParam,
4529+
bool Final)
45274530
: Expr(SubstNonTypeTemplateParmExprClass, Ty, ValueKind, OK_Ordinary),
45284531
Replacement(Replacement),
45294532
AssociatedDeclAndRef(AssociatedDecl, RefParam), Index(Index),
4530-
PackIndex(PackIndex ? *PackIndex + 1 : 0) {
4533+
PackIndex(PackIndex ? *PackIndex + 1 : 0), Final(Final) {
45314534
assert(AssociatedDecl != nullptr);
45324535
SubstNonTypeTemplateParmExprBits.NameLoc = Loc;
45334536
setDependence(computeDependence(this));
@@ -4555,6 +4558,10 @@ class SubstNonTypeTemplateParmExpr : public Expr {
45554558
return PackIndex - 1;
45564559
}
45574560

4561+
// This substitution is Final, which means the substitution is fully
4562+
// sugared: it doesn't need to be resugared later.
4563+
bool getFinal() const { return Final; }
4564+
45584565
NonTypeTemplateParmDecl *getParameter() const;
45594566

45604567
bool isReferenceParameter() const { return AssociatedDeclAndRef.getInt(); }
@@ -4598,7 +4605,10 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
45984605
const TemplateArgument *Arguments;
45994606

46004607
/// The number of template arguments in \c Arguments.
4601-
unsigned NumArguments : 16;
4608+
unsigned NumArguments : 15;
4609+
4610+
LLVM_PREFERRED_TYPE(bool)
4611+
unsigned Final : 1;
46024612

46034613
unsigned Index : 16;
46044614

@@ -4612,7 +4622,8 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
46124622
SubstNonTypeTemplateParmPackExpr(QualType T, ExprValueKind ValueKind,
46134623
SourceLocation NameLoc,
46144624
const TemplateArgument &ArgPack,
4615-
Decl *AssociatedDecl, unsigned Index);
4625+
Decl *AssociatedDecl, unsigned Index,
4626+
bool Final);
46164627

46174628
/// A template-like entity which owns the whole pattern being substituted.
46184629
/// This will own a set of template parameters.
@@ -4622,6 +4633,10 @@ class SubstNonTypeTemplateParmPackExpr : public Expr {
46224633
/// This should match the result of `getParameterPack()->getIndex()`.
46234634
unsigned getIndex() const { return Index; }
46244635

4636+
// This substitution will be Final, which means the substitution will be fully
4637+
// sugared: it doesn't need to be resugared later.
4638+
bool getFinal() const { return Final; }
4639+
46254640
/// Retrieve the non-type template parameter pack being substituted.
46264641
NonTypeTemplateParmDecl *getParameterPack() const;
46274642

clang/include/clang/AST/PropertiesBase.td

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,8 +730,9 @@ let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParm"> in {
730730
def : Property<"packIndex", Optional<UInt32>> {
731731
let Read = [{ parm->getPackIndex() }];
732732
}
733+
def : Property<"final", Bool> { let Read = [{ parm->getFinal() }]; }
733734
def : Creator<[{
734-
return ctx.getSubstTemplateTemplateParm(replacement, associatedDecl, index, packIndex);
735+
return ctx.getSubstTemplateTemplateParm(replacement, associatedDecl, index, packIndex, final);
735736
}]>;
736737
}
737738
let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParmPack"> in {

clang/include/clang/AST/TemplateName.h

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -414,9 +414,11 @@ class SubstTemplateTemplateParmStorage
414414

415415
SubstTemplateTemplateParmStorage(TemplateName Replacement,
416416
Decl *AssociatedDecl, unsigned Index,
417-
std::optional<unsigned> PackIndex)
417+
std::optional<unsigned> PackIndex,
418+
bool Final)
418419
: UncommonTemplateNameStorage(SubstTemplateTemplateParm, Index,
419-
PackIndex ? *PackIndex + 1 : 0),
420+
((PackIndex ? *PackIndex + 1 : 0) << 1) |
421+
Final),
420422
Replacement(Replacement), AssociatedDecl(AssociatedDecl) {
421423
assert(AssociatedDecl != nullptr);
422424
}
@@ -430,10 +432,15 @@ class SubstTemplateTemplateParmStorage
430432
/// This should match the result of `getParameter()->getIndex()`.
431433
unsigned getIndex() const { return Bits.Index; }
432434

435+
// This substitution is Final, which means the substitution is fully
436+
// sugared: it doesn't need to be resugared later.
437+
bool getFinal() const { return Bits.Data & 1; }
438+
433439
std::optional<unsigned> getPackIndex() const {
434-
if (Bits.Data == 0)
440+
auto Data = Bits.Data >> 1;
441+
if (Data == 0)
435442
return std::nullopt;
436-
return Bits.Data - 1;
443+
return Data - 1;
437444
}
438445

439446
TemplateTemplateParmDecl *getParameter() const;
@@ -443,7 +450,7 @@ class SubstTemplateTemplateParmStorage
443450

444451
static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Replacement,
445452
Decl *AssociatedDecl, unsigned Index,
446-
std::optional<unsigned> PackIndex);
453+
std::optional<unsigned> PackIndex, bool Final);
447454
};
448455

449456
class DeducedTemplateStorage : public UncommonTemplateNameStorage,

clang/include/clang/AST/Type.h

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2158,12 +2158,15 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
21582158
// The index of the template parameter this substitution represents.
21592159
unsigned Index : 15;
21602160

2161+
LLVM_PREFERRED_TYPE(bool)
2162+
unsigned Final : 1;
2163+
21612164
/// Represents the index within a pack if this represents a substitution
21622165
/// from a pack expansion. This index starts at the end of the pack and
21632166
/// increments towards the beginning.
21642167
/// Positive non-zero number represents the index + 1.
21652168
/// Zero means this is not substituted from an expansion.
2166-
unsigned PackIndex : 16;
2169+
unsigned PackIndex : 15;
21672170
};
21682171

21692172
class SubstTemplateTypeParmPackTypeBitfields {
@@ -6397,7 +6400,8 @@ class SubstTemplateTypeParmType final
63976400
Decl *AssociatedDecl;
63986401

63996402
SubstTemplateTypeParmType(QualType Replacement, Decl *AssociatedDecl,
6400-
unsigned Index, std::optional<unsigned> PackIndex);
6403+
unsigned Index, std::optional<unsigned> PackIndex,
6404+
bool Final);
64016405

64026406
public:
64036407
/// Gets the type that was substituted for the template
@@ -6420,6 +6424,10 @@ class SubstTemplateTypeParmType final
64206424
/// This should match the result of `getReplacedParameter()->getIndex()`.
64216425
unsigned getIndex() const { return SubstTemplateTypeParmTypeBits.Index; }
64226426

6427+
// This substitution is Final, which means the substitution is fully
6428+
// sugared: it doesn't need to be resugared later.
6429+
unsigned getFinal() const { return SubstTemplateTypeParmTypeBits.Final; }
6430+
64236431
std::optional<unsigned> getPackIndex() const {
64246432
if (SubstTemplateTypeParmTypeBits.PackIndex == 0)
64256433
return std::nullopt;
@@ -6431,17 +6439,12 @@ class SubstTemplateTypeParmType final
64316439

64326440
void Profile(llvm::FoldingSetNodeID &ID) {
64336441
Profile(ID, getReplacementType(), getAssociatedDecl(), getIndex(),
6434-
getPackIndex());
6442+
getPackIndex(), getFinal());
64356443
}
64366444

64376445
static void Profile(llvm::FoldingSetNodeID &ID, QualType Replacement,
64386446
const Decl *AssociatedDecl, unsigned Index,
6439-
std::optional<unsigned> PackIndex) {
6440-
Replacement.Profile(ID);
6441-
ID.AddPointer(AssociatedDecl);
6442-
ID.AddInteger(Index);
6443-
ID.AddInteger(PackIndex ? *PackIndex - 1 : 0);
6444-
}
6447+
std::optional<unsigned> PackIndex, bool Final);
64456448

64466449
static bool classof(const Type *T) {
64476450
return T->getTypeClass() == SubstTemplateTypeParm;
@@ -6488,7 +6491,8 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
64886491
/// This should match the result of `getReplacedParameter()->getIndex()`.
64896492
unsigned getIndex() const { return SubstTemplateTypeParmPackTypeBits.Index; }
64906493

6491-
// When true the substitution will be 'Final' (subst node won't be placed).
6494+
// This substitution will be Final, which means the substitution will be fully
6495+
// sugared: it doesn't need to be resugared later.
64926496
bool getFinal() const;
64936497

64946498
unsigned getNumArgs() const {

clang/include/clang/AST/TypeProperties.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -842,11 +842,11 @@ let Class = SubstTemplateTypeParmType in {
842842
def : Property<"PackIndex", Optional<UInt32>> {
843843
let Read = [{ node->getPackIndex() }];
844844
}
845+
def : Property<"Final", Bool> { let Read = [{ node->getFinal() }]; }
845846

846-
// The call to getCanonicalType here existed in ASTReader.cpp, too.
847847
def : Creator<[{
848848
return ctx.getSubstTemplateTypeParmType(
849-
replacementType, associatedDecl, Index, PackIndex);
849+
replacementType, associatedDecl, Index, PackIndex, Final);
850850
}]>;
851851
}
852852

clang/lib/AST/ASTContext.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5447,10 +5447,10 @@ QualType ASTContext::getHLSLAttributedResourceType(
54475447
/// Retrieve a substitution-result type.
54485448
QualType ASTContext::getSubstTemplateTypeParmType(
54495449
QualType Replacement, Decl *AssociatedDecl, unsigned Index,
5450-
std::optional<unsigned> PackIndex) const {
5450+
std::optional<unsigned> PackIndex, bool Final) const {
54515451
llvm::FoldingSetNodeID ID;
54525452
SubstTemplateTypeParmType::Profile(ID, Replacement, AssociatedDecl, Index,
5453-
PackIndex);
5453+
PackIndex, Final);
54545454
void *InsertPos = nullptr;
54555455
SubstTemplateTypeParmType *SubstParm =
54565456
SubstTemplateTypeParmTypes.FindNodeOrInsertPos(ID, InsertPos);
@@ -5460,7 +5460,7 @@ QualType ASTContext::getSubstTemplateTypeParmType(
54605460
!Replacement.isCanonical()),
54615461
alignof(SubstTemplateTypeParmType));
54625462
SubstParm = new (Mem) SubstTemplateTypeParmType(Replacement, AssociatedDecl,
5463-
Index, PackIndex);
5463+
Index, PackIndex, Final);
54645464
Types.push_back(SubstParm);
54655465
SubstTemplateTypeParmTypes.InsertNode(SubstParm, InsertPos);
54665466
}
@@ -10090,18 +10090,18 @@ ASTContext::getDependentTemplateName(const DependentTemplateStorage &S) const {
1009010090

1009110091
TemplateName ASTContext::getSubstTemplateTemplateParm(
1009210092
TemplateName Replacement, Decl *AssociatedDecl, unsigned Index,
10093-
std::optional<unsigned> PackIndex) const {
10093+
std::optional<unsigned> PackIndex, bool Final) const {
1009410094
llvm::FoldingSetNodeID ID;
1009510095
SubstTemplateTemplateParmStorage::Profile(ID, Replacement, AssociatedDecl,
10096-
Index, PackIndex);
10096+
Index, PackIndex, Final);
1009710097

1009810098
void *insertPos = nullptr;
1009910099
SubstTemplateTemplateParmStorage *subst
1010010100
= SubstTemplateTemplateParms.FindNodeOrInsertPos(ID, insertPos);
1010110101

1010210102
if (!subst) {
1010310103
subst = new (*this) SubstTemplateTemplateParmStorage(
10104-
Replacement, AssociatedDecl, Index, PackIndex);
10104+
Replacement, AssociatedDecl, Index, PackIndex, Final);
1010510105
SubstTemplateTemplateParms.InsertNode(subst, insertPos);
1010610106
}
1010710107

@@ -14202,7 +14202,8 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
1420214202
if (PackIndex != SY->getPackIndex())
1420314203
return QualType();
1420414204
return Ctx.getSubstTemplateTypeParmType(Ctx.getQualifiedType(Underlying),
14205-
CD, Index, PackIndex);
14205+
CD, Index, PackIndex,
14206+
SX->getFinal() && SY->getFinal());
1420614207
}
1420714208
case Type::ObjCTypeParam:
1420814209
// FIXME: Try to merge these.

clang/lib/AST/ASTImporter.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1631,8 +1631,8 @@ ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmType(
16311631
return ToReplacementTypeOrErr.takeError();
16321632

16331633
return Importer.getToContext().getSubstTemplateTypeParmType(
1634-
*ToReplacementTypeOrErr, *ReplacedOrErr, T->getIndex(),
1635-
T->getPackIndex());
1634+
*ToReplacementTypeOrErr, *ReplacedOrErr, T->getIndex(), T->getPackIndex(),
1635+
T->getFinal());
16361636
}
16371637

16381638
ExpectedType ASTNodeImporter::VisitSubstTemplateTypeParmPackType(
@@ -8937,7 +8937,8 @@ ExpectedStmt ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr(
89378937

89388938
return new (Importer.getToContext()) SubstNonTypeTemplateParmExpr(
89398939
ToType, E->getValueKind(), ToExprLoc, ToReplacement, ToAssociatedDecl,
8940-
E->getIndex(), E->getPackIndex(), E->isReferenceParameter());
8940+
E->getIndex(), E->getPackIndex(), E->isReferenceParameter(),
8941+
E->getFinal());
89418942
}
89428943

89438944
ExpectedStmt ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) {
@@ -9932,7 +9933,7 @@ Expected<TemplateName> ASTImporter::Import(TemplateName From) {
99329933

99339934
return ToContext.getSubstTemplateTemplateParm(
99349935
*ReplacementOrErr, *AssociatedDeclOrErr, Subst->getIndex(),
9935-
Subst->getPackIndex());
9936+
Subst->getPackIndex(), Subst->getFinal());
99369937
}
99379938

99389939
case TemplateName::SubstTemplateTemplateParmPack: {

clang/lib/AST/ExprCXX.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1760,10 +1760,12 @@ QualType SubstNonTypeTemplateParmExpr::getParameterType(
17601760

17611761
SubstNonTypeTemplateParmPackExpr::SubstNonTypeTemplateParmPackExpr(
17621762
QualType T, ExprValueKind ValueKind, SourceLocation NameLoc,
1763-
const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index)
1763+
const TemplateArgument &ArgPack, Decl *AssociatedDecl, unsigned Index,
1764+
bool Final)
17641765
: Expr(SubstNonTypeTemplateParmPackExprClass, T, ValueKind, OK_Ordinary),
17651766
AssociatedDecl(AssociatedDecl), Arguments(ArgPack.pack_begin()),
1766-
NumArguments(ArgPack.pack_size()), Index(Index), NameLoc(NameLoc) {
1767+
NumArguments(ArgPack.pack_size()), Final(Final), Index(Index),
1768+
NameLoc(NameLoc) {
17671769
assert(AssociatedDecl != nullptr);
17681770
setDependence(ExprDependence::TypeValueInstantiation |
17691771
ExprDependence::UnexpandedPack);

clang/lib/AST/TemplateName.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,18 @@ SubstTemplateTemplateParmStorage::getParameter() const {
7777
}
7878

7979
void SubstTemplateTemplateParmStorage::Profile(llvm::FoldingSetNodeID &ID) {
80-
Profile(ID, Replacement, getAssociatedDecl(), getIndex(), getPackIndex());
80+
Profile(ID, Replacement, getAssociatedDecl(), getIndex(), getPackIndex(),
81+
getFinal());
8182
}
8283

8384
void SubstTemplateTemplateParmStorage::Profile(
8485
llvm::FoldingSetNodeID &ID, TemplateName Replacement, Decl *AssociatedDecl,
85-
unsigned Index, std::optional<unsigned> PackIndex) {
86+
unsigned Index, std::optional<unsigned> PackIndex, bool Final) {
8687
Replacement.Profile(ID);
8788
ID.AddPointer(AssociatedDecl);
8889
ID.AddInteger(Index);
8990
ID.AddInteger(PackIndex ? *PackIndex + 1 : 0);
91+
ID.AddBoolean(Final);
9092
}
9193

9294
SubstTemplateTemplateParmPackStorage::SubstTemplateTemplateParmPackStorage(

clang/lib/AST/TextNodeDumper.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1298,6 +1298,8 @@ void TextNodeDumper::dumpBareTemplateName(TemplateName TN) {
12981298
OS << " index " << STS->getIndex();
12991299
if (std::optional<unsigned int> PackIndex = STS->getPackIndex())
13001300
OS << " pack_index " << *PackIndex;
1301+
if (STS->getFinal())
1302+
OS << " final";
13011303
if (const TemplateTemplateParmDecl *P = STS->getParameter())
13021304
AddChild("parameter", [=] { Visit(P); });
13031305
dumpDeclRef(STS->getAssociatedDecl(), "associated");
@@ -2124,6 +2126,8 @@ void TextNodeDumper::VisitSubstTemplateTypeParmType(
21242126
VisitTemplateTypeParmDecl(T->getReplacedParameter());
21252127
if (auto PackIndex = T->getPackIndex())
21262128
OS << " pack_index " << *PackIndex;
2129+
if (T->getFinal())
2130+
OS << " final";
21272131
}
21282132

21292133
void TextNodeDumper::VisitSubstTemplateTypeParmPackType(

0 commit comments

Comments
 (0)