Skip to content

Commit 7275c54

Browse files
committed
[clang] Track final substitution for SubstNonTypeTemplateParmExpr nodes
1 parent c5e5008 commit 7275c54

File tree

5 files changed

+42
-28
lines changed

5 files changed

+42
-28
lines changed

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/lib/AST/ASTImporter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8945,7 +8945,8 @@ ExpectedStmt ASTNodeImporter::VisitSubstNonTypeTemplateParmExpr(
89458945

89468946
return new (Importer.getToContext()) SubstNonTypeTemplateParmExpr(
89478947
ToType, E->getValueKind(), ToExprLoc, ToReplacement, ToAssociatedDecl,
8948-
E->getIndex(), E->getPackIndex(), E->isReferenceParameter());
8948+
E->getIndex(), E->getPackIndex(), E->isReferenceParameter(),
8949+
E->getFinal());
89498950
}
89508951

89518952
ExpectedStmt ASTNodeImporter::VisitTypeTraitExpr(TypeTraitExpr *E) {

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/Sema/SemaTemplate.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7569,7 +7569,7 @@ ExprResult Sema::BuildExpressionFromDeclTemplateArgument(
75697569
ParamType->getPointeeType(), RefExpr.get()->getValueKind(),
75707570
RefExpr.get()->getExprLoc(), RefExpr.get(), VD, NTTP->getIndex(),
75717571
/*PackIndex=*/std::nullopt,
7572-
/*RefParam=*/true);
7572+
/*RefParam=*/true, /*Final=*/true);
75737573
}
75747574
}
75757575
}

clang/lib/Sema/SemaTemplateInstantiate.cpp

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1865,11 +1865,10 @@ namespace {
18651865
Sema::ExtParameterInfoBuilder &PInfos);
18661866

18671867
private:
1868-
ExprResult
1869-
transformNonTypeTemplateParmRef(Decl *AssociatedDecl,
1870-
const NonTypeTemplateParmDecl *parm,
1871-
SourceLocation loc, TemplateArgument arg,
1872-
std::optional<unsigned> PackIndex);
1868+
ExprResult transformNonTypeTemplateParmRef(
1869+
Decl *AssociatedDecl, const NonTypeTemplateParmDecl *parm,
1870+
SourceLocation loc, TemplateArgument arg,
1871+
std::optional<unsigned> PackIndex, bool Final);
18731872
};
18741873
}
18751874

@@ -2140,7 +2139,8 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
21402139
return Arg.getAsExpr();
21412140
}
21422141

2143-
auto [AssociatedDecl, _] = TemplateArgs.getAssociatedDecl(NTTP->getDepth());
2142+
auto [AssociatedDecl, Final] =
2143+
TemplateArgs.getAssociatedDecl(NTTP->getDepth());
21442144
std::optional<unsigned> PackIndex;
21452145
if (NTTP->isParameterPack()) {
21462146
assert(Arg.getKind() == TemplateArgument::Pack &&
@@ -2159,17 +2159,15 @@ TemplateInstantiator::TransformTemplateParmRefExpr(DeclRefExpr *E,
21592159
QualType ExprType = TargetType.getNonLValueExprType(SemaRef.Context);
21602160
if (TargetType->isRecordType())
21612161
ExprType.addConst();
2162-
// FIXME: Pass in Final.
21632162
return new (SemaRef.Context) SubstNonTypeTemplateParmPackExpr(
21642163
ExprType, TargetType->isReferenceType() ? VK_LValue : VK_PRValue,
2165-
E->getLocation(), Arg, AssociatedDecl, NTTP->getPosition());
2164+
E->getLocation(), Arg, AssociatedDecl, NTTP->getPosition(), Final);
21662165
}
21672166
PackIndex = getPackIndex(Arg);
21682167
Arg = getPackSubstitutedTemplateArgument(getSema(), Arg);
21692168
}
2170-
// FIXME: Don't put subst node on Final replacement.
21712169
return transformNonTypeTemplateParmRef(AssociatedDecl, NTTP, E->getLocation(),
2172-
Arg, PackIndex);
2170+
Arg, PackIndex, Final);
21732171
}
21742172

21752173
const AnnotateAttr *
@@ -2264,8 +2262,8 @@ TemplateInstantiator::TransformOpenACCRoutineDeclAttr(
22642262

22652263
ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(
22662264
Decl *AssociatedDecl, const NonTypeTemplateParmDecl *parm,
2267-
SourceLocation loc, TemplateArgument arg,
2268-
std::optional<unsigned> PackIndex) {
2265+
SourceLocation loc, TemplateArgument arg, std::optional<unsigned> PackIndex,
2266+
bool Final) {
22692267
ExprResult result;
22702268

22712269
// Determine the substituted parameter type. We can usually infer this from
@@ -2331,10 +2329,9 @@ ExprResult TemplateInstantiator::transformNonTypeTemplateParmRef(
23312329
return ExprError();
23322330

23332331
Expr *resultExpr = result.get();
2334-
// FIXME: Don't put subst node on final replacement.
23352332
return new (SemaRef.Context) SubstNonTypeTemplateParmExpr(
23362333
resultExpr->getType(), resultExpr->getValueKind(), loc, resultExpr,
2337-
AssociatedDecl, parm->getIndex(), PackIndex, refParam);
2334+
AssociatedDecl, parm->getIndex(), PackIndex, refParam, Final);
23382335
}
23392336

23402337
ExprResult
@@ -2347,10 +2344,9 @@ TemplateInstantiator::TransformSubstNonTypeTemplateParmPackExpr(
23472344

23482345
TemplateArgument Pack = E->getArgumentPack();
23492346
TemplateArgument Arg = getPackSubstitutedTemplateArgument(getSema(), Pack);
2350-
// FIXME: Don't put subst node on final replacement.
23512347
return transformNonTypeTemplateParmRef(
23522348
E->getAssociatedDecl(), E->getParameterPack(),
2353-
E->getParameterPackLocation(), Arg, getPackIndex(Pack));
2349+
E->getParameterPackLocation(), Arg, getPackIndex(Pack), E->getFinal());
23542350
}
23552351

23562352
ExprResult
@@ -2392,9 +2388,9 @@ TemplateInstantiator::TransformSubstNonTypeTemplateParmExpr(
23922388
/*PartialOrderingTTP=*/false, Sema::CTAK_Specified)
23932389
.isInvalid())
23942390
return true;
2395-
return transformNonTypeTemplateParmRef(E->getAssociatedDecl(),
2396-
E->getParameter(), E->getExprLoc(),
2397-
SugaredConverted, E->getPackIndex());
2391+
return transformNonTypeTemplateParmRef(
2392+
E->getAssociatedDecl(), E->getParameter(), E->getExprLoc(),
2393+
SugaredConverted, E->getPackIndex(), E->getFinal());
23982394
}
23992395

24002396
ExprResult TemplateInstantiator::RebuildVarDeclRefExpr(ValueDecl *PD,

0 commit comments

Comments
 (0)