Skip to content

Commit c2b437d

Browse files
Awanish PandeySouraVX
authored andcommitted
[DebugInfo][clang][DWARF5]: Added support for debuginfo generation for defaulted parameters
in C++ templates. Summary: This patch adds support for debuginfo generation for defaulted parameters in clang and also extends corresponding DebugMetadata/IR to support this feature. Reviewers: probinson, aprantl, dblaikie Reviewed By: aprantl, dblaikie Differential Revision: https://reviews.llvm.org/D73462
1 parent daab6ad commit c2b437d

File tree

13 files changed

+296
-94
lines changed

13 files changed

+296
-94
lines changed

clang/lib/CodeGen/CGDebugInfo.cpp

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1787,18 +1787,36 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList,
17871787
for (unsigned i = 0, e = TAList.size(); i != e; ++i) {
17881788
const TemplateArgument &TA = TAList[i];
17891789
StringRef Name;
1790+
bool defaultParameter = false;
17901791
if (TPList)
17911792
Name = TPList->getParam(i)->getName();
17921793
switch (TA.getKind()) {
17931794
case TemplateArgument::Type: {
17941795
llvm::DIType *TTy = getOrCreateType(TA.getAsType(), Unit);
1795-
TemplateParams.push_back(
1796-
DBuilder.createTemplateTypeParameter(TheCU, Name, TTy));
1796+
1797+
if (TPList)
1798+
if (auto *templateType =
1799+
dyn_cast_or_null<TemplateTypeParmDecl>(TPList->getParam(i)))
1800+
if (templateType->hasDefaultArgument())
1801+
defaultParameter =
1802+
templateType->getDefaultArgument() == TA.getAsType();
1803+
1804+
TemplateParams.push_back(DBuilder.createTemplateTypeParameter(
1805+
TheCU, Name, TTy, defaultParameter));
1806+
17971807
} break;
17981808
case TemplateArgument::Integral: {
17991809
llvm::DIType *TTy = getOrCreateType(TA.getIntegralType(), Unit);
1810+
if (TPList)
1811+
if (auto *templateType =
1812+
dyn_cast_or_null<NonTypeTemplateParmDecl>(TPList->getParam(i)))
1813+
if (templateType->hasDefaultArgument())
1814+
defaultParameter =
1815+
templateType->getDefaultArgument()->EvaluateKnownConstInt(
1816+
CGM.getContext()) == TA.getAsIntegral();
1817+
18001818
TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1801-
TheCU, Name, TTy,
1819+
TheCU, Name, TTy, defaultParameter,
18021820
llvm::ConstantInt::get(CGM.getLLVMContext(), TA.getAsIntegral())));
18031821
} break;
18041822
case TemplateArgument::Declaration: {
@@ -1837,7 +1855,7 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList,
18371855
V = V->stripPointerCasts();
18381856
}
18391857
TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1840-
TheCU, Name, TTy, cast_or_null<llvm::Constant>(V)));
1858+
TheCU, Name, TTy, defaultParameter, cast_or_null<llvm::Constant>(V)));
18411859
} break;
18421860
case TemplateArgument::NullPtr: {
18431861
QualType T = TA.getNullPtrType();
@@ -1855,8 +1873,8 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList,
18551873
V = CGM.getCXXABI().EmitNullMemberPointer(MPT);
18561874
if (!V)
18571875
V = llvm::ConstantInt::get(CGM.Int8Ty, 0);
1858-
TemplateParams.push_back(
1859-
DBuilder.createTemplateValueParameter(TheCU, Name, TTy, V));
1876+
TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1877+
TheCU, Name, TTy, defaultParameter, V));
18601878
} break;
18611879
case TemplateArgument::Template:
18621880
TemplateParams.push_back(DBuilder.createTemplateTemplateParameter(
@@ -1877,7 +1895,7 @@ CGDebugInfo::CollectTemplateParams(const TemplateParameterList *TPList,
18771895
assert(V && "Expression in template argument isn't constant");
18781896
llvm::DIType *TTy = getOrCreateType(T, Unit);
18791897
TemplateParams.push_back(DBuilder.createTemplateValueParameter(
1880-
TheCU, Name, TTy, V->stripPointerCasts()));
1898+
TheCU, Name, TTy, defaultParameter, V->stripPointerCasts()));
18811899
} break;
18821900
// And the following should never occur:
18831901
case TemplateArgument::TemplateExpansion:

llvm/include/llvm/IR/DIBuilder.h

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -443,19 +443,22 @@ namespace llvm {
443443
/// \param Scope Scope in which this type is defined.
444444
/// \param Name Type parameter name.
445445
/// \param Ty Parameter type.
446-
DITemplateTypeParameter *
447-
createTemplateTypeParameter(DIScope *Scope, StringRef Name, DIType *Ty);
446+
/// \param IsDefault Parameter is default or not
447+
DITemplateTypeParameter *createTemplateTypeParameter(DIScope *Scope,
448+
StringRef Name,
449+
DIType *Ty,
450+
bool IsDefault);
448451

449452
/// Create debugging information for template
450453
/// value parameter.
451454
/// \param Scope Scope in which this type is defined.
452455
/// \param Name Value parameter name.
453456
/// \param Ty Parameter type.
457+
/// \param IsDefault Parameter is default or not
454458
/// \param Val Constant parameter value.
455-
DITemplateValueParameter *createTemplateValueParameter(DIScope *Scope,
456-
StringRef Name,
457-
DIType *Ty,
458-
Constant *Val);
459+
DITemplateValueParameter *
460+
createTemplateValueParameter(DIScope *Scope, StringRef Name, DIType *Ty,
461+
bool IsDefault, Constant *Val);
459462

460463
/// Create debugging information for a template template parameter.
461464
/// \param Scope Scope in which this type is defined.

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 36 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2131,9 +2131,11 @@ class DIModule : public DIScope {
21312131
/// Base class for template parameters.
21322132
class DITemplateParameter : public DINode {
21332133
protected:
2134+
bool IsDefault;
2135+
21342136
DITemplateParameter(LLVMContext &Context, unsigned ID, StorageType Storage,
2135-
unsigned Tag, ArrayRef<Metadata *> Ops)
2136-
: DINode(Context, ID, Storage, Tag, Ops) {}
2137+
unsigned Tag, bool IsDefault, ArrayRef<Metadata *> Ops)
2138+
: DINode(Context, ID, Storage, Tag, Ops), IsDefault(IsDefault) {}
21372139
~DITemplateParameter() = default;
21382140

21392141
public:
@@ -2142,6 +2144,7 @@ class DITemplateParameter : public DINode {
21422144

21432145
MDString *getRawName() const { return getOperandAs<MDString>(0); }
21442146
Metadata *getRawType() const { return getOperand(1); }
2147+
bool isDefault() const { return IsDefault; }
21452148

21462149
static bool classof(const Metadata *MD) {
21472150
return MD->getMetadataID() == DITemplateTypeParameterKind ||
@@ -2154,30 +2157,35 @@ class DITemplateTypeParameter : public DITemplateParameter {
21542157
friend class MDNode;
21552158

21562159
DITemplateTypeParameter(LLVMContext &Context, StorageType Storage,
2157-
ArrayRef<Metadata *> Ops)
2160+
bool IsDefault, ArrayRef<Metadata *> Ops)
21582161
: DITemplateParameter(Context, DITemplateTypeParameterKind, Storage,
2159-
dwarf::DW_TAG_template_type_parameter, Ops) {}
2162+
dwarf::DW_TAG_template_type_parameter, IsDefault,
2163+
Ops) {}
21602164
~DITemplateTypeParameter() = default;
21612165

21622166
static DITemplateTypeParameter *getImpl(LLVMContext &Context, StringRef Name,
2163-
DIType *Type, StorageType Storage,
2167+
DIType *Type, bool IsDefault,
2168+
StorageType Storage,
21642169
bool ShouldCreate = true) {
2165-
return getImpl(Context, getCanonicalMDString(Context, Name), Type, Storage,
2166-
ShouldCreate);
2170+
return getImpl(Context, getCanonicalMDString(Context, Name), Type,
2171+
IsDefault, Storage, ShouldCreate);
21672172
}
21682173
static DITemplateTypeParameter *getImpl(LLVMContext &Context, MDString *Name,
2169-
Metadata *Type, StorageType Storage,
2174+
Metadata *Type, bool IsDefault,
2175+
StorageType Storage,
21702176
bool ShouldCreate = true);
21712177

21722178
TempDITemplateTypeParameter cloneImpl() const {
2173-
return getTemporary(getContext(), getName(), getType());
2179+
return getTemporary(getContext(), getName(), getType(), isDefault());
21742180
}
21752181

21762182
public:
2177-
DEFINE_MDNODE_GET(DITemplateTypeParameter, (StringRef Name, DIType *Type),
2178-
(Name, Type))
2179-
DEFINE_MDNODE_GET(DITemplateTypeParameter, (MDString * Name, Metadata *Type),
2180-
(Name, Type))
2183+
DEFINE_MDNODE_GET(DITemplateTypeParameter,
2184+
(StringRef Name, DIType *Type, bool IsDefault),
2185+
(Name, Type, IsDefault))
2186+
DEFINE_MDNODE_GET(DITemplateTypeParameter,
2187+
(MDString *Name, Metadata *Type, bool IsDefault),
2188+
(Name, Type, IsDefault))
21812189

21822190
TempDITemplateTypeParameter clone() const { return cloneImpl(); }
21832191

@@ -2191,36 +2199,40 @@ class DITemplateValueParameter : public DITemplateParameter {
21912199
friend class MDNode;
21922200

21932201
DITemplateValueParameter(LLVMContext &Context, StorageType Storage,
2194-
unsigned Tag, ArrayRef<Metadata *> Ops)
2202+
unsigned Tag, bool IsDefault,
2203+
ArrayRef<Metadata *> Ops)
21952204
: DITemplateParameter(Context, DITemplateValueParameterKind, Storage, Tag,
2196-
Ops) {}
2205+
IsDefault, Ops) {}
21972206
~DITemplateValueParameter() = default;
21982207

21992208
static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
22002209
StringRef Name, DIType *Type,
2201-
Metadata *Value, StorageType Storage,
2210+
bool IsDefault, Metadata *Value,
2211+
StorageType Storage,
22022212
bool ShouldCreate = true) {
22032213
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), Type,
2204-
Value, Storage, ShouldCreate);
2214+
IsDefault, Value, Storage, ShouldCreate);
22052215
}
22062216
static DITemplateValueParameter *getImpl(LLVMContext &Context, unsigned Tag,
22072217
MDString *Name, Metadata *Type,
2208-
Metadata *Value, StorageType Storage,
2218+
bool IsDefault, Metadata *Value,
2219+
StorageType Storage,
22092220
bool ShouldCreate = true);
22102221

22112222
TempDITemplateValueParameter cloneImpl() const {
22122223
return getTemporary(getContext(), getTag(), getName(), getType(),
2213-
getValue());
2224+
isDefault(), getValue());
22142225
}
22152226

22162227
public:
22172228
DEFINE_MDNODE_GET(DITemplateValueParameter,
2218-
(unsigned Tag, StringRef Name, DIType *Type,
2229+
(unsigned Tag, StringRef Name, DIType *Type, bool IsDefault,
22192230
Metadata *Value),
2220-
(Tag, Name, Type, Value))
2221-
DEFINE_MDNODE_GET(DITemplateValueParameter, (unsigned Tag, MDString *Name,
2222-
Metadata *Type, Metadata *Value),
2223-
(Tag, Name, Type, Value))
2231+
(Tag, Name, Type, IsDefault, Value))
2232+
DEFINE_MDNODE_GET(DITemplateValueParameter,
2233+
(unsigned Tag, MDString *Name, Metadata *Type,
2234+
bool IsDefault, Metadata *Value),
2235+
(Tag, Name, Type, IsDefault, Value))
22242236

22252237
TempDITemplateValueParameter clone() const { return cloneImpl(); }
22262238

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4842,33 +4842,38 @@ bool LLParser::ParseDIModule(MDNode *&Result, bool IsDistinct) {
48424842
}
48434843

48444844
/// ParseDITemplateTypeParameter:
4845-
/// ::= !DITemplateTypeParameter(name: "Ty", type: !1)
4845+
/// ::= !DITemplateTypeParameter(name: "Ty", type: !1, defaulted: false)
48464846
bool LLParser::ParseDITemplateTypeParameter(MDNode *&Result, bool IsDistinct) {
48474847
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
48484848
OPTIONAL(name, MDStringField, ); \
4849-
REQUIRED(type, MDField, );
4849+
REQUIRED(type, MDField, ); \
4850+
OPTIONAL(defaulted, MDBoolField, );
48504851
PARSE_MD_FIELDS();
48514852
#undef VISIT_MD_FIELDS
48524853

4853-
Result =
4854-
GET_OR_DISTINCT(DITemplateTypeParameter, (Context, name.Val, type.Val));
4854+
Result = GET_OR_DISTINCT(DITemplateTypeParameter,
4855+
(Context, name.Val, type.Val, defaulted.Val));
48554856
return false;
48564857
}
48574858

48584859
/// ParseDITemplateValueParameter:
48594860
/// ::= !DITemplateValueParameter(tag: DW_TAG_template_value_parameter,
4860-
/// name: "V", type: !1, value: i32 7)
4861+
/// name: "V", type: !1, defaulted: false,
4862+
/// value: i32 7)
48614863
bool LLParser::ParseDITemplateValueParameter(MDNode *&Result, bool IsDistinct) {
48624864
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
48634865
OPTIONAL(tag, DwarfTagField, (dwarf::DW_TAG_template_value_parameter)); \
48644866
OPTIONAL(name, MDStringField, ); \
48654867
OPTIONAL(type, MDField, ); \
4868+
OPTIONAL(defaulted, MDBoolField, ); \
48664869
REQUIRED(value, MDField, );
4870+
48674871
PARSE_MD_FIELDS();
48684872
#undef VISIT_MD_FIELDS
48694873

4870-
Result = GET_OR_DISTINCT(DITemplateValueParameter,
4871-
(Context, tag.Val, name.Val, type.Val, value.Val));
4874+
Result = GET_OR_DISTINCT(
4875+
DITemplateValueParameter,
4876+
(Context, tag.Val, name.Val, type.Val, defaulted.Val, value.Val));
48724877
return false;
48734878
}
48744879

llvm/lib/Bitcode/Reader/MetadataLoader.cpp

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1668,27 +1668,34 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
16681668
break;
16691669
}
16701670
case bitc::METADATA_TEMPLATE_TYPE: {
1671-
if (Record.size() != 3)
1671+
if (Record.size() < 3 || Record.size() > 4)
16721672
return error("Invalid record");
16731673

16741674
IsDistinct = Record[0];
1675-
MetadataList.assignValue(GET_OR_DISTINCT(DITemplateTypeParameter,
1676-
(Context, getMDString(Record[1]),
1677-
getDITypeRefOrNull(Record[2]))),
1678-
NextMetadataNo);
1675+
MetadataList.assignValue(
1676+
GET_OR_DISTINCT(DITemplateTypeParameter,
1677+
(Context, getMDString(Record[1]),
1678+
getDITypeRefOrNull(Record[2]),
1679+
(Record.size() == 4) ? getMDOrNull(Record[3])
1680+
: getMDOrNull(false))),
1681+
NextMetadataNo);
16791682
NextMetadataNo++;
16801683
break;
16811684
}
16821685
case bitc::METADATA_TEMPLATE_VALUE: {
1683-
if (Record.size() != 5)
1686+
if (Record.size() < 5 || Record.size() > 6)
16841687
return error("Invalid record");
16851688

16861689
IsDistinct = Record[0];
1690+
16871691
MetadataList.assignValue(
1688-
GET_OR_DISTINCT(DITemplateValueParameter,
1689-
(Context, Record[1], getMDString(Record[2]),
1690-
getDITypeRefOrNull(Record[3]),
1691-
getMDOrNull(Record[4]))),
1692+
GET_OR_DISTINCT(
1693+
DITemplateValueParameter,
1694+
(Context, Record[1], getMDString(Record[2]),
1695+
getDITypeRefOrNull(Record[3]),
1696+
(Record.size() == 6) ? getMDOrNull(Record[4]) : getMDOrNull(false),
1697+
(Record.size() == 6) ? getMDOrNull(Record[5])
1698+
: getMDOrNull(Record[4]))),
16921699
NextMetadataNo);
16931700
NextMetadataNo++;
16941701
break;

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1792,6 +1792,7 @@ void ModuleBitcodeWriter::writeDITemplateTypeParameter(
17921792
Record.push_back(N->isDistinct());
17931793
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
17941794
Record.push_back(VE.getMetadataOrNullID(N->getType()));
1795+
Record.push_back(N->isDefault());
17951796

17961797
Stream.EmitRecord(bitc::METADATA_TEMPLATE_TYPE, Record, Abbrev);
17971798
Record.clear();
@@ -1804,6 +1805,7 @@ void ModuleBitcodeWriter::writeDITemplateValueParameter(
18041805
Record.push_back(N->getTag());
18051806
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
18061807
Record.push_back(VE.getMetadataOrNullID(N->getType()));
1808+
Record.push_back(N->isDefault());
18071809
Record.push_back(VE.getMetadataOrNullID(N->getValue()));
18081810

18091811
Stream.EmitRecord(bitc::METADATA_TEMPLATE_VALUE, Record, Abbrev);

llvm/lib/IR/AsmWriter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,6 +2073,7 @@ static void writeDITemplateTypeParameter(raw_ostream &Out,
20732073
MDFieldPrinter Printer(Out, TypePrinter, Machine, Context);
20742074
Printer.printString("name", N->getName());
20752075
Printer.printMetadata("type", N->getRawType(), /* ShouldSkipNull */ false);
2076+
Printer.printBool("defaulted", N->isDefault(), /* Default= */ false);
20762077
Out << ")";
20772078
}
20782079

@@ -2087,6 +2088,7 @@ static void writeDITemplateValueParameter(raw_ostream &Out,
20872088
Printer.printTag(N);
20882089
Printer.printString("name", N->getName());
20892090
Printer.printMetadata("type", N->getRawType());
2091+
Printer.printBool("defaulted", N->isDefault(), /* Default= */ false);
20902092
Printer.printMetadata("value", N->getValue(), /* ShouldSkipNull */ false);
20912093
Out << ")";
20922094
}

llvm/lib/IR/DIBuilder.cpp

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -406,41 +406,42 @@ DIBuilder::createObjCProperty(StringRef Name, DIFile *File, unsigned LineNumber,
406406

407407
DITemplateTypeParameter *
408408
DIBuilder::createTemplateTypeParameter(DIScope *Context, StringRef Name,
409-
DIType *Ty) {
409+
DIType *Ty, bool isDefault) {
410410
assert((!Context || isa<DICompileUnit>(Context)) && "Expected compile unit");
411-
return DITemplateTypeParameter::get(VMContext, Name, Ty);
411+
return DITemplateTypeParameter::get(VMContext, Name, Ty, isDefault);
412412
}
413413

414414
static DITemplateValueParameter *
415415
createTemplateValueParameterHelper(LLVMContext &VMContext, unsigned Tag,
416416
DIScope *Context, StringRef Name, DIType *Ty,
417-
Metadata *MD) {
417+
bool IsDefault, Metadata *MD) {
418418
assert((!Context || isa<DICompileUnit>(Context)) && "Expected compile unit");
419-
return DITemplateValueParameter::get(VMContext, Tag, Name, Ty, MD);
419+
return DITemplateValueParameter::get(VMContext, Tag, Name, Ty, IsDefault, MD);
420420
}
421421

422422
DITemplateValueParameter *
423423
DIBuilder::createTemplateValueParameter(DIScope *Context, StringRef Name,
424-
DIType *Ty, Constant *Val) {
424+
DIType *Ty, bool isDefault,
425+
Constant *Val) {
425426
return createTemplateValueParameterHelper(
426427
VMContext, dwarf::DW_TAG_template_value_parameter, Context, Name, Ty,
427-
getConstantOrNull(Val));
428+
isDefault, getConstantOrNull(Val));
428429
}
429430

430431
DITemplateValueParameter *
431432
DIBuilder::createTemplateTemplateParameter(DIScope *Context, StringRef Name,
432433
DIType *Ty, StringRef Val) {
433434
return createTemplateValueParameterHelper(
434435
VMContext, dwarf::DW_TAG_GNU_template_template_param, Context, Name, Ty,
435-
MDString::get(VMContext, Val));
436+
false, MDString::get(VMContext, Val));
436437
}
437438

438439
DITemplateValueParameter *
439440
DIBuilder::createTemplateParameterPack(DIScope *Context, StringRef Name,
440441
DIType *Ty, DINodeArray Val) {
441442
return createTemplateValueParameterHelper(
442443
VMContext, dwarf::DW_TAG_GNU_template_parameter_pack, Context, Name, Ty,
443-
Val.get());
444+
false, Val.get());
444445
}
445446

446447
DICompositeType *DIBuilder::createClassType(

0 commit comments

Comments
 (0)