forked from OSchip/llvm-project
[DebugInfo] Support for DW_AT_associated and DW_AT_allocated.
Summary: This support is needed for the Fortran array variables with pointer/allocatable attribute. This support enables debugger to identify the status of variable whether that is currently allocated/associated. for pointer array (before allocation/association) without DW_AT_associated (gdb) pt ptr type = integer (140737345375288:140737354129776) (gdb) p ptr value requires 35017956 bytes, which is more than max-value-size with DW_AT_associated (gdb) pt ptr type = integer (:) (gdb) p ptr $1 = <not associated> for allocatable array (before allocation) without DW_AT_allocated (gdb) pt arr type = integer (140737345375288:140737354129776) (gdb) p arr value requires 35017956 bytes, which is more than max-value-size with DW_AT_allocated (gdb) pt arr type = integer, allocatable (:) (gdb) p arr $1 = <not allocated> Testing - unit test cases added - check-llvm - check-debuginfo Reviewed By: aprantl Differential Revision: https://reviews.llvm.org/D83544
This commit is contained in:
parent
5e999cbe8d
commit
2d10258a31
|
@ -4886,7 +4886,12 @@ DIExpression that describes how to get from an object's address to the actual
|
|||
raw data, if they aren't equivalent. This is only supported for array types,
|
||||
particularly to describe Fortran arrays, which have an array descriptor in
|
||||
addition to the array data. Alternatively it can also be DIVariable which
|
||||
has the address of the actual raw data.
|
||||
has the address of the actual raw data. The Fortran language supports pointer
|
||||
arrays which can be attached to actual arrays, this attachement between pointer
|
||||
and pointee is called association. The optional ``associated`` is a
|
||||
DIExpression that describes whether the pointer array is currently associated.
|
||||
The optional ``allocated`` is a DIExpression that describes whether the
|
||||
allocatable array is currently allocated.
|
||||
|
||||
For ``DW_TAG_enumeration_type``, the ``elements:`` should be :ref:`enumerator
|
||||
descriptors <DIEnumerator>`, each representing the definition of an enumeration
|
||||
|
|
|
@ -942,13 +942,14 @@ class DICompositeType : public DIType {
|
|||
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
|
||||
DITemplateParameterArray TemplateParams, StringRef Identifier,
|
||||
DIDerivedType *Discriminator, Metadata *DataLocation,
|
||||
StorageType Storage, bool ShouldCreate = true) {
|
||||
Metadata *Associated, Metadata *Allocated, StorageType Storage,
|
||||
bool ShouldCreate = true) {
|
||||
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
|
||||
Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
|
||||
Flags, Elements.get(), RuntimeLang, VTableHolder,
|
||||
TemplateParams.get(),
|
||||
getCanonicalMDString(Context, Identifier), Discriminator,
|
||||
DataLocation, Storage, ShouldCreate);
|
||||
DataLocation, Associated, Allocated, Storage, ShouldCreate);
|
||||
}
|
||||
static DICompositeType *
|
||||
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
|
||||
|
@ -957,15 +958,16 @@ class DICompositeType : public DIType {
|
|||
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
|
||||
Metadata *VTableHolder, Metadata *TemplateParams,
|
||||
MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
|
||||
StorageType Storage, bool ShouldCreate = true);
|
||||
Metadata *Associated, Metadata *Allocated, StorageType Storage,
|
||||
bool ShouldCreate = true);
|
||||
|
||||
TempDICompositeType cloneImpl() const {
|
||||
return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
|
||||
getScope(), getBaseType(), getSizeInBits(),
|
||||
getAlignInBits(), getOffsetInBits(), getFlags(),
|
||||
getElements(), getRuntimeLang(), getVTableHolder(),
|
||||
getTemplateParams(), getIdentifier(),
|
||||
getDiscriminator(), getRawDataLocation());
|
||||
return getTemporary(
|
||||
getContext(), getTag(), getName(), getFile(), getLine(), getScope(),
|
||||
getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(),
|
||||
getFlags(), getElements(), getRuntimeLang(), getVTableHolder(),
|
||||
getTemplateParams(), getIdentifier(), getDiscriminator(),
|
||||
getRawDataLocation(), getRawAssociated(), getRawAllocated());
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -977,10 +979,11 @@ public:
|
|||
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
|
||||
DITemplateParameterArray TemplateParams = nullptr,
|
||||
StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
|
||||
Metadata *DataLocation = nullptr),
|
||||
Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
|
||||
Metadata *Allocated = nullptr),
|
||||
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
|
||||
Identifier, Discriminator, DataLocation))
|
||||
Identifier, Discriminator, DataLocation, Associated, Allocated))
|
||||
DEFINE_MDNODE_GET(
|
||||
DICompositeType,
|
||||
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
|
||||
|
@ -988,10 +991,11 @@ public:
|
|||
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
|
||||
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
|
||||
Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr,
|
||||
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr),
|
||||
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
|
||||
Metadata *Associated = nullptr, Metadata *Allocated = nullptr),
|
||||
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
|
||||
Identifier, Discriminator, DataLocation))
|
||||
Identifier, Discriminator, DataLocation, Associated, Allocated))
|
||||
|
||||
TempDICompositeType clone() const { return cloneImpl(); }
|
||||
|
||||
|
@ -1009,7 +1013,7 @@ public:
|
|||
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
|
||||
unsigned RuntimeLang, Metadata *VTableHolder,
|
||||
Metadata *TemplateParams, Metadata *Discriminator,
|
||||
Metadata *DataLocation);
|
||||
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated);
|
||||
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
|
||||
MDString &Identifier);
|
||||
|
||||
|
@ -1022,14 +1026,13 @@ public:
|
|||
///
|
||||
/// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
|
||||
/// nullptr.
|
||||
static DICompositeType *
|
||||
buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
|
||||
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
|
||||
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
|
||||
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
|
||||
unsigned RuntimeLang, Metadata *VTableHolder,
|
||||
Metadata *TemplateParams, Metadata *Discriminator,
|
||||
Metadata *DataLocation);
|
||||
static DICompositeType *buildODRType(
|
||||
LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
|
||||
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
|
||||
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
||||
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
|
||||
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
|
||||
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated);
|
||||
|
||||
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
|
||||
DINodeArray getElements() const {
|
||||
|
@ -1058,6 +1061,20 @@ public:
|
|||
DIExpression *getDataLocationExp() const {
|
||||
return dyn_cast_or_null<DIExpression>(getRawDataLocation());
|
||||
}
|
||||
Metadata *getRawAssociated() const { return getOperand(10); }
|
||||
DIVariable *getAssociated() const {
|
||||
return dyn_cast_or_null<DIVariable>(getRawAssociated());
|
||||
}
|
||||
DIExpression *getAssociatedExp() const {
|
||||
return dyn_cast_or_null<DIExpression>(getRawAssociated());
|
||||
}
|
||||
Metadata *getRawAllocated() const { return getOperand(11); }
|
||||
DIVariable *getAllocated() const {
|
||||
return dyn_cast_or_null<DIVariable>(getRawAllocated());
|
||||
}
|
||||
DIExpression *getAllocatedExp() const {
|
||||
return dyn_cast_or_null<DIExpression>(getRawAllocated());
|
||||
}
|
||||
|
||||
/// Replace operands.
|
||||
///
|
||||
|
|
|
@ -4682,7 +4682,9 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
|
|||
OPTIONAL(templateParams, MDField, ); \
|
||||
OPTIONAL(identifier, MDStringField, ); \
|
||||
OPTIONAL(discriminator, MDField, ); \
|
||||
OPTIONAL(dataLocation, MDField, );
|
||||
OPTIONAL(dataLocation, MDField, ); \
|
||||
OPTIONAL(associated, MDField, ); \
|
||||
OPTIONAL(allocated, MDField, );
|
||||
PARSE_MD_FIELDS();
|
||||
#undef VISIT_MD_FIELDS
|
||||
|
||||
|
@ -4692,7 +4694,8 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
|
|||
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
|
||||
scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val,
|
||||
elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val,
|
||||
discriminator.Val, dataLocation.Val)) {
|
||||
discriminator.Val, dataLocation.Val, associated.Val,
|
||||
allocated.Val)) {
|
||||
Result = CT;
|
||||
return false;
|
||||
}
|
||||
|
@ -4704,7 +4707,7 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
|
|||
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
|
||||
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
|
||||
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
|
||||
discriminator.Val, dataLocation.Val));
|
||||
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1350,7 +1350,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
|||
break;
|
||||
}
|
||||
case bitc::METADATA_COMPOSITE_TYPE: {
|
||||
if (Record.size() < 16 || Record.size() > 18)
|
||||
if (Record.size() < 16 || Record.size() > 20)
|
||||
return error("Invalid record");
|
||||
|
||||
// If we have a UUID and this is not a forward declaration, lookup the
|
||||
|
@ -1375,6 +1375,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
|||
Metadata *TemplateParams = nullptr;
|
||||
Metadata *Discriminator = nullptr;
|
||||
Metadata *DataLocation = nullptr;
|
||||
Metadata *Associated = nullptr;
|
||||
Metadata *Allocated = nullptr;
|
||||
auto *Identifier = getMDString(Record[15]);
|
||||
// If this module is being parsed so that it can be ThinLTO imported
|
||||
// into another module, composite types only need to be imported
|
||||
|
@ -1399,13 +1401,18 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
|||
Discriminator = getMDOrNull(Record[16]);
|
||||
if (Record.size() > 17)
|
||||
DataLocation = getMDOrNull(Record[17]);
|
||||
if (Record.size() > 19) {
|
||||
Associated = getMDOrNull(Record[18]);
|
||||
Allocated = getMDOrNull(Record[19]);
|
||||
}
|
||||
}
|
||||
DICompositeType *CT = nullptr;
|
||||
if (Identifier)
|
||||
CT = DICompositeType::buildODRType(
|
||||
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
|
||||
SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
|
||||
VTableHolder, TemplateParams, Discriminator, DataLocation);
|
||||
VTableHolder, TemplateParams, Discriminator, DataLocation, Associated,
|
||||
Allocated);
|
||||
|
||||
// Create a node if we didn't get a lazy ODR type.
|
||||
if (!CT)
|
||||
|
@ -1413,7 +1420,8 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
|||
(Context, Tag, Name, File, Line, Scope, BaseType,
|
||||
SizeInBits, AlignInBits, OffsetInBits, Flags,
|
||||
Elements, RuntimeLang, VTableHolder, TemplateParams,
|
||||
Identifier, Discriminator, DataLocation));
|
||||
Identifier, Discriminator, DataLocation, Associated,
|
||||
Allocated));
|
||||
if (!IsNotUsedInTypeRef && Identifier)
|
||||
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
|
||||
|
||||
|
|
|
@ -1632,6 +1632,8 @@ void ModuleBitcodeWriter::writeDICompositeType(
|
|||
Record.push_back(VE.getMetadataOrNullID(N->getRawIdentifier()));
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getDiscriminator()));
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getRawDataLocation()));
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getRawAssociated()));
|
||||
Record.push_back(VE.getMetadataOrNullID(N->getRawAllocated()));
|
||||
|
||||
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
|
||||
Record.clear();
|
||||
|
|
|
@ -803,6 +803,10 @@ static SmallVector<const DIVariable *, 2> dependencies(DbgVariable *Var) {
|
|||
return Result;
|
||||
if (auto *DLVar = Array->getDataLocation())
|
||||
Result.push_back(DLVar);
|
||||
if (auto *AsVar = Array->getAssociated())
|
||||
Result.push_back(AsVar);
|
||||
if (auto *AlVar = Array->getAllocated())
|
||||
Result.push_back(AlVar);
|
||||
for (auto *El : Array->getElements()) {
|
||||
if (auto *Subrange = dyn_cast<DISubrange>(El)) {
|
||||
if (auto Count = Subrange->getCount())
|
||||
|
|
|
@ -1445,6 +1445,28 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
|
|||
addBlock(Buffer, dwarf::DW_AT_data_location, DwarfExpr.finalize());
|
||||
}
|
||||
|
||||
if (DIVariable *Var = CTy->getAssociated()) {
|
||||
if (auto *VarDIE = getDIE(Var))
|
||||
addDIEEntry(Buffer, dwarf::DW_AT_associated, *VarDIE);
|
||||
} else if (DIExpression *Expr = CTy->getAssociatedExp()) {
|
||||
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
|
||||
DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
|
||||
DwarfExpr.setMemoryLocationKind();
|
||||
DwarfExpr.addExpression(Expr);
|
||||
addBlock(Buffer, dwarf::DW_AT_associated, DwarfExpr.finalize());
|
||||
}
|
||||
|
||||
if (DIVariable *Var = CTy->getAllocated()) {
|
||||
if (auto *VarDIE = getDIE(Var))
|
||||
addDIEEntry(Buffer, dwarf::DW_AT_allocated, *VarDIE);
|
||||
} else if (DIExpression *Expr = CTy->getAllocatedExp()) {
|
||||
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
|
||||
DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
|
||||
DwarfExpr.setMemoryLocationKind();
|
||||
DwarfExpr.addExpression(Expr);
|
||||
addBlock(Buffer, dwarf::DW_AT_allocated, DwarfExpr.finalize());
|
||||
}
|
||||
|
||||
// Emit the element type.
|
||||
addType(Buffer, CTy->getBaseType());
|
||||
|
||||
|
|
|
@ -1962,6 +1962,8 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
|
|||
Printer.printString("identifier", N->getIdentifier());
|
||||
Printer.printMetadata("discriminator", N->getRawDiscriminator());
|
||||
Printer.printMetadata("dataLocation", N->getRawDataLocation());
|
||||
Printer.printMetadata("associated", N->getRawAssociated());
|
||||
Printer.printMetadata("allocated", N->getRawAllocated());
|
||||
Out << ")";
|
||||
}
|
||||
|
||||
|
|
|
@ -493,7 +493,8 @@ DICompositeType *DICompositeType::getImpl(
|
|||
uint32_t AlignInBits, uint64_t OffsetInBits, DIFlags Flags,
|
||||
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
|
||||
Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator,
|
||||
Metadata *DataLocation, StorageType Storage, bool ShouldCreate) {
|
||||
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
|
||||
StorageType Storage, bool ShouldCreate) {
|
||||
assert(isCanonical(Name) && "Expected canonical MDString");
|
||||
|
||||
// Keep this in sync with buildODRType.
|
||||
|
@ -501,10 +502,10 @@ DICompositeType *DICompositeType::getImpl(
|
|||
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
|
||||
AlignInBits, OffsetInBits, Flags, Elements,
|
||||
RuntimeLang, VTableHolder, TemplateParams, Identifier,
|
||||
Discriminator, DataLocation));
|
||||
Discriminator, DataLocation, Associated, Allocated));
|
||||
Metadata *Ops[] = {File, Scope, Name, BaseType,
|
||||
Elements, VTableHolder, TemplateParams, Identifier,
|
||||
Discriminator, DataLocation};
|
||||
Discriminator, DataLocation, Associated, Allocated};
|
||||
DEFINE_GETIMPL_STORE(DICompositeType, (Tag, Line, RuntimeLang, SizeInBits,
|
||||
AlignInBits, OffsetInBits, Flags),
|
||||
Ops);
|
||||
|
@ -516,7 +517,7 @@ DICompositeType *DICompositeType::buildODRType(
|
|||
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
||||
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
|
||||
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
|
||||
Metadata *DataLocation) {
|
||||
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated) {
|
||||
assert(!Identifier.getString().empty() && "Expected valid identifier");
|
||||
if (!Context.isODRUniquingDebugTypes())
|
||||
return nullptr;
|
||||
|
@ -526,7 +527,7 @@ DICompositeType *DICompositeType::buildODRType(
|
|||
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
|
||||
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
|
||||
VTableHolder, TemplateParams, &Identifier, Discriminator,
|
||||
DataLocation);
|
||||
DataLocation, Associated, Allocated);
|
||||
|
||||
// Only mutate CT if it's a forward declaration and the new operands aren't.
|
||||
assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");
|
||||
|
@ -538,7 +539,7 @@ DICompositeType *DICompositeType::buildODRType(
|
|||
Flags);
|
||||
Metadata *Ops[] = {File, Scope, Name, BaseType,
|
||||
Elements, VTableHolder, TemplateParams, &Identifier,
|
||||
Discriminator, DataLocation};
|
||||
Discriminator, DataLocation, Associated, Allocated};
|
||||
assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
|
||||
"Mismatched number of operands");
|
||||
for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
|
||||
|
@ -553,7 +554,7 @@ DICompositeType *DICompositeType::getODRType(
|
|||
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
||||
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
|
||||
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
|
||||
Metadata *DataLocation) {
|
||||
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated) {
|
||||
assert(!Identifier.getString().empty() && "Expected valid identifier");
|
||||
if (!Context.isODRUniquingDebugTypes())
|
||||
return nullptr;
|
||||
|
@ -562,7 +563,8 @@ DICompositeType *DICompositeType::getODRType(
|
|||
CT = DICompositeType::getDistinct(
|
||||
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
|
||||
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder,
|
||||
TemplateParams, &Identifier, Discriminator, DataLocation);
|
||||
TemplateParams, &Identifier, Discriminator, DataLocation, Associated,
|
||||
Allocated);
|
||||
return CT;
|
||||
}
|
||||
|
||||
|
|
|
@ -525,6 +525,8 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||
MDString *Identifier;
|
||||
Metadata *Discriminator;
|
||||
Metadata *DataLocation;
|
||||
Metadata *Associated;
|
||||
Metadata *Allocated;
|
||||
|
||||
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
|
||||
Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
|
||||
|
@ -532,13 +534,15 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||
Metadata *Elements, unsigned RuntimeLang,
|
||||
Metadata *VTableHolder, Metadata *TemplateParams,
|
||||
MDString *Identifier, Metadata *Discriminator,
|
||||
Metadata *DataLocation)
|
||||
Metadata *DataLocation, Metadata *Associated,
|
||||
Metadata *Allocated)
|
||||
: Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
|
||||
BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
|
||||
AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
|
||||
RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
|
||||
TemplateParams(TemplateParams), Identifier(Identifier),
|
||||
Discriminator(Discriminator), DataLocation(DataLocation) {}
|
||||
Discriminator(Discriminator), DataLocation(DataLocation),
|
||||
Associated(Associated), Allocated(Allocated) {}
|
||||
MDNodeKeyImpl(const DICompositeType *N)
|
||||
: Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
|
||||
Line(N->getLine()), Scope(N->getRawScope()),
|
||||
|
@ -549,7 +553,8 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||
TemplateParams(N->getRawTemplateParams()),
|
||||
Identifier(N->getRawIdentifier()),
|
||||
Discriminator(N->getRawDiscriminator()),
|
||||
DataLocation(N->getRawDataLocation()) {}
|
||||
DataLocation(N->getRawDataLocation()),
|
||||
Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()) {}
|
||||
|
||||
bool isKeyOf(const DICompositeType *RHS) const {
|
||||
return Tag == RHS->getTag() && Name == RHS->getRawName() &&
|
||||
|
@ -564,7 +569,9 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||
TemplateParams == RHS->getRawTemplateParams() &&
|
||||
Identifier == RHS->getRawIdentifier() &&
|
||||
Discriminator == RHS->getRawDiscriminator() &&
|
||||
DataLocation == RHS->getRawDataLocation();
|
||||
DataLocation == RHS->getRawDataLocation() &&
|
||||
Associated == RHS->getRawAssociated() &&
|
||||
Allocated == RHS->getRawAllocated();
|
||||
}
|
||||
|
||||
unsigned getHashValue() const {
|
||||
|
|
|
@ -1035,6 +1035,16 @@ void Verifier::visitDICompositeType(const DICompositeType &N) {
|
|||
AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
|
||||
"dataLocation can only appear in array type");
|
||||
}
|
||||
|
||||
if (N.getRawAssociated()) {
|
||||
AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
|
||||
"associated can only appear in array type");
|
||||
}
|
||||
|
||||
if (N.getRawAllocated()) {
|
||||
AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
|
||||
"allocated can only appear in array type");
|
||||
}
|
||||
}
|
||||
|
||||
void Verifier::visitDISubroutineType(const DISubroutineType &N) {
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
;; This test checks dataLocation field of DICompositeType
|
||||
|
||||
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
|
||||
|
||||
;; Test whether DW_AT_data_location is generated.
|
||||
; CHECK: !DICompositeType(tag: DW_TAG_array_type, baseType: !{{[0-9]+}}, size: 32, align: 32, elements: !{{[0-9]+}}, dataLocation: !{{[0-9]+}}, allocated: !{{[0-9]+}})
|
||||
; CHECK: !DICompositeType(tag: DW_TAG_array_type, baseType: !{{[0-9]+}}, size: 32, align: 32, elements: !{{[0-9]+}}, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), allocated: !DIExpression(DW_OP_push_object_address, DW_OP_deref))
|
||||
|
||||
; ModuleID = 'allocated.f90'
|
||||
source_filename = "/dir/allocated.ll"
|
||||
|
||||
!llvm.module.flags = !{!0, !1}
|
||||
!llvm.dbg.cu = !{!2}
|
||||
|
||||
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !4, imports: !4)
|
||||
!3 = !DIFile(filename: "allocated.f90", directory: "/dir")
|
||||
!4 = !{}
|
||||
!5 = !{!6, !17}
|
||||
!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32, align: 32, elements: !8, dataLocation: !10, allocated: !15)
|
||||
!7 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
!8 = !{!9}
|
||||
!9 = !DISubrange(count: 19, lowerBound: 2)
|
||||
!10 = distinct !DILocalVariable(scope: !11, file: !3, type: !14, flags: DIFlagArtificial)
|
||||
!11 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !12, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2)
|
||||
!12 = !DISubroutineType(cc: DW_CC_program, types: !13)
|
||||
!13 = !{null}
|
||||
!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32, align: 32)
|
||||
!15 = distinct !DILocalVariable(scope: !11, file: !3, type: !16, flags: DIFlagArtificial)
|
||||
!16 = !DIBasicType(name: "logical", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
!17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32, align: 32, elements: !8, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), allocated: !DIExpression(DW_OP_push_object_address, DW_OP_deref))
|
|
@ -0,0 +1,32 @@
|
|||
;; This test checks dataLocation field of DICompositeType
|
||||
|
||||
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
|
||||
|
||||
;; Test whether DW_AT_data_location is generated.
|
||||
; CHECK: !DICompositeType(tag: DW_TAG_array_type, baseType: !{{[0-9]+}}, size: 32, align: 32, elements: !{{[0-9]+}}, dataLocation: !{{[0-9]+}}, associated: !{{[0-9]+}})
|
||||
; CHECK: !DICompositeType(tag: DW_TAG_array_type, baseType: !{{[0-9]+}}, size: 32, align: 32, elements: !{{[0-9]+}}, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref))
|
||||
|
||||
; ModuleID = 'associated.f90'
|
||||
source_filename = "/dir/associated.ll"
|
||||
|
||||
!llvm.module.flags = !{!0, !1}
|
||||
!llvm.dbg.cu = !{!2}
|
||||
|
||||
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !5, globals: !4, imports: !4)
|
||||
!3 = !DIFile(filename: "associated.f90", directory: "/dir")
|
||||
!4 = !{}
|
||||
!5 = !{!6, !17}
|
||||
!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32, align: 32, elements: !8, dataLocation: !10, associated: !15)
|
||||
!7 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
!8 = !{!9}
|
||||
!9 = !DISubrange(count: 19, lowerBound: 2)
|
||||
!10 = distinct !DILocalVariable(scope: !11, file: !3, type: !14, flags: DIFlagArtificial)
|
||||
!11 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !12, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2)
|
||||
!12 = !DISubroutineType(cc: DW_CC_program, types: !13)
|
||||
!13 = !{null}
|
||||
!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32, align: 32)
|
||||
!15 = distinct !DILocalVariable(scope: !11, file: !3, type: !16, flags: DIFlagArtificial)
|
||||
!16 = !DIBasicType(name: "logical", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
!17 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32, align: 32, elements: !8, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref))
|
|
@ -0,0 +1,56 @@
|
|||
; RUN: llc %s -O2 -filetype=obj -o %t.o
|
||||
; RUN: llvm-dwarfdump %t.o | FileCheck %s
|
||||
|
||||
; Test whether DW_AT_data_location is generated.
|
||||
; CHECK-LABEL: DW_TAG_array_type
|
||||
; CHECK: DW_AT_allocated (DW_OP_push_object_address, DW_OP_deref)
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_TAG_subrange_type
|
||||
|
||||
; Test case is hand written with the help of below testcase
|
||||
;------------------------------
|
||||
;program main
|
||||
;integer, allocatable :: arr(:)
|
||||
;allocate(arr(2:20))
|
||||
;arr(2)=99
|
||||
;print *, arr
|
||||
;end program main
|
||||
;------------------------------
|
||||
|
||||
; ModuleID = 'allocated.ll'
|
||||
source_filename = "allocated.ll"
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define void @MAIN_() !dbg !5 {
|
||||
L.entry:
|
||||
%.Z0640_333 = alloca i32*, align 8
|
||||
%"arr$sd1_349" = alloca [16 x i64], align 8
|
||||
call void @llvm.dbg.declare(metadata [16 x i64]* %"arr$sd1_349", metadata !8, metadata !DIExpression()), !dbg !13
|
||||
call void @llvm.dbg.declare(metadata i32** %.Z0640_333, metadata !14, metadata !DIExpression()), !dbg !13
|
||||
ret void, !dbg !16
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone speculatable willreturn
|
||||
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||
|
||||
!llvm.module.flags = !{!0, !1}
|
||||
!llvm.dbg.cu = !{!2}
|
||||
|
||||
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !4)
|
||||
!3 = !DIFile(filename: "allocated.f90", directory: "/dir")
|
||||
!4 = !{}
|
||||
!5 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2)
|
||||
!6 = !DISubroutineType(cc: DW_CC_program, types: !7)
|
||||
!7 = !{null}
|
||||
!8 = !DILocalVariable(name: "arr", scope: !5, file: !3, type: !9)
|
||||
!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 32, align: 32, elements: !11, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), allocated: !DIExpression(DW_OP_push_object_address, DW_OP_deref))
|
||||
!10 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
!11 = !{!12}
|
||||
!12 = !DISubrange(count: 19, lowerBound: 2)
|
||||
!13 = !DILocation(line: 0, scope: !5)
|
||||
!14 = distinct !DILocalVariable(scope: !5, file: !3, type: !15, flags: DIFlagArtificial)
|
||||
!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 32, align: 32)
|
||||
!16 = !DILocation(line: 6, column: 1, scope: !5)
|
|
@ -0,0 +1,68 @@
|
|||
;; This test checks whether DW_AT_data_location attribute
|
||||
;; accepts DIVariable
|
||||
|
||||
; RUN: llc -mtriple=x86_64-unknown-linux-gnu %s -filetype=obj -o %t.o
|
||||
; RUN: llvm-dwarfdump %t.o | FileCheck %s
|
||||
|
||||
;; Test whether DW_AT_data_location is generated.
|
||||
; CHECK: [[ALCDIE:0x.+]]: DW_TAG_variable
|
||||
; CHECK: DW_AT_type ({{0x[0-9]+}} "logical")
|
||||
; CHECK: [[LOCDIE:0x.+]]: DW_TAG_variable
|
||||
; CHECK: DW_AT_type ({{0x[0-9]+}} "integer*")
|
||||
; CHECK: DW_AT_artificial (true)
|
||||
; CHECK: DW_TAG_variable
|
||||
; CHECK: DW_AT_name ("arr")
|
||||
; CHECK: DW_TAG_array_type
|
||||
; CHECK-NEXT: DW_AT_data_location ([[LOCDIE]])
|
||||
; CHECK-NEXT: DW_AT_allocated ([[ALCDIE]])
|
||||
|
||||
;; Test case is hand written with the help of below testcase
|
||||
;;------------------------------
|
||||
;;program main
|
||||
;;integer, allocatable :: arr(:)
|
||||
;;allocate(arr(2:20))
|
||||
;;arr(2)=99
|
||||
;;print *, arr
|
||||
;;end program main
|
||||
;;------------------------------
|
||||
|
||||
; ModuleID = 'allocated.ll'
|
||||
source_filename = "allocated.ll"
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define void @MAIN_() !dbg !5 {
|
||||
L.entry:
|
||||
%.Z0640_333 = alloca i32*, align 8
|
||||
%"arr$sd1_349" = alloca [16 x i64], align 8
|
||||
call void @llvm.dbg.declare(metadata [16 x i64]* %"arr$sd1_349", metadata !8, metadata !DIExpression()), !dbg !17
|
||||
call void @llvm.dbg.declare(metadata i32** %.Z0640_333, metadata !13, metadata !DIExpression()), !dbg !17
|
||||
call void @llvm.dbg.declare(metadata i32** %.Z0640_333, metadata !15, metadata !DIExpression()), !dbg !17
|
||||
ret void, !dbg !18
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone speculatable willreturn
|
||||
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||
|
||||
!llvm.module.flags = !{!0, !1}
|
||||
!llvm.dbg.cu = !{!2}
|
||||
|
||||
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !4)
|
||||
!3 = !DIFile(filename: "allocated.f90", directory: "/dir")
|
||||
!4 = !{}
|
||||
!5 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2)
|
||||
!6 = !DISubroutineType(cc: DW_CC_program, types: !7)
|
||||
!7 = !{null}
|
||||
!8 = !DILocalVariable(name: "arr", scope: !5, file: !3, type: !9)
|
||||
!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 32, align: 32, elements: !11, dataLocation: !13, allocated: !15)
|
||||
!10 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
!11 = !{!12}
|
||||
!12 = !DISubrange(count: 19, lowerBound: 2)
|
||||
!13 = distinct !DILocalVariable(scope: !5, file: !3, type: !14, flags: DIFlagArtificial)
|
||||
!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 32, align: 32)
|
||||
!15 = distinct !DILocalVariable(scope: !5, file: !3, type: !16, flags: DIFlagArtificial)
|
||||
!16 = !DIBasicType(name: "logical", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
!17 = !DILocation(line: 0, scope: !5)
|
||||
!18 = !DILocation(line: 6, column: 1, scope: !5)
|
|
@ -0,0 +1,56 @@
|
|||
; RUN: llc %s -O2 -filetype=obj -o %t.o
|
||||
; RUN: llvm-dwarfdump %t.o | FileCheck %s
|
||||
|
||||
; Test whether DW_AT_data_location is generated.
|
||||
; CHECK-LABEL: DW_TAG_array_type
|
||||
; CHECK-NOT: DW_TAG
|
||||
; CHECK: DW_AT_associated (DW_OP_push_object_address, DW_OP_deref)
|
||||
; CHECK: DW_TAG_subrange_type
|
||||
|
||||
; Test case is hand written with the help of below testcase
|
||||
;------------------------------
|
||||
;program main
|
||||
;integer, pointer :: arr(:)
|
||||
;allocate(arr(2:20))
|
||||
;arr(2)=99
|
||||
;print *, arr
|
||||
;end program main
|
||||
;------------------------------
|
||||
|
||||
; ModuleID = 'associated.ll'
|
||||
source_filename = "associated.ll"
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define void @MAIN_() !dbg !5 {
|
||||
L.entry:
|
||||
%.Z0640_333 = alloca i32*, align 8
|
||||
%"arr$sd1_349" = alloca [16 x i64], align 8
|
||||
call void @llvm.dbg.declare(metadata [16 x i64]* %"arr$sd1_349", metadata !8, metadata !DIExpression()), !dbg !13
|
||||
call void @llvm.dbg.declare(metadata i32** %.Z0640_333, metadata !14, metadata !DIExpression()), !dbg !13
|
||||
ret void, !dbg !16
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone speculatable willreturn
|
||||
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||
|
||||
!llvm.module.flags = !{!0, !1}
|
||||
!llvm.dbg.cu = !{!2}
|
||||
|
||||
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !4)
|
||||
!3 = !DIFile(filename: "associated.f90", directory: "/dir")
|
||||
!4 = !{}
|
||||
!5 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2)
|
||||
!6 = !DISubroutineType(cc: DW_CC_program, types: !7)
|
||||
!7 = !{null}
|
||||
!8 = !DILocalVariable(name: "arr", scope: !5, file: !3, type: !9)
|
||||
!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 32, align: 32, elements: !11, dataLocation: !DIExpression(DW_OP_push_object_address, DW_OP_deref), associated: !DIExpression(DW_OP_push_object_address, DW_OP_deref))
|
||||
!10 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
!11 = !{!12}
|
||||
!12 = !DISubrange(count: 19, lowerBound: 2)
|
||||
!13 = !DILocation(line: 0, scope: !5)
|
||||
!14 = distinct !DILocalVariable(scope: !5, file: !3, type: !15, flags: DIFlagArtificial)
|
||||
!15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 32, align: 32)
|
||||
!16 = !DILocation(line: 6, column: 1, scope: !5)
|
|
@ -0,0 +1,68 @@
|
|||
;; This test checks whether DW_AT_data_location attribute
|
||||
;; accepts DIVariable
|
||||
|
||||
; RUN: llc -mtriple=x86_64-unknown-linux-gnu %s -filetype=obj -o %t.o
|
||||
; RUN: llvm-dwarfdump %t.o | FileCheck %s
|
||||
|
||||
;; Test whether DW_AT_data_location is generated.
|
||||
; CHECK: [[ALCDIE:0x.+]]: DW_TAG_variable
|
||||
; CHECK: DW_AT_type ({{0x[0-9]+}} "logical")
|
||||
; CHECK: [[LOCDIE:0x.+]]: DW_TAG_variable
|
||||
; CHECK: DW_AT_type ({{0x[0-9]+}} "integer*")
|
||||
; CHECK: DW_AT_artificial (true)
|
||||
; CHECK: DW_TAG_variable
|
||||
; CHECK: DW_AT_name ("arr")
|
||||
; CHECK: DW_TAG_array_type
|
||||
; CHECK-NEXT: DW_AT_data_location ([[LOCDIE]])
|
||||
; CHECK-NEXT: DW_AT_associated ([[ALCDIE]])
|
||||
|
||||
;; Test case is hand written with the help of below testcase
|
||||
;;------------------------------
|
||||
;;program main
|
||||
;;integer, pointer :: arr(:)
|
||||
;;allocate(arr(2:20))
|
||||
;;arr(2)=99
|
||||
;;print *, arr
|
||||
;;end program main
|
||||
;;------------------------------
|
||||
|
||||
; ModuleID = 'associated.ll'
|
||||
source_filename = "associated.ll"
|
||||
target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
define void @MAIN_() !dbg !5 {
|
||||
L.entry:
|
||||
%.Z0640_333 = alloca i32*, align 8
|
||||
%"arr$sd1_349" = alloca [16 x i64], align 8
|
||||
call void @llvm.dbg.declare(metadata [16 x i64]* %"arr$sd1_349", metadata !8, metadata !DIExpression()), !dbg !17
|
||||
call void @llvm.dbg.declare(metadata i32** %.Z0640_333, metadata !13, metadata !DIExpression()), !dbg !17
|
||||
call void @llvm.dbg.declare(metadata i32** %.Z0640_333, metadata !15, metadata !DIExpression()), !dbg !17
|
||||
ret void, !dbg !18
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind readnone speculatable willreturn
|
||||
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||
|
||||
!llvm.module.flags = !{!0, !1}
|
||||
!llvm.dbg.cu = !{!2}
|
||||
|
||||
!0 = !{i32 2, !"Dwarf Version", i32 4}
|
||||
!1 = !{i32 2, !"Debug Info Version", i32 3}
|
||||
!2 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, retainedTypes: !4, globals: !4, imports: !4)
|
||||
!3 = !DIFile(filename: "associated.f90", directory: "/dir")
|
||||
!4 = !{}
|
||||
!5 = distinct !DISubprogram(name: "main", scope: !2, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !2)
|
||||
!6 = !DISubroutineType(cc: DW_CC_program, types: !7)
|
||||
!7 = !{null}
|
||||
!8 = !DILocalVariable(name: "arr", scope: !5, file: !3, type: !9)
|
||||
!9 = !DICompositeType(tag: DW_TAG_array_type, baseType: !10, size: 32, align: 32, elements: !11, dataLocation: !13, associated: !15)
|
||||
!10 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
!11 = !{!12}
|
||||
!12 = !DISubrange(count: 19, lowerBound: 2)
|
||||
!13 = distinct !DILocalVariable(scope: !5, file: !3, type: !14, flags: DIFlagArtificial)
|
||||
!14 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !10, size: 32, align: 32)
|
||||
!15 = distinct !DILocalVariable(scope: !5, file: !3, type: !16, flags: DIFlagArtificial)
|
||||
!16 = !DIBasicType(name: "logical", size: 32, align: 32, encoding: DW_ATE_signed)
|
||||
!17 = !DILocation(line: 0, scope: !5)
|
||||
!18 = !DILocation(line: 6, column: 1, scope: !5)
|
|
@ -0,0 +1,6 @@
|
|||
; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s
|
||||
|
||||
!named = !{!0}
|
||||
!0 = !DICompositeType(tag: DW_TAG_structure_type, name: "A", size: 64, allocated: !DIExpression(DW_OP_constu, 6789))
|
||||
|
||||
; CHECK: allocated can only appear in array type
|
|
@ -0,0 +1,6 @@
|
|||
; RUN: not llvm-as -disable-output <%s 2>&1 | FileCheck %s
|
||||
|
||||
!named = !{!0}
|
||||
!0 = !DICompositeType(tag: DW_TAG_structure_type, name: "A", size: 64, associated: !DIExpression(DW_OP_constu, 6789))
|
||||
|
||||
; CHECK: associated can only appear in array type
|
|
@ -30,7 +30,7 @@ TEST(DebugTypeODRUniquingTest, getODRType) {
|
|||
EXPECT_FALSE(DICompositeType::getODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr,
|
||||
nullptr));
|
||||
nullptr, nullptr, nullptr));
|
||||
|
||||
// Enable the mapping. There still shouldn't be a type.
|
||||
Context.enableDebugTypeODRUniquing();
|
||||
|
@ -40,7 +40,7 @@ TEST(DebugTypeODRUniquingTest, getODRType) {
|
|||
auto &CT = *DICompositeType::getODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr,
|
||||
nullptr);
|
||||
nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(UUID.getString(), CT.getIdentifier());
|
||||
|
||||
// Check that we get it back, even if we change a field.
|
||||
|
@ -48,12 +48,12 @@ TEST(DebugTypeODRUniquingTest, getODRType) {
|
|||
EXPECT_EQ(&CT, DICompositeType::getODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
|
||||
nullptr, nullptr, nullptr, nullptr));
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||
EXPECT_EQ(&CT, DICompositeType::getODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type,
|
||||
MDString::get(Context, "name"), nullptr, 0, nullptr,
|
||||
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr,
|
||||
nullptr, nullptr, nullptr));
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||
|
||||
// Check that it's discarded with the type map.
|
||||
Context.disableDebugTypeODRUniquing();
|
||||
|
@ -73,34 +73,36 @@ TEST(DebugTypeODRUniquingTest, buildODRType) {
|
|||
auto &CT = *DICompositeType::buildODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||
nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr,
|
||||
nullptr, nullptr);
|
||||
nullptr, nullptr, nullptr, nullptr);
|
||||
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
|
||||
|
||||
// Update with another forward decl. This should be a no-op.
|
||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||
Context, UUID, dwarf::DW_TAG_structure_type, nullptr,
|
||||
nullptr, 0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl,
|
||||
nullptr, 0, nullptr, nullptr, nullptr, nullptr));
|
||||
EXPECT_EQ(&CT,
|
||||
DICompositeType::buildODRType(
|
||||
Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr,
|
||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
|
||||
|
||||
// Update with a definition. This time we should see a change.
|
||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||
Context, UUID, dwarf::DW_TAG_structure_type, nullptr,
|
||||
nullptr, 0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero,
|
||||
nullptr, 0, nullptr, nullptr, nullptr, nullptr));
|
||||
EXPECT_EQ(&CT,
|
||||
DICompositeType::buildODRType(
|
||||
Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr,
|
||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
|
||||
|
||||
// Further updates should be ignored.
|
||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr,
|
||||
0, nullptr, nullptr, nullptr, nullptr));
|
||||
0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
|
||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
|
||||
nullptr, nullptr, nullptr, nullptr));
|
||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
|
||||
}
|
||||
|
||||
|
@ -112,7 +114,8 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {
|
|||
MDString &UUID = *MDString::get(Context, "UUID");
|
||||
auto &CT = *DICompositeType::buildODRType(
|
||||
Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0,
|
||||
DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr);
|
||||
DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr, nullptr, nullptr,
|
||||
nullptr, nullptr);
|
||||
|
||||
// Create macros for running through all the fields except Identifier and Flags.
|
||||
#define FOR_EACH_MDFIELD() \
|
||||
|
@ -141,11 +144,12 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {
|
|||
#undef DO_FOR_FIELD
|
||||
|
||||
// Replace all the fields with new values that are distinct from each other.
|
||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
||||
Context, UUID, Tag, Name, File, Line, Scope, BaseType,
|
||||
SizeInBits, AlignInBits, OffsetInBits,
|
||||
DINode::FlagArtificial, Elements, RuntimeLang,
|
||||
VTableHolder, TemplateParams, nullptr, nullptr));
|
||||
EXPECT_EQ(&CT,
|
||||
DICompositeType::buildODRType(
|
||||
Context, UUID, Tag, Name, File, Line, Scope, BaseType,
|
||||
SizeInBits, AlignInBits, OffsetInBits, DINode::FlagArtificial,
|
||||
Elements, RuntimeLang, VTableHolder, TemplateParams, nullptr,
|
||||
nullptr, nullptr, nullptr));
|
||||
|
||||
// Confirm that all the right fields got updated.
|
||||
#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X());
|
||||
|
|
Loading…
Reference in New Issue