Skip to content

Commit 4042ada

Browse files
alokkrsharmaSouraVX
authored andcommitted
[DebugInfo] support for DW_AT_data_location in llvm
This patch adds support for DWARF attribute DW_AT_data_location. Summary: Dynamic arrays in fortran are described by array descriptor and data allocation address. Former is mapped to DW_AT_location and later is mapped to DW_AT_data_location. Testing: unit test cases added (hand-written) check llvm check debug-info Reviewed By: aprantl Differential Revision: https://reviews.llvm.org/D79592
1 parent a2545c3 commit 4042ada

File tree

17 files changed

+365
-82
lines changed

17 files changed

+365
-82
lines changed

llvm/docs/LangRef.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4810,7 +4810,12 @@ The following ``tag:`` values are valid:
48104810
For ``DW_TAG_array_type``, the ``elements:`` should be :ref:`subrange
48114811
descriptors <DISubrange>`, each representing the range of subscripts at that
48124812
level of indexing. The ``DIFlagVector`` flag to ``flags:`` indicates that an
4813-
array type is a native packed vector.
4813+
array type is a native packed vector. The optional ``dataLocation`` is a
4814+
DIExpression that describes how to get from an object's address to the actual
4815+
raw data, if they aren't equivalent. This is only supported for array types,
4816+
particularly to describe Fortran arrays, which have an array descriptor in
4817+
addition to the array data. Alternatively it can also be DIVariable which
4818+
has the address of the actual raw data.
48144819

48154820
For ``DW_TAG_enumeration_type``, the ``elements:`` should be :ref:`enumerator
48164821
descriptors <DIEnumerator>`, each representing the definition of an enumeration

llvm/include/llvm/IR/DebugInfoMetadata.h

Lines changed: 45 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -931,56 +931,57 @@ class DICompositeType : public DIType {
931931
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
932932
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
933933
DITemplateParameterArray TemplateParams, StringRef Identifier,
934-
DIDerivedType *Discriminator, StorageType Storage,
935-
bool ShouldCreate = true) {
936-
return getImpl(
937-
Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
938-
BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
939-
RuntimeLang, VTableHolder, TemplateParams.get(),
940-
getCanonicalMDString(Context, Identifier), Discriminator, Storage, ShouldCreate);
934+
DIDerivedType *Discriminator, Metadata *DataLocation,
935+
StorageType Storage, bool ShouldCreate = true) {
936+
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
937+
Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
938+
Flags, Elements.get(), RuntimeLang, VTableHolder,
939+
TemplateParams.get(),
940+
getCanonicalMDString(Context, Identifier), Discriminator,
941+
DataLocation, Storage, ShouldCreate);
941942
}
942943
static DICompositeType *
943944
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
944945
unsigned Line, Metadata *Scope, Metadata *BaseType,
945946
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
946947
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
947948
Metadata *VTableHolder, Metadata *TemplateParams,
948-
MDString *Identifier, Metadata *Discriminator,
949+
MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
949950
StorageType Storage, bool ShouldCreate = true);
950951

951952
TempDICompositeType cloneImpl() const {
952953
return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
953954
getScope(), getBaseType(), getSizeInBits(),
954955
getAlignInBits(), getOffsetInBits(), getFlags(),
955956
getElements(), getRuntimeLang(), getVTableHolder(),
956-
getTemplateParams(), getIdentifier(), getDiscriminator());
957+
getTemplateParams(), getIdentifier(),
958+
getDiscriminator(), getRawDataLocation());
957959
}
958960

959961
public:
960-
DEFINE_MDNODE_GET(DICompositeType,
961-
(unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
962-
DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
963-
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
964-
DINodeArray Elements, unsigned RuntimeLang,
965-
DIType *VTableHolder,
966-
DITemplateParameterArray TemplateParams = nullptr,
967-
StringRef Identifier = "",
968-
DIDerivedType *Discriminator = nullptr),
969-
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
970-
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
971-
VTableHolder, TemplateParams, Identifier, Discriminator))
972-
DEFINE_MDNODE_GET(DICompositeType,
973-
(unsigned Tag, MDString *Name, Metadata *File,
974-
unsigned Line, Metadata *Scope, Metadata *BaseType,
975-
uint64_t SizeInBits, uint32_t AlignInBits,
976-
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
977-
unsigned RuntimeLang, Metadata *VTableHolder,
978-
Metadata *TemplateParams = nullptr,
979-
MDString *Identifier = nullptr,
980-
Metadata *Discriminator = nullptr),
981-
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
982-
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
983-
VTableHolder, TemplateParams, Identifier, Discriminator))
962+
DEFINE_MDNODE_GET(
963+
DICompositeType,
964+
(unsigned Tag, StringRef Name, DIFile *File, unsigned Line,
965+
DIScope *Scope, DIType *BaseType, uint64_t SizeInBits,
966+
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
967+
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
968+
DITemplateParameterArray TemplateParams = nullptr,
969+
StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
970+
Metadata *DataLocation = nullptr),
971+
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
972+
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
973+
Identifier, Discriminator, DataLocation))
974+
DEFINE_MDNODE_GET(
975+
DICompositeType,
976+
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
977+
Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
978+
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
979+
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
980+
Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr,
981+
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr),
982+
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
983+
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
984+
Identifier, Discriminator, DataLocation))
984985

985986
TempDICompositeType clone() const { return cloneImpl(); }
986987

@@ -997,7 +998,8 @@ class DICompositeType : public DIType {
997998
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
998999
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
9991000
unsigned RuntimeLang, Metadata *VTableHolder,
1000-
Metadata *TemplateParams, Metadata *Discriminator);
1001+
Metadata *TemplateParams, Metadata *Discriminator,
1002+
Metadata *DataLocation);
10011003
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
10021004
MDString &Identifier);
10031005

@@ -1016,7 +1018,8 @@ class DICompositeType : public DIType {
10161018
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
10171019
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
10181020
unsigned RuntimeLang, Metadata *VTableHolder,
1019-
Metadata *TemplateParams, Metadata *Discriminator);
1021+
Metadata *TemplateParams, Metadata *Discriminator,
1022+
Metadata *DataLocation);
10201023

10211024
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
10221025
DINodeArray getElements() const {
@@ -1038,6 +1041,13 @@ class DICompositeType : public DIType {
10381041
MDString *getRawIdentifier() const { return getOperandAs<MDString>(7); }
10391042
Metadata *getRawDiscriminator() const { return getOperand(8); }
10401043
DIDerivedType *getDiscriminator() const { return getOperandAs<DIDerivedType>(8); }
1044+
Metadata *getRawDataLocation() const { return getOperand(9); }
1045+
DIVariable *getDataLocation() const {
1046+
return dyn_cast_or_null<DIVariable>(getRawDataLocation());
1047+
}
1048+
DIExpression *getDataLocationExp() const {
1049+
return dyn_cast_or_null<DIExpression>(getRawDataLocation());
1050+
}
10411051

10421052
/// Replace operands.
10431053
///

llvm/lib/AsmParser/LLParser.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4617,7 +4617,8 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
46174617
OPTIONAL(vtableHolder, MDField, ); \
46184618
OPTIONAL(templateParams, MDField, ); \
46194619
OPTIONAL(identifier, MDStringField, ); \
4620-
OPTIONAL(discriminator, MDField, );
4620+
OPTIONAL(discriminator, MDField, ); \
4621+
OPTIONAL(dataLocation, MDField, );
46214622
PARSE_MD_FIELDS();
46224623
#undef VISIT_MD_FIELDS
46234624

@@ -4626,8 +4627,8 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
46264627
if (auto *CT = DICompositeType::buildODRType(
46274628
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
46284629
scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val,
4629-
elements.Val, runtimeLang.Val, vtableHolder.Val,
4630-
templateParams.Val, discriminator.Val)) {
4630+
elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val,
4631+
discriminator.Val, dataLocation.Val)) {
46314632
Result = CT;
46324633
return false;
46334634
}
@@ -4639,7 +4640,7 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
46394640
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
46404641
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
46414642
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
4642-
discriminator.Val));
4643+
discriminator.Val, dataLocation.Val));
46434644
return false;
46444645
}
46454646

llvm/lib/Bitcode/Reader/MetadataLoader.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1340,7 +1340,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
13401340
break;
13411341
}
13421342
case bitc::METADATA_COMPOSITE_TYPE: {
1343-
if (Record.size() < 16 || Record.size() > 17)
1343+
if (Record.size() < 16 || Record.size() > 18)
13441344
return error("Invalid record");
13451345

13461346
// If we have a UUID and this is not a forward declaration, lookup the
@@ -1364,6 +1364,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
13641364
Metadata *VTableHolder = nullptr;
13651365
Metadata *TemplateParams = nullptr;
13661366
Metadata *Discriminator = nullptr;
1367+
Metadata *DataLocation = nullptr;
13671368
auto *Identifier = getMDString(Record[15]);
13681369
// If this module is being parsed so that it can be ThinLTO imported
13691370
// into another module, composite types only need to be imported
@@ -1386,21 +1387,23 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
13861387
TemplateParams = getMDOrNull(Record[14]);
13871388
if (Record.size() > 16)
13881389
Discriminator = getMDOrNull(Record[16]);
1390+
if (Record.size() > 17)
1391+
DataLocation = getMDOrNull(Record[17]);
13891392
}
13901393
DICompositeType *CT = nullptr;
13911394
if (Identifier)
13921395
CT = DICompositeType::buildODRType(
13931396
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
13941397
SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
1395-
VTableHolder, TemplateParams, Discriminator);
1398+
VTableHolder, TemplateParams, Discriminator, DataLocation);
13961399

13971400
// Create a node if we didn't get a lazy ODR type.
13981401
if (!CT)
13991402
CT = GET_OR_DISTINCT(DICompositeType,
14001403
(Context, Tag, Name, File, Line, Scope, BaseType,
14011404
SizeInBits, AlignInBits, OffsetInBits, Flags,
14021405
Elements, RuntimeLang, VTableHolder, TemplateParams,
1403-
Identifier, Discriminator));
1406+
Identifier, Discriminator, DataLocation));
14041407
if (!IsNotUsedInTypeRef && Identifier)
14051408
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
14061409

llvm/lib/Bitcode/Writer/BitcodeWriter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1627,6 +1627,7 @@ void ModuleBitcodeWriter::writeDICompositeType(
16271627
Record.push_back(VE.getMetadataOrNullID(N->getTemplateParams().get()));
16281628
Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier()));
16291629
Record.push_back(VE.getMetadataOrNullID(N->getDiscriminator()));
1630+
Record.push_back(VE.getMetadataOrNullID(N->getRawDataLocation()));
16301631

16311632
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
16321633
Record.clear();

llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -764,6 +764,8 @@ static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {
764764
auto *Array = dyn_cast<DICompositeType>(Var->getType());
765765
if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)
766766
return Result;
767+
if (auto *DLVar = Array->getDataLocation())
768+
Result.push_back(DLVar);
767769
for (auto *El : Array->getElements()) {
768770
if (auto *Subrange = dyn_cast<DISubrange>(El)) {
769771
auto Count = Subrange->getCount();

llvm/lib/CodeGen/AsmPrinter/DwarfUnit.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,6 +1414,17 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
14141414
CTy->getSizeInBits() / CHAR_BIT);
14151415
}
14161416

1417+
if (DIVariable *Var = CTy->getDataLocation()) {
1418+
if (auto *VarDIE = getDIE(Var))
1419+
addDIEEntry(Buffer, dwarf::DW_AT_data_location, *VarDIE);
1420+
} else if (DIExpression *Expr = CTy->getDataLocationExp()) {
1421+
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
1422+
DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
1423+
DwarfExpr.setMemoryLocationKind();
1424+
DwarfExpr.addExpression(Expr);
1425+
addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize());
1426+
}
1427+
14171428
// Emit the element type.
14181429
addType(Buffer, CTy->getBaseType());
14191430

llvm/lib/IR/AsmWriter.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1931,6 +1931,7 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
19311931
Printer.printMetadata("templateParams", N->getRawTemplateParams());
19321932
Printer.printString("identifier", N->getIdentifier());
19331933
Printer.printMetadata("discriminator", N->getRawDiscriminator());
1934+
Printer.printMetadata("dataLocation", N->getRawDataLocation());
19341935
Out << ")";
19351936
}
19361937

llvm/lib/IR/DebugInfoMetadata.cpp

Lines changed: 19 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -405,17 +405,18 @@ DICompositeType *DICompositeType::getImpl(
405405
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
406406
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
407407
Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator,
408-
StorageType Storage, bool ShouldCreate) {
408+
Metadata *DataLocation, StorageType Storage, bool ShouldCreate) {
409409
assert(isCanonical(Name) && "Expected canonical MDString");
410410

411411
// Keep this in sync with buildODRType.
412-
DEFINE_GETIMPL_LOOKUP(
413-
DICompositeType, (Tag, Name, File, Line, Scope, BaseType, SizeInBits,
414-
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
415-
VTableHolder, TemplateParams, Identifier, Discriminator));
416-
Metadata *Ops[] = {File, Scope, Name, BaseType,
417-
Elements, VTableHolder, TemplateParams, Identifier,
418-
Discriminator};
412+
DEFINE_GETIMPL_LOOKUP(DICompositeType,
413+
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
414+
AlignInBits, OffsetInBits, Flags, Elements,
415+
RuntimeLang, VTableHolder, TemplateParams, Identifier,
416+
Discriminator, DataLocation));
417+
Metadata *Ops[] = {File, Scope, Name, BaseType,
418+
Elements, VTableHolder, TemplateParams, Identifier,
419+
Discriminator, DataLocation};
419420
DEFINE_GETIMPL_STORE(DICompositeType, (Tag, Line, RuntimeLang, SizeInBits,
420421
AlignInBits, OffsetInBits, Flags),
421422
Ops);
@@ -426,7 +427,8 @@ DICompositeType *DICompositeType::buildODRType(
426427
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
427428
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
428429
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
429-
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator) {
430+
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
431+
Metadata *DataLocation) {
430432
assert(!Identifier.getString().empty() && "Expected valid identifier");
431433
if (!Context.isODRUniquingDebugTypes())
432434
return nullptr;
@@ -435,7 +437,8 @@ DICompositeType *DICompositeType::buildODRType(
435437
return CT = DICompositeType::getDistinct(
436438
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
437439
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
438-
VTableHolder, TemplateParams, &Identifier, Discriminator);
440+
VTableHolder, TemplateParams, &Identifier, Discriminator,
441+
DataLocation);
439442

440443
// Only mutate CT if it's a forward declaration and the new operands aren't.
441444
assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");
@@ -445,9 +448,9 @@ DICompositeType *DICompositeType::buildODRType(
445448
// Mutate CT in place. Keep this in sync with getImpl.
446449
CT->mutate(Tag, Line, RuntimeLang, SizeInBits, AlignInBits, OffsetInBits,
447450
Flags);
448-
Metadata *Ops[] = {File, Scope, Name, BaseType,
449-
Elements, VTableHolder, TemplateParams, &Identifier,
450-
Discriminator};
451+
Metadata *Ops[] = {File, Scope, Name, BaseType,
452+
Elements, VTableHolder, TemplateParams, &Identifier,
453+
Discriminator, DataLocation};
451454
assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
452455
"Mismatched number of operands");
453456
for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
@@ -461,7 +464,8 @@ DICompositeType *DICompositeType::getODRType(
461464
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
462465
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
463466
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
464-
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator) {
467+
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
468+
Metadata *DataLocation) {
465469
assert(!Identifier.getString().empty() && "Expected valid identifier");
466470
if (!Context.isODRUniquingDebugTypes())
467471
return nullptr;
@@ -470,7 +474,7 @@ DICompositeType *DICompositeType::getODRType(
470474
CT = DICompositeType::getDistinct(
471475
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
472476
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder,
473-
TemplateParams, &Identifier, Discriminator);
477+
TemplateParams, &Identifier, Discriminator, DataLocation);
474478
return CT;
475479
}
476480

0 commit comments

Comments
 (0)