Skip to content

Commit c4c2a3c

Browse files
committed
[clang] Implement sugared substitution changes to infrastructure
Implements the changes required to perform substitution with non-canonical template arguments, and to 'finalize' them by not placing 'Subst' nodes. A finalized substitution means we won't resugar them later, because these templates themselves were eagerly substituted with the intended arguments at the point of use. We may still resugar other templates used within those, though. This patch does not actually implement any uses of this functionality, those will be added in subsequent patches, so expect no changes to existing tests. Signed-off-by: Matheus Izvekov <[email protected]> Differential Revision: https://reviews.llvm.org/D134604
1 parent 5312198 commit c4c2a3c

22 files changed

+447
-289
lines changed

clang/include/clang/AST/ASTContext.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1621,7 +1621,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
16211621
Decl *AssociatedDecl, unsigned Index,
16221622
Optional<unsigned> PackIndex) const;
16231623
QualType getSubstTemplateTypeParmPackType(Decl *AssociatedDecl,
1624-
unsigned Index,
1624+
unsigned Index, bool Final,
16251625
const TemplateArgument &ArgPack);
16261626

16271627
QualType
@@ -2207,7 +2207,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
22072207
Optional<unsigned> PackIndex) const;
22082208
TemplateName getSubstTemplateTemplateParmPack(const TemplateArgument &ArgPack,
22092209
Decl *AssociatedDecl,
2210-
unsigned Index) const;
2210+
unsigned Index,
2211+
bool Final) const;
22112212

22122213
enum GetBuiltinTypeError {
22132214
/// No error

clang/include/clang/AST/PropertiesBase.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -730,8 +730,11 @@ let Class = PropertyTypeCase<TemplateName, "SubstTemplateTemplateParmPack"> in {
730730
def : Property<"index", UInt32> {
731731
let Read = [{ parm->getIndex() }];
732732
}
733+
def : Property<"final", Bool> {
734+
let Read = [{ parm->getFinal() }];
735+
}
733736
def : Creator<[{
734-
return ctx.getSubstTemplateTemplateParmPack(argumentPack, associatedDecl, index);
737+
return ctx.getSubstTemplateTemplateParmPack(argumentPack, associatedDecl, index, final);
735738
}]>;
736739
}
737740

clang/include/clang/AST/TemplateName.h

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -139,25 +139,24 @@ class OverloadedTemplateStorage : public UncommonTemplateNameStorage {
139139
class SubstTemplateTemplateParmPackStorage : public UncommonTemplateNameStorage,
140140
public llvm::FoldingSetNode {
141141
const TemplateArgument *Arguments;
142-
Decl *AssociatedDecl;
142+
llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
143143

144144
public:
145145
SubstTemplateTemplateParmPackStorage(ArrayRef<TemplateArgument> ArgPack,
146-
Decl *AssociatedDecl, unsigned Index)
147-
: UncommonTemplateNameStorage(SubstTemplateTemplateParmPack, Index,
148-
ArgPack.size()),
149-
Arguments(ArgPack.data()), AssociatedDecl(AssociatedDecl) {
150-
assert(AssociatedDecl != nullptr);
151-
}
146+
Decl *AssociatedDecl, unsigned Index,
147+
bool Final);
152148

153149
/// A template-like entity which owns the whole pattern being substituted.
154150
/// This will own a set of template parameters.
155-
Decl *getAssociatedDecl() const { return AssociatedDecl; }
151+
Decl *getAssociatedDecl() const;
156152

157153
/// Returns the index of the replaced parameter in the associated declaration.
158154
/// This should match the result of `getParameterPack()->getIndex()`.
159155
unsigned getIndex() const { return Bits.Index; }
160156

157+
// When true the substitution will be 'Final' (subst node won't be placed).
158+
bool getFinal() const;
159+
161160
/// Retrieve the template template parameter pack being substituted.
162161
TemplateTemplateParmDecl *getParameterPack() const;
163162

@@ -169,7 +168,7 @@ class SubstTemplateTemplateParmPackStorage : public UncommonTemplateNameStorage,
169168

170169
static void Profile(llvm::FoldingSetNodeID &ID, ASTContext &Context,
171170
const TemplateArgument &ArgPack, Decl *AssociatedDecl,
172-
unsigned Index);
171+
unsigned Index, bool Final);
173172
};
174173

175174
/// Represents a C++ template name within the type system.

clang/include/clang/AST/Type.h

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5158,10 +5158,10 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
51585158
/// parameter pack is instantiated with.
51595159
const TemplateArgument *Arguments;
51605160

5161-
Decl *AssociatedDecl;
5161+
llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
51625162

51635163
SubstTemplateTypeParmPackType(QualType Canon, Decl *AssociatedDecl,
5164-
unsigned Index,
5164+
unsigned Index, bool Final,
51655165
const TemplateArgument &ArgPack);
51665166

51675167
public:
@@ -5170,7 +5170,7 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
51705170
/// A template-like entity which owns the whole pattern being substituted.
51715171
/// This will usually own a set of template parameters, or in some
51725172
/// cases might even be a template parameter itself.
5173-
Decl *getAssociatedDecl() const { return AssociatedDecl; }
5173+
Decl *getAssociatedDecl() const;
51745174

51755175
/// Gets the template parameter declaration that was substituted for.
51765176
const TemplateTypeParmDecl *getReplacedParameter() const;
@@ -5179,6 +5179,9 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
51795179
/// This should match the result of `getReplacedParameter()->getIndex()`.
51805180
unsigned getIndex() const { return SubstTemplateTypeParmPackTypeBits.Index; }
51815181

5182+
// When true the substitution will be 'Final' (subst node won't be placed).
5183+
bool getFinal() const;
5184+
51825185
unsigned getNumArgs() const {
51835186
return SubstTemplateTypeParmPackTypeBits.NumArgs;
51845187
}
@@ -5190,7 +5193,8 @@ class SubstTemplateTypeParmPackType : public Type, public llvm::FoldingSetNode {
51905193

51915194
void Profile(llvm::FoldingSetNodeID &ID);
51925195
static void Profile(llvm::FoldingSetNodeID &ID, const Decl *AssociatedDecl,
5193-
unsigned Index, const TemplateArgument &ArgPack);
5196+
unsigned Index, bool Final,
5197+
const TemplateArgument &ArgPack);
51945198

51955199
static bool classof(const Type *T) {
51965200
return T->getTypeClass() == SubstTemplateTypeParmPack;

clang/include/clang/AST/TypeProperties.td

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -773,13 +773,16 @@ let Class = SubstTemplateTypeParmPackType in {
773773
def : Property<"Index", UInt32> {
774774
let Read = [{ node->getIndex() }];
775775
}
776+
def : Property<"Final", Bool> {
777+
let Read = [{ node->getFinal() }];
778+
}
776779
def : Property<"replacementPack", TemplateArgument> {
777780
let Read = [{ node->getArgumentPack() }];
778781
}
779782

780783
def : Creator<[{
781784
return ctx.getSubstTemplateTypeParmPackType(
782-
associatedDecl, Index, replacementPack);
785+
associatedDecl, Index, Final, replacementPack);
783786
}]>;
784787
}
785788

clang/include/clang/Sema/Sema.h

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9074,10 +9074,12 @@ class Sema final {
90749074
// C++ Template Instantiation
90759075
//
90769076

9077-
MultiLevelTemplateArgumentList getTemplateInstantiationArgs(
9078-
const NamedDecl *D, const TemplateArgumentList *Innermost = nullptr,
9079-
bool RelativeToPrimary = false, const FunctionDecl *Pattern = nullptr,
9080-
bool ForConstraintInstantiation = false);
9077+
MultiLevelTemplateArgumentList
9078+
getTemplateInstantiationArgs(const NamedDecl *D, bool Final = false,
9079+
const TemplateArgumentList *Innermost = nullptr,
9080+
bool RelativeToPrimary = false,
9081+
const FunctionDecl *Pattern = nullptr,
9082+
bool ForConstraintInstantiation = false);
90819083

90829084
/// A context in which code is being synthesized (where a source location
90839085
/// alone is not sufficient to identify the context). This covers template
@@ -10171,16 +10173,12 @@ class Sema final {
1017110173
bool FailOnError = false);
1017210174

1017310175
/// Build an Objective-C object pointer type.
10174-
QualType BuildObjCObjectType(QualType BaseType,
10175-
SourceLocation Loc,
10176-
SourceLocation TypeArgsLAngleLoc,
10177-
ArrayRef<TypeSourceInfo *> TypeArgs,
10178-
SourceLocation TypeArgsRAngleLoc,
10179-
SourceLocation ProtocolLAngleLoc,
10180-
ArrayRef<ObjCProtocolDecl *> Protocols,
10181-
ArrayRef<SourceLocation> ProtocolLocs,
10182-
SourceLocation ProtocolRAngleLoc,
10183-
bool FailOnError = false);
10176+
QualType BuildObjCObjectType(
10177+
QualType BaseType, SourceLocation Loc, SourceLocation TypeArgsLAngleLoc,
10178+
ArrayRef<TypeSourceInfo *> TypeArgs, SourceLocation TypeArgsRAngleLoc,
10179+
SourceLocation ProtocolLAngleLoc, ArrayRef<ObjCProtocolDecl *> Protocols,
10180+
ArrayRef<SourceLocation> ProtocolLocs, SourceLocation ProtocolRAngleLoc,
10181+
bool FailOnError, bool Rebuilding);
1018410182

1018510183
/// Ensure attributes are consistent with type.
1018610184
/// \param [in, out] Attributes The attributes to check; they will

clang/include/clang/Sema/Template.h

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ enum class TemplateSubstitutionKind : char {
7777

7878
using ArgList = ArrayRef<TemplateArgument>;
7979
struct ArgumentListLevel {
80-
Decl *AssociatedDecl;
80+
llvm::PointerIntPair<Decl *, 1, bool> AssociatedDeclAndFinal;
8181
ArgList Args;
8282
};
8383
using ContainerType = SmallVector<ArgumentListLevel, 4>;
@@ -101,8 +101,8 @@ enum class TemplateSubstitutionKind : char {
101101
MultiLevelTemplateArgumentList() = default;
102102

103103
/// Construct a single-level template argument list.
104-
MultiLevelTemplateArgumentList(Decl *D, ArgList Args) {
105-
addOuterTemplateArguments(D, Args);
104+
MultiLevelTemplateArgumentList(Decl *D, ArgList Args, bool Final) {
105+
addOuterTemplateArguments(D, Args, Final);
106106
}
107107

108108
void setKind(TemplateSubstitutionKind K) { Kind = K; }
@@ -160,9 +160,11 @@ enum class TemplateSubstitutionKind : char {
160160
/// A template-like entity which owns the whole pattern being substituted.
161161
/// This will usually own a set of template parameters, or in some
162162
/// cases might even be a template parameter itself.
163-
Decl *getAssociatedDecl(unsigned Depth) const {
163+
std::pair<Decl *, bool> getAssociatedDecl(unsigned Depth) const {
164164
assert(NumRetainedOuterLevels <= Depth && Depth < getNumLevels());
165-
return TemplateArgumentLists[getNumLevels() - Depth - 1].AssociatedDecl;
165+
auto AD = TemplateArgumentLists[getNumLevels() - Depth - 1]
166+
.AssociatedDeclAndFinal;
167+
return {AD.getPointer(), AD.getInt()};
166168
}
167169

168170
/// Determine whether there is a non-NULL template argument at the
@@ -202,21 +204,22 @@ enum class TemplateSubstitutionKind : char {
202204

203205
/// Add a new outmost level to the multi-level template argument
204206
/// list.
205-
void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args) {
207+
/// A 'Final' substitution means that Subst* nodes won't be built
208+
/// for the replacements.
209+
void addOuterTemplateArguments(Decl *AssociatedDecl, ArgList Args,
210+
bool Final) {
206211
assert(!NumRetainedOuterLevels &&
207212
"substituted args outside retained args?");
208213
assert(getKind() == TemplateSubstitutionKind::Specialization);
209-
assert(AssociatedDecl != nullptr || Args.size() == 0);
210214
TemplateArgumentLists.push_back(
211-
{AssociatedDecl ? AssociatedDecl->getCanonicalDecl() : nullptr,
212-
Args});
215+
{{AssociatedDecl->getCanonicalDecl(), Final}, Args});
213216
}
214217

215218
void addOuterTemplateArguments(ArgList Args) {
216219
assert(!NumRetainedOuterLevels &&
217220
"substituted args outside retained args?");
218221
assert(getKind() == TemplateSubstitutionKind::Rewrite);
219-
TemplateArgumentLists.push_back({nullptr, Args});
222+
TemplateArgumentLists.push_back({{}, Args});
220223
}
221224

222225
void addOuterTemplateArguments(llvm::NoneType) {

0 commit comments

Comments
 (0)