Skip to content

Commit 3996f1f

Browse files
committed
[clang] remove isDefaulted bit from TemplateArgument
The IsDefaulted bit being part of a canonical TemplateArgument doesn't make sense, as that information is not information a canonical type should have. In C++, all template specialization types for ther same template are the same if the full list of template arguments is the same, an argument being defaulted or not doesn't matter. Moreover, this information is already available in the sugared template specialization type, in the sense that, taking the as-written list and matching it up to the template parameters, any parameters which are left without a corresponding template argument must have been defaulted. This patch besides removing that bit, changes the current DebugInfo users to derive that information from the as-written argument list. And it goes a little beyond that by wiring up the actual sugared TemplateArguments, so the Debug Info produced is also richer. This patch is a performance improvement, as the TemplateArgument is one of the hottest data structures for C++ compilation: The small regression on `-O0 -g` test is explained by the increased amount of debug info generated.
1 parent 0c28482 commit 3996f1f

20 files changed

+214
-303
lines changed

clang/include/clang/AST/PropertiesBase.td

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -785,14 +785,9 @@ let Class = PropertyTypeCase<TemplateArgument, "Null"> in {
785785
}]>;
786786
}
787787
let Class = PropertyTypeCase<TemplateArgument, "Type"> in {
788-
def : Property<"type", QualType> {
789-
let Read = [{ node.getAsType() }];
790-
}
791-
def : Property<"isDefaulted", Bool> {
792-
let Read = [{ node.getIsDefaulted() }];
793-
}
788+
def : Property<"type", QualType> { let Read = [{ node.getAsType() }]; }
794789
def : Creator<[{
795-
return TemplateArgument(type, /* isNullPtr */ false, isDefaulted);
790+
return TemplateArgument(type, /* isNullPtr=*/false);
796791
}]>;
797792
}
798793
let Class = PropertyTypeCase<TemplateArgument, "Declaration"> in {
@@ -802,36 +797,23 @@ let Class = PropertyTypeCase<TemplateArgument, "Declaration"> in {
802797
def : Property<"parameterType", QualType> {
803798
let Read = [{ node.getParamTypeForDecl() }];
804799
}
805-
def : Property<"isDefaulted", Bool> {
806-
let Read = [{ node.getIsDefaulted() }];
807-
}
808800
def : Creator<[{
809-
return TemplateArgument(declaration, parameterType, isDefaulted);
801+
return TemplateArgument(declaration, parameterType);
810802
}]>;
811803
}
812804
let Class = PropertyTypeCase<TemplateArgument, "NullPtr"> in {
813-
def : Property<"type", QualType> {
814-
let Read = [{ node.getNullPtrType() }];
815-
}
816-
def : Property<"isDefaulted", Bool> {
817-
let Read = [{ node.getIsDefaulted() }];
818-
}
805+
def : Property<"type", QualType> { let Read = [{ node.getNullPtrType() }]; }
819806
def : Creator<[{
820-
return TemplateArgument(type, /*nullptr*/ true, isDefaulted);
807+
return TemplateArgument(type, /*IsNullPtr=*/true);
821808
}]>;
822809
}
823810
let Class = PropertyTypeCase<TemplateArgument, "Integral"> in {
824811
def : Property<"value", APSInt> {
825812
let Read = [{ node.getAsIntegral() }];
826813
}
827-
def : Property<"type", QualType> {
828-
let Read = [{ node.getIntegralType() }];
829-
}
830-
def : Property<"isDefaulted", Bool> {
831-
let Read = [{ node.getIsDefaulted() }];
832-
}
814+
def : Property<"type", QualType> { let Read = [{ node.getIntegralType() }]; }
833815
def : Creator<[{
834-
return TemplateArgument(ctx, value, type, isDefaulted);
816+
return TemplateArgument(ctx, value, type);
835817
}]>;
836818
}
837819
let Class = PropertyTypeCase<TemplateArgument, "StructuralValue"> in {
@@ -841,22 +823,16 @@ let Class = PropertyTypeCase<TemplateArgument, "StructuralValue"> in {
841823
def : Property<"type", QualType> {
842824
let Read = [{ node.getStructuralValueType() }];
843825
}
844-
def : Property<"isDefaulted", Bool> {
845-
let Read = [{ node.getIsDefaulted() }];
846-
}
847826
def : Creator<[{
848-
return TemplateArgument(ctx, type, value, isDefaulted);
827+
return TemplateArgument(ctx, type, value);
849828
}]>;
850829
}
851830
let Class = PropertyTypeCase<TemplateArgument, "Template"> in {
852831
def : Property<"name", TemplateName> {
853832
let Read = [{ node.getAsTemplateOrTemplatePattern() }];
854833
}
855-
def : Property<"isDefaulted", Bool> {
856-
let Read = [{ node.getIsDefaulted() }];
857-
}
858834
def : Creator<[{
859-
return TemplateArgument(name, isDefaulted);
835+
return TemplateArgument(name);
860836
}]>;
861837
}
862838
let Class = PropertyTypeCase<TemplateArgument, "TemplateExpansion"> in {
@@ -868,11 +844,8 @@ let Class = PropertyTypeCase<TemplateArgument, "TemplateExpansion"> in {
868844
node.getNumTemplateExpansions()
869845
}];
870846
}
871-
def : Property<"isDefaulted", Bool> {
872-
let Read = [{ node.getIsDefaulted() }];
873-
}
874847
def : Creator<[{
875-
return TemplateArgument(name, numExpansions, isDefaulted);
848+
return TemplateArgument(name, numExpansions);
876849
}]>;
877850
}
878851
let Class = PropertyTypeCase<TemplateArgument, "Expression"> in {
@@ -882,11 +855,8 @@ let Class = PropertyTypeCase<TemplateArgument, "Expression"> in {
882855
def : Property<"IsCanonical", Bool> {
883856
let Read = [{ node.isCanonicalExpr() }];
884857
}
885-
def : Property<"isDefaulted", Bool> {
886-
let Read = [{ node.getIsDefaulted() }];
887-
}
888858
def : Creator<[{
889-
return TemplateArgument(expression, IsCanonical, isDefaulted);
859+
return TemplateArgument(expression, IsCanonical);
890860
}]>;
891861
}
892862
let Class = PropertyTypeCase<TemplateArgument, "Pack"> in {

clang/include/clang/AST/TemplateBase.h

Lines changed: 26 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -113,22 +113,18 @@ class TemplateArgument {
113113
struct DA {
114114
LLVM_PREFERRED_TYPE(ArgKind)
115115
unsigned Kind : 31;
116-
LLVM_PREFERRED_TYPE(bool)
117-
unsigned IsDefaulted : 1;
118116
void *QT;
119117
ValueDecl *D;
120118
};
121119
struct I {
122120
LLVM_PREFERRED_TYPE(ArgKind)
123121
unsigned Kind : 31;
124122
LLVM_PREFERRED_TYPE(bool)
125-
unsigned IsDefaulted : 1;
123+
unsigned IsUnsigned : 1;
126124
// We store a decomposed APSInt with the data allocated by ASTContext if
127125
// BitWidth > 64. The memory may be shared between multiple
128126
// TemplateArgument instances.
129127
unsigned BitWidth : 31;
130-
LLVM_PREFERRED_TYPE(bool)
131-
unsigned IsUnsigned : 1;
132128
union {
133129
/// Used to store the <= 64 bits integer value.
134130
uint64_t VAL;
@@ -141,33 +137,25 @@ class TemplateArgument {
141137
struct V {
142138
LLVM_PREFERRED_TYPE(ArgKind)
143139
unsigned Kind : 31;
144-
LLVM_PREFERRED_TYPE(bool)
145-
unsigned IsDefaulted : 1;
146140
APValue *Value;
147141
void *Type;
148142
};
149143
struct A {
150144
LLVM_PREFERRED_TYPE(ArgKind)
151145
unsigned Kind : 31;
152-
LLVM_PREFERRED_TYPE(bool)
153-
unsigned IsDefaulted : 1;
154146
unsigned NumArgs;
155147
const TemplateArgument *Args;
156148
};
157149
struct TA {
158150
LLVM_PREFERRED_TYPE(ArgKind)
159151
unsigned Kind : 31;
160-
LLVM_PREFERRED_TYPE(bool)
161-
unsigned IsDefaulted : 1;
162152
UnsignedOrNone NumExpansions;
163153
void *Name;
164154
};
165155
struct TV {
166156
LLVM_PREFERRED_TYPE(ArgKind)
167157
unsigned Kind : 31;
168158
LLVM_PREFERRED_TYPE(bool)
169-
unsigned IsDefaulted : 1;
170-
LLVM_PREFERRED_TYPE(bool)
171159
unsigned IsCanonicalExpr : 1;
172160
uintptr_t V;
173161
};
@@ -180,38 +168,46 @@ class TemplateArgument {
180168
struct TV TypeOrValue;
181169
};
182170

183-
void initFromType(QualType T, bool IsNullPtr, bool IsDefaulted);
184-
void initFromDeclaration(ValueDecl *D, QualType QT, bool IsDefaulted);
171+
void initFromType(QualType T, bool IsNullPtr) {
172+
TypeOrValue.Kind = IsNullPtr ? NullPtr : Type;
173+
TypeOrValue.V = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
174+
}
175+
176+
void initFromDeclaration(ValueDecl *D, QualType QT) {
177+
assert(D && "Expected decl");
178+
DeclArg.Kind = Declaration;
179+
DeclArg.QT = QT.getAsOpaquePtr();
180+
DeclArg.D = D;
181+
}
182+
185183
void initFromIntegral(const ASTContext &Ctx, const llvm::APSInt &Value,
186-
QualType Type, bool IsDefaulted);
184+
QualType Type);
187185
void initFromStructural(const ASTContext &Ctx, QualType Type,
188-
const APValue &V, bool IsDefaulted);
186+
const APValue &V);
189187

190188
public:
191189
/// Construct an empty, invalid template argument.
192190
constexpr TemplateArgument()
193-
: TypeOrValue{Null, /*IsDefaulted=*/0, /*IsCanonicalExpr=*/0, /*V=*/0} {}
191+
: TypeOrValue{Null, /*IsCanonicalExpr=*/false, /*V=*/0} {}
194192

195193
/// Construct a template type argument.
196-
TemplateArgument(QualType T, bool isNullPtr = false,
197-
bool IsDefaulted = false) {
198-
initFromType(T, isNullPtr, IsDefaulted);
194+
TemplateArgument(QualType T, bool isNullPtr = false) {
195+
initFromType(T, isNullPtr);
199196
}
200197

201198
/// Construct a template argument that refers to a (non-dependent)
202199
/// declaration.
203-
TemplateArgument(ValueDecl *D, QualType QT, bool IsDefaulted = false) {
204-
initFromDeclaration(D, QT, IsDefaulted);
205-
}
200+
TemplateArgument(ValueDecl *D, QualType QT) { initFromDeclaration(D, QT); }
206201

207202
/// Construct an integral constant template argument. The memory to
208203
/// store the value is allocated with Ctx.
209204
TemplateArgument(const ASTContext &Ctx, const llvm::APSInt &Value,
210-
QualType Type, bool IsDefaulted = false);
205+
QualType Type) {
206+
initFromIntegral(Ctx, Value, Type);
207+
}
211208

212209
/// Construct a template argument from an arbitrary constant value.
213-
TemplateArgument(const ASTContext &Ctx, QualType Type, const APValue &Value,
214-
bool IsDefaulted = false);
210+
TemplateArgument(const ASTContext &Ctx, QualType Type, const APValue &Value);
215211

216212
/// Construct an integral constant template argument with the same
217213
/// value as Other but a different type.
@@ -228,12 +224,8 @@ class TemplateArgument {
228224
/// is taken.
229225
///
230226
/// \param Name The template name.
231-
///
232-
/// \param IsDefaulted If 'true', implies that this TemplateArgument
233-
/// corresponds to a default template parameter
234-
TemplateArgument(TemplateName Name, bool IsDefaulted = false) {
227+
TemplateArgument(TemplateName Name) {
235228
TemplateArg.Kind = Template;
236-
TemplateArg.IsDefaulted = IsDefaulted;
237229
TemplateArg.Name = Name.getAsVoidPointer();
238230
TemplateArg.NumExpansions = std::nullopt;
239231
}
@@ -249,13 +241,8 @@ class TemplateArgument {
249241
///
250242
/// \param NumExpansions The number of expansions that will be generated by
251243
/// instantiating
252-
///
253-
/// \param IsDefaulted If 'true', implies that this TemplateArgument
254-
/// corresponds to a default template parameter
255-
TemplateArgument(TemplateName Name, UnsignedOrNone NumExpansions,
256-
bool IsDefaulted = false) {
244+
TemplateArgument(TemplateName Name, UnsignedOrNone NumExpansions) {
257245
TemplateArg.Kind = TemplateExpansion;
258-
TemplateArg.IsDefaulted = IsDefaulted;
259246
TemplateArg.Name = Name.getAsVoidPointer();
260247
TemplateArg.NumExpansions = NumExpansions;
261248
}
@@ -265,9 +252,8 @@ class TemplateArgument {
265252
/// This form of template argument only occurs in template argument
266253
/// lists used for dependent types and for expression; it will not
267254
/// occur in a non-dependent, canonical template argument list.
268-
TemplateArgument(Expr *E, bool IsCanonical, bool IsDefaulted = false) {
255+
TemplateArgument(Expr *E, bool IsCanonical) {
269256
TypeOrValue.Kind = Expression;
270-
TypeOrValue.IsDefaulted = IsDefaulted;
271257
TypeOrValue.IsCanonicalExpr = IsCanonical;
272258
TypeOrValue.V = reinterpret_cast<uintptr_t>(E);
273259
}
@@ -278,7 +264,6 @@ class TemplateArgument {
278264
/// outlives the TemplateArgument itself.
279265
explicit TemplateArgument(ArrayRef<TemplateArgument> Args) {
280266
this->Args.Kind = Pack;
281-
this->Args.IsDefaulted = false;
282267
this->Args.Args = Args.data();
283268
this->Args.NumArgs = Args.size();
284269
}
@@ -387,14 +372,6 @@ class TemplateArgument {
387372
Integer.Type = T.getAsOpaquePtr();
388373
}
389374

390-
/// Set to 'true' if this TemplateArgument corresponds to a
391-
/// default template parameter.
392-
void setIsDefaulted(bool v) { TypeOrValue.IsDefaulted = v; }
393-
394-
/// If returns 'true', this TemplateArgument corresponds to a
395-
/// default template parameter.
396-
bool getIsDefaulted() const { return (bool)TypeOrValue.IsDefaulted; }
397-
398375
/// Get the value of a StructuralValue.
399376
const APValue &getAsStructuralValue() const { return *Value.Value; }
400377

clang/lib/AST/ASTContext.cpp

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7945,39 +7945,36 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
79457945
return Arg;
79467946

79477947
case TemplateArgument::Expression:
7948-
return TemplateArgument(Arg.getAsExpr(), /*IsCanonical=*/true,
7949-
Arg.getIsDefaulted());
7948+
return TemplateArgument(Arg.getAsExpr(), /*IsCanonical=*/true);
79507949

79517950
case TemplateArgument::Declaration: {
79527951
auto *D = cast<ValueDecl>(Arg.getAsDecl()->getCanonicalDecl());
7953-
return TemplateArgument(D, getCanonicalType(Arg.getParamTypeForDecl()),
7954-
Arg.getIsDefaulted());
7952+
return TemplateArgument(D, getCanonicalType(Arg.getParamTypeForDecl()));
79557953
}
79567954

79577955
case TemplateArgument::NullPtr:
79587956
return TemplateArgument(getCanonicalType(Arg.getNullPtrType()),
7959-
/*isNullPtr*/ true, Arg.getIsDefaulted());
7957+
/*isNullPtr=*/true);
79607958

79617959
case TemplateArgument::Template:
7962-
return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate()),
7963-
Arg.getIsDefaulted());
7960+
return TemplateArgument(getCanonicalTemplateName(Arg.getAsTemplate()));
79647961

79657962
case TemplateArgument::TemplateExpansion:
79667963
return TemplateArgument(
79677964
getCanonicalTemplateName(Arg.getAsTemplateOrTemplatePattern()),
7968-
Arg.getNumTemplateExpansions(), Arg.getIsDefaulted());
7965+
Arg.getNumTemplateExpansions());
79697966

79707967
case TemplateArgument::Integral:
79717968
return TemplateArgument(Arg, getCanonicalType(Arg.getIntegralType()));
79727969

79737970
case TemplateArgument::StructuralValue:
79747971
return TemplateArgument(*this,
79757972
getCanonicalType(Arg.getStructuralValueType()),
7976-
Arg.getAsStructuralValue(), Arg.getIsDefaulted());
7973+
Arg.getAsStructuralValue());
79777974

79787975
case TemplateArgument::Type:
79797976
return TemplateArgument(getCanonicalType(Arg.getAsType()),
7980-
/*isNullPtr*/ false, Arg.getIsDefaulted());
7977+
/*isNullPtr=*/false);
79817978

79827979
case TemplateArgument::Pack: {
79837980
bool AnyNonCanonArgs = false;
@@ -7987,7 +7984,6 @@ ASTContext::getCanonicalTemplateArgument(const TemplateArgument &Arg) const {
79877984
return Arg;
79887985
auto NewArg = TemplateArgument::CreatePackCopy(
79897986
const_cast<ASTContext &>(*this), CanonArgs);
7990-
NewArg.setIsDefaulted(Arg.getIsDefaulted());
79917987
return NewArg;
79927988
}
79937989
}

0 commit comments

Comments
 (0)