mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 04:02:41 +01:00
[DebugInfo] Support for DWARF attribute DW_AT_rank
This patch adds support for DWARF attribute DW_AT_rank. Summary: Fortran assumed rank arrays have dynamic rank. DWARF attribute DW_AT_rank is needed to support that. Testing: unit test cases added (hand-written) check llvm check debug-info Reviewed By: aprantl Differential Revision: https://reviews.llvm.org/D89141
This commit is contained in:
parent
d5dc3dc1f4
commit
0a8029e199
@ -4906,7 +4906,9 @@ arrays which can be attached to actual arrays, this attachment between pointer
|
|||||||
and pointee is called association. The optional ``associated`` is a
|
and pointee is called association. The optional ``associated`` is a
|
||||||
DIExpression that describes whether the pointer array is currently associated.
|
DIExpression that describes whether the pointer array is currently associated.
|
||||||
The optional ``allocated`` is a DIExpression that describes whether the
|
The optional ``allocated`` is a DIExpression that describes whether the
|
||||||
allocatable array is currently allocated.
|
allocatable array is currently allocated. The optional ``rank`` is a
|
||||||
|
DIExpression that describes the rank (number of dimensions) of fortran assumed
|
||||||
|
rank array (rank is known at runtime).
|
||||||
|
|
||||||
For ``DW_TAG_enumeration_type``, the ``elements:`` should be :ref:`enumerator
|
For ``DW_TAG_enumeration_type``, the ``elements:`` should be :ref:`enumerator
|
||||||
descriptors <DIEnumerator>`, each representing the definition of an enumeration
|
descriptors <DIEnumerator>`, each representing the definition of an enumeration
|
||||||
|
@ -1026,14 +1026,14 @@ class DICompositeType : public DIType {
|
|||||||
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
|
DINodeArray Elements, unsigned RuntimeLang, DIType *VTableHolder,
|
||||||
DITemplateParameterArray TemplateParams, StringRef Identifier,
|
DITemplateParameterArray TemplateParams, StringRef Identifier,
|
||||||
DIDerivedType *Discriminator, Metadata *DataLocation,
|
DIDerivedType *Discriminator, Metadata *DataLocation,
|
||||||
Metadata *Associated, Metadata *Allocated, StorageType Storage,
|
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
|
||||||
bool ShouldCreate = true) {
|
StorageType Storage, bool ShouldCreate = true) {
|
||||||
return getImpl(Context, Tag, getCanonicalMDString(Context, Name), File,
|
return getImpl(
|
||||||
Line, Scope, BaseType, SizeInBits, AlignInBits, OffsetInBits,
|
Context, Tag, getCanonicalMDString(Context, Name), File, Line, Scope,
|
||||||
Flags, Elements.get(), RuntimeLang, VTableHolder,
|
BaseType, SizeInBits, AlignInBits, OffsetInBits, Flags, Elements.get(),
|
||||||
TemplateParams.get(),
|
RuntimeLang, VTableHolder, TemplateParams.get(),
|
||||||
getCanonicalMDString(Context, Identifier), Discriminator,
|
getCanonicalMDString(Context, Identifier), Discriminator, DataLocation,
|
||||||
DataLocation, Associated, Allocated, Storage, ShouldCreate);
|
Associated, Allocated, Rank, Storage, ShouldCreate);
|
||||||
}
|
}
|
||||||
static DICompositeType *
|
static DICompositeType *
|
||||||
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
|
getImpl(LLVMContext &Context, unsigned Tag, MDString *Name, Metadata *File,
|
||||||
@ -1042,16 +1042,17 @@ class DICompositeType : public DIType {
|
|||||||
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
|
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
|
||||||
Metadata *VTableHolder, Metadata *TemplateParams,
|
Metadata *VTableHolder, Metadata *TemplateParams,
|
||||||
MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
|
MDString *Identifier, Metadata *Discriminator, Metadata *DataLocation,
|
||||||
Metadata *Associated, Metadata *Allocated, StorageType Storage,
|
Metadata *Associated, Metadata *Allocated, Metadata *Rank,
|
||||||
bool ShouldCreate = true);
|
StorageType Storage, bool ShouldCreate = true);
|
||||||
|
|
||||||
TempDICompositeType cloneImpl() const {
|
TempDICompositeType cloneImpl() const {
|
||||||
return getTemporary(
|
return getTemporary(getContext(), getTag(), getName(), getFile(), getLine(),
|
||||||
getContext(), getTag(), getName(), getFile(), getLine(), getScope(),
|
getScope(), getBaseType(), getSizeInBits(),
|
||||||
getBaseType(), getSizeInBits(), getAlignInBits(), getOffsetInBits(),
|
getAlignInBits(), getOffsetInBits(), getFlags(),
|
||||||
getFlags(), getElements(), getRuntimeLang(), getVTableHolder(),
|
getElements(), getRuntimeLang(), getVTableHolder(),
|
||||||
getTemplateParams(), getIdentifier(), getDiscriminator(),
|
getTemplateParams(), getIdentifier(),
|
||||||
getRawDataLocation(), getRawAssociated(), getRawAllocated());
|
getDiscriminator(), getRawDataLocation(),
|
||||||
|
getRawAssociated(), getRawAllocated(), getRawRank());
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@ -1064,10 +1065,10 @@ public:
|
|||||||
DITemplateParameterArray TemplateParams = nullptr,
|
DITemplateParameterArray TemplateParams = nullptr,
|
||||||
StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
|
StringRef Identifier = "", DIDerivedType *Discriminator = nullptr,
|
||||||
Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
|
Metadata *DataLocation = nullptr, Metadata *Associated = nullptr,
|
||||||
Metadata *Allocated = nullptr),
|
Metadata *Allocated = nullptr, Metadata *Rank = nullptr),
|
||||||
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
|
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
|
||||||
Identifier, Discriminator, DataLocation, Associated, Allocated))
|
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank))
|
||||||
DEFINE_MDNODE_GET(
|
DEFINE_MDNODE_GET(
|
||||||
DICompositeType,
|
DICompositeType,
|
||||||
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
|
(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
|
||||||
@ -1076,10 +1077,11 @@ public:
|
|||||||
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
|
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
|
||||||
Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr,
|
Metadata *TemplateParams = nullptr, MDString *Identifier = nullptr,
|
||||||
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
|
Metadata *Discriminator = nullptr, Metadata *DataLocation = nullptr,
|
||||||
Metadata *Associated = nullptr, Metadata *Allocated = nullptr),
|
Metadata *Associated = nullptr, Metadata *Allocated = nullptr,
|
||||||
|
Metadata *Rank = nullptr),
|
||||||
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
|
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
|
||||||
Identifier, Discriminator, DataLocation, Associated, Allocated))
|
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank))
|
||||||
|
|
||||||
TempDICompositeType clone() const { return cloneImpl(); }
|
TempDICompositeType clone() const { return cloneImpl(); }
|
||||||
|
|
||||||
@ -1097,7 +1099,8 @@ public:
|
|||||||
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
|
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
|
||||||
unsigned RuntimeLang, Metadata *VTableHolder,
|
unsigned RuntimeLang, Metadata *VTableHolder,
|
||||||
Metadata *TemplateParams, Metadata *Discriminator,
|
Metadata *TemplateParams, Metadata *Discriminator,
|
||||||
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated);
|
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
|
||||||
|
Metadata *Rank);
|
||||||
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
|
static DICompositeType *getODRTypeIfExists(LLVMContext &Context,
|
||||||
MDString &Identifier);
|
MDString &Identifier);
|
||||||
|
|
||||||
@ -1110,13 +1113,15 @@ public:
|
|||||||
///
|
///
|
||||||
/// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
|
/// If not \a LLVMContext::isODRUniquingDebugTypes(), this function returns
|
||||||
/// nullptr.
|
/// nullptr.
|
||||||
static DICompositeType *buildODRType(
|
static DICompositeType *
|
||||||
LLVMContext &Context, MDString &Identifier, unsigned Tag, MDString *Name,
|
buildODRType(LLVMContext &Context, MDString &Identifier, unsigned Tag,
|
||||||
Metadata *File, unsigned Line, Metadata *Scope, Metadata *BaseType,
|
MDString *Name, Metadata *File, unsigned Line, Metadata *Scope,
|
||||||
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
Metadata *BaseType, uint64_t SizeInBits, uint32_t AlignInBits,
|
||||||
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
|
uint64_t OffsetInBits, DIFlags Flags, Metadata *Elements,
|
||||||
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
|
unsigned RuntimeLang, Metadata *VTableHolder,
|
||||||
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated);
|
Metadata *TemplateParams, Metadata *Discriminator,
|
||||||
|
Metadata *DataLocation, Metadata *Associated,
|
||||||
|
Metadata *Allocated, Metadata *Rank);
|
||||||
|
|
||||||
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
|
DIType *getBaseType() const { return cast_or_null<DIType>(getRawBaseType()); }
|
||||||
DINodeArray getElements() const {
|
DINodeArray getElements() const {
|
||||||
@ -1159,6 +1164,15 @@ public:
|
|||||||
DIExpression *getAllocatedExp() const {
|
DIExpression *getAllocatedExp() const {
|
||||||
return dyn_cast_or_null<DIExpression>(getRawAllocated());
|
return dyn_cast_or_null<DIExpression>(getRawAllocated());
|
||||||
}
|
}
|
||||||
|
Metadata *getRawRank() const { return getOperand(12); }
|
||||||
|
ConstantInt *getRankConst() const {
|
||||||
|
if (auto *MD = dyn_cast_or_null<ConstantAsMetadata>(getRawRank()))
|
||||||
|
return dyn_cast_or_null<ConstantInt>(MD->getValue());
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
DIExpression *getRankExp() const {
|
||||||
|
return dyn_cast_or_null<DIExpression>(getRawRank());
|
||||||
|
}
|
||||||
|
|
||||||
/// Replace operands.
|
/// Replace operands.
|
||||||
///
|
///
|
||||||
|
@ -4712,18 +4712,26 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
|
|||||||
OPTIONAL(discriminator, MDField, ); \
|
OPTIONAL(discriminator, MDField, ); \
|
||||||
OPTIONAL(dataLocation, MDField, ); \
|
OPTIONAL(dataLocation, MDField, ); \
|
||||||
OPTIONAL(associated, MDField, ); \
|
OPTIONAL(associated, MDField, ); \
|
||||||
OPTIONAL(allocated, MDField, );
|
OPTIONAL(allocated, MDField, ); \
|
||||||
|
OPTIONAL(rank, MDSignedOrMDField, );
|
||||||
PARSE_MD_FIELDS();
|
PARSE_MD_FIELDS();
|
||||||
#undef VISIT_MD_FIELDS
|
#undef VISIT_MD_FIELDS
|
||||||
|
|
||||||
|
Metadata *Rank = nullptr;
|
||||||
|
if (rank.isMDSignedField())
|
||||||
|
Rank = ConstantAsMetadata::get(ConstantInt::getSigned(
|
||||||
|
Type::getInt64Ty(Context), rank.getMDSignedValue()));
|
||||||
|
else if (rank.isMDField())
|
||||||
|
Rank = rank.getMDFieldValue();
|
||||||
|
|
||||||
// If this has an identifier try to build an ODR type.
|
// If this has an identifier try to build an ODR type.
|
||||||
if (identifier.Val)
|
if (identifier.Val)
|
||||||
if (auto *CT = DICompositeType::buildODRType(
|
if (auto *CT = DICompositeType::buildODRType(
|
||||||
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
|
Context, *identifier.Val, tag.Val, name.Val, file.Val, line.Val,
|
||||||
scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val,
|
scope.Val, baseType.Val, size.Val, align.Val, offset.Val, flags.Val,
|
||||||
elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val,
|
elements.Val, runtimeLang.Val, vtableHolder.Val, templateParams.Val,
|
||||||
discriminator.Val, dataLocation.Val, associated.Val,
|
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
|
||||||
allocated.Val)) {
|
Rank)) {
|
||||||
Result = CT;
|
Result = CT;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -4735,7 +4743,8 @@ bool LLParser::ParseDICompositeType(MDNode *&Result, bool IsDistinct) {
|
|||||||
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
|
(Context, tag.Val, name.Val, file.Val, line.Val, scope.Val, baseType.Val,
|
||||||
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
|
size.Val, align.Val, offset.Val, flags.Val, elements.Val,
|
||||||
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
|
runtimeLang.Val, vtableHolder.Val, templateParams.Val, identifier.Val,
|
||||||
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val));
|
discriminator.Val, dataLocation.Val, associated.Val, allocated.Val,
|
||||||
|
Rank));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1362,7 +1362,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case bitc::METADATA_COMPOSITE_TYPE: {
|
case bitc::METADATA_COMPOSITE_TYPE: {
|
||||||
if (Record.size() < 16 || Record.size() > 20)
|
if (Record.size() < 16 || Record.size() > 21)
|
||||||
return error("Invalid record");
|
return error("Invalid record");
|
||||||
|
|
||||||
// If we have a UUID and this is not a forward declaration, lookup the
|
// If we have a UUID and this is not a forward declaration, lookup the
|
||||||
@ -1389,6 +1389,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
|||||||
Metadata *DataLocation = nullptr;
|
Metadata *DataLocation = nullptr;
|
||||||
Metadata *Associated = nullptr;
|
Metadata *Associated = nullptr;
|
||||||
Metadata *Allocated = nullptr;
|
Metadata *Allocated = nullptr;
|
||||||
|
Metadata *Rank = nullptr;
|
||||||
auto *Identifier = getMDString(Record[15]);
|
auto *Identifier = getMDString(Record[15]);
|
||||||
// If this module is being parsed so that it can be ThinLTO imported
|
// If this module is being parsed so that it can be ThinLTO imported
|
||||||
// into another module, composite types only need to be imported
|
// into another module, composite types only need to be imported
|
||||||
@ -1417,6 +1418,9 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
|||||||
Associated = getMDOrNull(Record[18]);
|
Associated = getMDOrNull(Record[18]);
|
||||||
Allocated = getMDOrNull(Record[19]);
|
Allocated = getMDOrNull(Record[19]);
|
||||||
}
|
}
|
||||||
|
if (Record.size() > 20) {
|
||||||
|
Rank = getMDOrNull(Record[20]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
DICompositeType *CT = nullptr;
|
DICompositeType *CT = nullptr;
|
||||||
if (Identifier)
|
if (Identifier)
|
||||||
@ -1424,7 +1428,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
|||||||
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
|
Context, *Identifier, Tag, Name, File, Line, Scope, BaseType,
|
||||||
SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
|
SizeInBits, AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
|
||||||
VTableHolder, TemplateParams, Discriminator, DataLocation, Associated,
|
VTableHolder, TemplateParams, Discriminator, DataLocation, Associated,
|
||||||
Allocated);
|
Allocated, Rank);
|
||||||
|
|
||||||
// Create a node if we didn't get a lazy ODR type.
|
// Create a node if we didn't get a lazy ODR type.
|
||||||
if (!CT)
|
if (!CT)
|
||||||
@ -1433,7 +1437,7 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
|
|||||||
SizeInBits, AlignInBits, OffsetInBits, Flags,
|
SizeInBits, AlignInBits, OffsetInBits, Flags,
|
||||||
Elements, RuntimeLang, VTableHolder, TemplateParams,
|
Elements, RuntimeLang, VTableHolder, TemplateParams,
|
||||||
Identifier, Discriminator, DataLocation, Associated,
|
Identifier, Discriminator, DataLocation, Associated,
|
||||||
Allocated));
|
Allocated, Rank));
|
||||||
if (!IsNotUsedInTypeRef && Identifier)
|
if (!IsNotUsedInTypeRef && Identifier)
|
||||||
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
|
MetadataList.addTypeRef(*Identifier, *cast<DICompositeType>(CT));
|
||||||
|
|
||||||
|
@ -1662,6 +1662,7 @@ void ModuleBitcodeWriter::writeDICompositeType(
|
|||||||
Record.push_back(VE.getMetadataOrNullID(N->getRawDataLocation()));
|
Record.push_back(VE.getMetadataOrNullID(N->getRawDataLocation()));
|
||||||
Record.push_back(VE.getMetadataOrNullID(N->getRawAssociated()));
|
Record.push_back(VE.getMetadataOrNullID(N->getRawAssociated()));
|
||||||
Record.push_back(VE.getMetadataOrNullID(N->getRawAllocated()));
|
Record.push_back(VE.getMetadataOrNullID(N->getRawAllocated()));
|
||||||
|
Record.push_back(VE.getMetadataOrNullID(N->getRawRank()));
|
||||||
|
|
||||||
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
|
Stream.EmitRecord(bitc::METADATA_COMPOSITE_TYPE, Record, Abbrev);
|
||||||
Record.clear();
|
Record.clear();
|
||||||
|
@ -1472,6 +1472,17 @@ void DwarfUnit::constructArrayTypeDIE(DIE &Buffer, const DICompositeType *CTy) {
|
|||||||
addBlock(Buffer, dwarf::DW_AT_allocated, DwarfExpr.finalize());
|
addBlock(Buffer, dwarf::DW_AT_allocated, DwarfExpr.finalize());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto *RankConst = CTy->getRankConst()) {
|
||||||
|
addSInt(Buffer, dwarf::DW_AT_rank, dwarf::DW_FORM_sdata,
|
||||||
|
RankConst->getSExtValue());
|
||||||
|
} else if (auto *RankExpr = CTy->getRankExp()) {
|
||||||
|
DIELoc *Loc = new (DIEValueAllocator) DIELoc;
|
||||||
|
DIEDwarfExpression DwarfExpr(*Asm, getCU(), *Loc);
|
||||||
|
DwarfExpr.setMemoryLocationKind();
|
||||||
|
DwarfExpr.addExpression(RankExpr);
|
||||||
|
addBlock(Buffer, dwarf::DW_AT_rank, DwarfExpr.finalize());
|
||||||
|
}
|
||||||
|
|
||||||
// Emit the element type.
|
// Emit the element type.
|
||||||
addType(Buffer, CTy->getBaseType());
|
addType(Buffer, CTy->getBaseType());
|
||||||
|
|
||||||
|
@ -1991,6 +1991,11 @@ static void writeDICompositeType(raw_ostream &Out, const DICompositeType *N,
|
|||||||
Printer.printMetadata("dataLocation", N->getRawDataLocation());
|
Printer.printMetadata("dataLocation", N->getRawDataLocation());
|
||||||
Printer.printMetadata("associated", N->getRawAssociated());
|
Printer.printMetadata("associated", N->getRawAssociated());
|
||||||
Printer.printMetadata("allocated", N->getRawAllocated());
|
Printer.printMetadata("allocated", N->getRawAllocated());
|
||||||
|
if (auto *RankConst = N->getRankConst())
|
||||||
|
Printer.printInt("rank", RankConst->getSExtValue(),
|
||||||
|
/* ShouldSkipZero */ false);
|
||||||
|
else
|
||||||
|
Printer.printMetadata("rank", N->getRawRank(), /*ShouldSkipNull */ true);
|
||||||
Out << ")";
|
Out << ")";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -508,18 +508,19 @@ DICompositeType *DICompositeType::getImpl(
|
|||||||
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
|
Metadata *Elements, unsigned RuntimeLang, Metadata *VTableHolder,
|
||||||
Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator,
|
Metadata *TemplateParams, MDString *Identifier, Metadata *Discriminator,
|
||||||
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
|
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
|
||||||
StorageType Storage, bool ShouldCreate) {
|
Metadata *Rank, StorageType Storage, bool ShouldCreate) {
|
||||||
assert(isCanonical(Name) && "Expected canonical MDString");
|
assert(isCanonical(Name) && "Expected canonical MDString");
|
||||||
|
|
||||||
// Keep this in sync with buildODRType.
|
// Keep this in sync with buildODRType.
|
||||||
DEFINE_GETIMPL_LOOKUP(DICompositeType,
|
DEFINE_GETIMPL_LOOKUP(
|
||||||
(Tag, Name, File, Line, Scope, BaseType, SizeInBits,
|
DICompositeType,
|
||||||
AlignInBits, OffsetInBits, Flags, Elements,
|
(Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
RuntimeLang, VTableHolder, TemplateParams, Identifier,
|
OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder, TemplateParams,
|
||||||
Discriminator, DataLocation, Associated, Allocated));
|
Identifier, Discriminator, DataLocation, Associated, Allocated, Rank));
|
||||||
Metadata *Ops[] = {File, Scope, Name, BaseType,
|
Metadata *Ops[] = {File, Scope, Name, BaseType,
|
||||||
Elements, VTableHolder, TemplateParams, Identifier,
|
Elements, VTableHolder, TemplateParams, Identifier,
|
||||||
Discriminator, DataLocation, Associated, Allocated};
|
Discriminator, DataLocation, Associated, Allocated,
|
||||||
|
Rank};
|
||||||
DEFINE_GETIMPL_STORE(DICompositeType, (Tag, Line, RuntimeLang, SizeInBits,
|
DEFINE_GETIMPL_STORE(DICompositeType, (Tag, Line, RuntimeLang, SizeInBits,
|
||||||
AlignInBits, OffsetInBits, Flags),
|
AlignInBits, OffsetInBits, Flags),
|
||||||
Ops);
|
Ops);
|
||||||
@ -531,7 +532,8 @@ DICompositeType *DICompositeType::buildODRType(
|
|||||||
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
||||||
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
|
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
|
||||||
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
|
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
|
||||||
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated) {
|
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
|
||||||
|
Metadata *Rank) {
|
||||||
assert(!Identifier.getString().empty() && "Expected valid identifier");
|
assert(!Identifier.getString().empty() && "Expected valid identifier");
|
||||||
if (!Context.isODRUniquingDebugTypes())
|
if (!Context.isODRUniquingDebugTypes())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -541,7 +543,7 @@ DICompositeType *DICompositeType::buildODRType(
|
|||||||
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
|
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
|
||||||
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
|
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang,
|
||||||
VTableHolder, TemplateParams, &Identifier, Discriminator,
|
VTableHolder, TemplateParams, &Identifier, Discriminator,
|
||||||
DataLocation, Associated, Allocated);
|
DataLocation, Associated, Allocated, Rank);
|
||||||
|
|
||||||
// Only mutate CT if it's a forward declaration and the new operands aren't.
|
// Only mutate CT if it's a forward declaration and the new operands aren't.
|
||||||
assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");
|
assert(CT->getRawIdentifier() == &Identifier && "Wrong ODR identifier?");
|
||||||
@ -553,7 +555,8 @@ DICompositeType *DICompositeType::buildODRType(
|
|||||||
Flags);
|
Flags);
|
||||||
Metadata *Ops[] = {File, Scope, Name, BaseType,
|
Metadata *Ops[] = {File, Scope, Name, BaseType,
|
||||||
Elements, VTableHolder, TemplateParams, &Identifier,
|
Elements, VTableHolder, TemplateParams, &Identifier,
|
||||||
Discriminator, DataLocation, Associated, Allocated};
|
Discriminator, DataLocation, Associated, Allocated,
|
||||||
|
Rank};
|
||||||
assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
|
assert((std::end(Ops) - std::begin(Ops)) == (int)CT->getNumOperands() &&
|
||||||
"Mismatched number of operands");
|
"Mismatched number of operands");
|
||||||
for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
|
for (unsigned I = 0, E = CT->getNumOperands(); I != E; ++I)
|
||||||
@ -568,7 +571,8 @@ DICompositeType *DICompositeType::getODRType(
|
|||||||
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
uint64_t SizeInBits, uint32_t AlignInBits, uint64_t OffsetInBits,
|
||||||
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
|
DIFlags Flags, Metadata *Elements, unsigned RuntimeLang,
|
||||||
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
|
Metadata *VTableHolder, Metadata *TemplateParams, Metadata *Discriminator,
|
||||||
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated) {
|
Metadata *DataLocation, Metadata *Associated, Metadata *Allocated,
|
||||||
|
Metadata *Rank) {
|
||||||
assert(!Identifier.getString().empty() && "Expected valid identifier");
|
assert(!Identifier.getString().empty() && "Expected valid identifier");
|
||||||
if (!Context.isODRUniquingDebugTypes())
|
if (!Context.isODRUniquingDebugTypes())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -578,7 +582,7 @@ DICompositeType *DICompositeType::getODRType(
|
|||||||
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
|
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits,
|
||||||
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder,
|
AlignInBits, OffsetInBits, Flags, Elements, RuntimeLang, VTableHolder,
|
||||||
TemplateParams, &Identifier, Discriminator, DataLocation, Associated,
|
TemplateParams, &Identifier, Discriminator, DataLocation, Associated,
|
||||||
Allocated);
|
Allocated, Rank);
|
||||||
return CT;
|
return CT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -538,6 +538,7 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||||||
Metadata *DataLocation;
|
Metadata *DataLocation;
|
||||||
Metadata *Associated;
|
Metadata *Associated;
|
||||||
Metadata *Allocated;
|
Metadata *Allocated;
|
||||||
|
Metadata *Rank;
|
||||||
|
|
||||||
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
|
MDNodeKeyImpl(unsigned Tag, MDString *Name, Metadata *File, unsigned Line,
|
||||||
Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
|
Metadata *Scope, Metadata *BaseType, uint64_t SizeInBits,
|
||||||
@ -546,14 +547,14 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||||||
Metadata *VTableHolder, Metadata *TemplateParams,
|
Metadata *VTableHolder, Metadata *TemplateParams,
|
||||||
MDString *Identifier, Metadata *Discriminator,
|
MDString *Identifier, Metadata *Discriminator,
|
||||||
Metadata *DataLocation, Metadata *Associated,
|
Metadata *DataLocation, Metadata *Associated,
|
||||||
Metadata *Allocated)
|
Metadata *Allocated, Metadata *Rank)
|
||||||
: Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
|
: Tag(Tag), Name(Name), File(File), Line(Line), Scope(Scope),
|
||||||
BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
|
BaseType(BaseType), SizeInBits(SizeInBits), OffsetInBits(OffsetInBits),
|
||||||
AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
|
AlignInBits(AlignInBits), Flags(Flags), Elements(Elements),
|
||||||
RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
|
RuntimeLang(RuntimeLang), VTableHolder(VTableHolder),
|
||||||
TemplateParams(TemplateParams), Identifier(Identifier),
|
TemplateParams(TemplateParams), Identifier(Identifier),
|
||||||
Discriminator(Discriminator), DataLocation(DataLocation),
|
Discriminator(Discriminator), DataLocation(DataLocation),
|
||||||
Associated(Associated), Allocated(Allocated) {}
|
Associated(Associated), Allocated(Allocated), Rank(Rank) {}
|
||||||
MDNodeKeyImpl(const DICompositeType *N)
|
MDNodeKeyImpl(const DICompositeType *N)
|
||||||
: Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
|
: Tag(N->getTag()), Name(N->getRawName()), File(N->getRawFile()),
|
||||||
Line(N->getLine()), Scope(N->getRawScope()),
|
Line(N->getLine()), Scope(N->getRawScope()),
|
||||||
@ -565,7 +566,8 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||||||
Identifier(N->getRawIdentifier()),
|
Identifier(N->getRawIdentifier()),
|
||||||
Discriminator(N->getRawDiscriminator()),
|
Discriminator(N->getRawDiscriminator()),
|
||||||
DataLocation(N->getRawDataLocation()),
|
DataLocation(N->getRawDataLocation()),
|
||||||
Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()) {}
|
Associated(N->getRawAssociated()), Allocated(N->getRawAllocated()),
|
||||||
|
Rank(N->getRawRank()) {}
|
||||||
|
|
||||||
bool isKeyOf(const DICompositeType *RHS) const {
|
bool isKeyOf(const DICompositeType *RHS) const {
|
||||||
return Tag == RHS->getTag() && Name == RHS->getRawName() &&
|
return Tag == RHS->getTag() && Name == RHS->getRawName() &&
|
||||||
@ -582,7 +584,7 @@ template <> struct MDNodeKeyImpl<DICompositeType> {
|
|||||||
Discriminator == RHS->getRawDiscriminator() &&
|
Discriminator == RHS->getRawDiscriminator() &&
|
||||||
DataLocation == RHS->getRawDataLocation() &&
|
DataLocation == RHS->getRawDataLocation() &&
|
||||||
Associated == RHS->getRawAssociated() &&
|
Associated == RHS->getRawAssociated() &&
|
||||||
Allocated == RHS->getRawAllocated();
|
Allocated == RHS->getRawAllocated() && Rank == RHS->getRawRank();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned getHashValue() const {
|
unsigned getHashValue() const {
|
||||||
|
@ -1056,6 +1056,11 @@ void Verifier::visitDICompositeType(const DICompositeType &N) {
|
|||||||
AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
|
AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
|
||||||
"allocated can only appear in array type");
|
"allocated can only appear in array type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (N.getRawRank()) {
|
||||||
|
AssertDI(N.getTag() == dwarf::DW_TAG_array_type,
|
||||||
|
"rank can only appear in array type");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Verifier::visitDISubroutineType(const DISubroutineType &N) {
|
void Verifier::visitDISubroutineType(const DISubroutineType &N) {
|
||||||
|
41
test/Bitcode/rankConst.ll
Normal file
41
test/Bitcode/rankConst.ll
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
;; This test checks rank field of DICompositeType
|
||||||
|
|
||||||
|
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
|
||||||
|
|
||||||
|
;; Test whether rank is generated.
|
||||||
|
; CHECK: !DICompositeType(tag: DW_TAG_array_type, baseType: !{{[0-9]+}}, size: 32, align: 32, elements: !{{[0-9]+}}, dataLocation: !{{[0-9]+}}, rank: 7)
|
||||||
|
|
||||||
|
; ModuleID = 'rank.f90'
|
||||||
|
source_filename = "/dir/rank.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: "arank.f90", directory: "/dir")
|
||||||
|
!4 = !{}
|
||||||
|
!5 = !{!6}
|
||||||
|
!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32, align: 32, elements: !8, dataLocation: !16, rank: 7)
|
||||||
|
!7 = !DIBasicType(name: "real", size: 32, align: 32, encoding: DW_ATE_float)
|
||||||
|
!8 = !{!9, !10, !11, !12, !13, !14, !15}
|
||||||
|
!9 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 80, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 120, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 112, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!10 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 128, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 168, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 160, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!11 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 176, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 216, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 208, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!12 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 224, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 264, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 256, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!13 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 272, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 312, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 304, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!14 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 320, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 360, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 352, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!15 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 368, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 408, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 400, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!16 = distinct !DILocalVariable(scope: !17, file: !3, type: !24, flags: DIFlagArtificial)
|
||||||
|
!17 = distinct !DISubprogram(name: "sub1", scope: !2, file: !3, line: 1, type: !18, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2)
|
||||||
|
!18 = !DISubroutineType(types: !19)
|
||||||
|
!19 = !{null, !20, !25}
|
||||||
|
!20 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32, align: 32, elements: !21)
|
||||||
|
!21 = !{!22}
|
||||||
|
!22 = !DISubrange(lowerBound: 1, upperBound: !23)
|
||||||
|
!23 = distinct !DILocalVariable(scope: !17, file: !3, type: !24, flags: DIFlagArtificial)
|
||||||
|
!24 = !DIBasicType(name: "integer*8", size: 64, align: 64, encoding: DW_ATE_signed)
|
||||||
|
!25 = !DICompositeType(tag: DW_TAG_array_type, baseType: !24, size: 1024, align: 64, elements: !26)
|
||||||
|
!26 = !{!27}
|
||||||
|
!27 = !DISubrange(lowerBound: 1, upperBound: 16)
|
41
test/Bitcode/rankExp.ll
Normal file
41
test/Bitcode/rankExp.ll
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
;; This test checks rank field of DICompositeType
|
||||||
|
|
||||||
|
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
|
||||||
|
|
||||||
|
;; Test whether rank is generated.
|
||||||
|
; CHECK: !DICompositeType(tag: DW_TAG_array_type, baseType: !{{[0-9]+}}, size: 32, align: 32, elements: !{{[0-9]+}}, dataLocation: !{{[0-9]+}}, rank: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8, DW_OP_deref))
|
||||||
|
|
||||||
|
; ModuleID = 'rank.f90'
|
||||||
|
source_filename = "/dir/rank.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: "arank.f90", directory: "/dir")
|
||||||
|
!4 = !{}
|
||||||
|
!5 = !{!6}
|
||||||
|
!6 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32, align: 32, elements: !8, dataLocation: !16, rank: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8, DW_OP_deref))
|
||||||
|
!7 = !DIBasicType(name: "real", size: 32, align: 32, encoding: DW_ATE_float)
|
||||||
|
!8 = !{!9, !10, !11, !12, !13, !14, !15}
|
||||||
|
!9 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 80, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 120, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 112, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!10 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 128, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 168, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 160, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!11 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 176, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 216, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 208, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!12 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 224, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 264, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 256, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!13 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 272, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 312, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 304, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!14 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 320, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 360, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 352, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!15 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 368, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 408, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 400, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!16 = distinct !DILocalVariable(scope: !17, file: !3, type: !24, flags: DIFlagArtificial)
|
||||||
|
!17 = distinct !DISubprogram(name: "sub1", scope: !2, file: !3, line: 1, type: !18, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2)
|
||||||
|
!18 = !DISubroutineType(types: !19)
|
||||||
|
!19 = !{null, !20, !25}
|
||||||
|
!20 = !DICompositeType(tag: DW_TAG_array_type, baseType: !7, size: 32, align: 32, elements: !21)
|
||||||
|
!21 = !{!22}
|
||||||
|
!22 = !DISubrange(lowerBound: 1, upperBound: !23)
|
||||||
|
!23 = distinct !DILocalVariable(scope: !17, file: !3, type: !24, flags: DIFlagArtificial)
|
||||||
|
!24 = !DIBasicType(name: "integer*8", size: 64, align: 64, encoding: DW_ATE_signed)
|
||||||
|
!25 = !DICompositeType(tag: DW_TAG_array_type, baseType: !24, size: 1024, align: 64, elements: !26)
|
||||||
|
!26 = !{!27}
|
||||||
|
!27 = !DISubrange(lowerBound: 1, upperBound: 16)
|
68
test/DebugInfo/X86/dwarfdump-rankConst.ll
Normal file
68
test/DebugInfo/X86/dwarfdump-rankConst.ll
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
;; This test checks whether DW_AT_rank attribute accepts DIExpression.
|
||||||
|
|
||||||
|
; RUN: llc %s -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_rank (7)
|
||||||
|
|
||||||
|
;; Test case is hand written with the help of below testcase
|
||||||
|
;;------------------------------
|
||||||
|
;;subroutine sub(arank)
|
||||||
|
;; real :: arank(..)
|
||||||
|
;; print *, RANK(arank)
|
||||||
|
;;end
|
||||||
|
;;------------------------------
|
||||||
|
|
||||||
|
; ModuleID = 'dwarfdump-rank.ll'
|
||||||
|
source_filename = "dwarfdump-rank.ll"
|
||||||
|
|
||||||
|
define void @sub_(i64* noalias %arank, i64* noalias %"arank$sd") !dbg !5 {
|
||||||
|
L.entry:
|
||||||
|
call void @llvm.dbg.value(metadata i64* %arank, metadata !17, metadata !DIExpression()), !dbg !18
|
||||||
|
call void @llvm.dbg.declare(metadata i64* %"arank$sd", metadata !19, metadata !DIExpression()), !dbg !18
|
||||||
|
call void @llvm.dbg.declare(metadata i64* %"arank$sd", metadata !29, metadata !DIExpression()), !dbg !18
|
||||||
|
ret void, !dbg !18
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nounwind readnone speculatable willreturn
|
||||||
|
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||||
|
|
||||||
|
; Function Attrs: nounwind readnone speculatable willreturn
|
||||||
|
declare void @llvm.dbg.value(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: "rank.f90", directory: "/dir")
|
||||||
|
!4 = !{}
|
||||||
|
!5 = distinct !DISubprogram(name: "sub", scope: !2, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2)
|
||||||
|
!6 = !DISubroutineType(types: !7)
|
||||||
|
!7 = !{null, !8, !14}
|
||||||
|
!8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 32, align: 32, elements: !10)
|
||||||
|
!9 = !DIBasicType(name: "real", size: 32, align: 32, encoding: DW_ATE_float)
|
||||||
|
!10 = !{!11}
|
||||||
|
!11 = !DISubrange(lowerBound: 1, upperBound: !12)
|
||||||
|
!12 = distinct !DILocalVariable(scope: !5, file: !3, type: !13, flags: DIFlagArtificial)
|
||||||
|
!13 = !DIBasicType(name: "integer*8", size: 64, align: 64, encoding: DW_ATE_signed)
|
||||||
|
!14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !13, size: 1024, align: 64, elements: !15)
|
||||||
|
!15 = !{!16}
|
||||||
|
!16 = !DISubrange(lowerBound: 1, upperBound: 16)
|
||||||
|
!17 = distinct !DILocalVariable(scope: !5, file: !3, type: !13, flags: DIFlagArtificial)
|
||||||
|
!18 = !DILocation(line: 0, scope: !5)
|
||||||
|
!19 = !DILocalVariable(name: "arank", arg: 1, scope: !5, file: !3, line: 1, type: !20)
|
||||||
|
!20 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 32, align: 32, elements: !21, dataLocation: !17, rank: 7)
|
||||||
|
!21 = !{!22, !23, !24, !25, !26, !27, !28}
|
||||||
|
!22 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 80, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 120, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 112, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!23 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 128, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 168, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 160, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!24 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 176, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 216, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 208, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!25 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 224, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 264, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 256, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!26 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 272, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 312, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 304, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!27 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 320, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 360, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 352, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!28 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 368, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 408, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 400, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!29 = !DILocalVariable(arg: 2, scope: !5, file: !3, line: 1, type: !14, flags: DIFlagArtificial)
|
68
test/DebugInfo/X86/dwarfdump-rankExp.ll
Normal file
68
test/DebugInfo/X86/dwarfdump-rankExp.ll
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
;; This test checks whether DW_AT_rank attribute accepts DIExpression.
|
||||||
|
|
||||||
|
; RUN: llc %s -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_rank (DW_OP_push_object_address, DW_OP_plus_uconst 0x8, DW_OP_deref)
|
||||||
|
|
||||||
|
;; Test case is hand written with the help of below testcase
|
||||||
|
;;------------------------------
|
||||||
|
;;subroutine sub(arank)
|
||||||
|
;; real :: arank(..)
|
||||||
|
;; print *, RANK(arank)
|
||||||
|
;;end
|
||||||
|
;;------------------------------
|
||||||
|
|
||||||
|
; ModuleID = 'dwarfdump-rank.ll'
|
||||||
|
source_filename = "dwarfdump-rank.ll"
|
||||||
|
|
||||||
|
define void @sub_(i64* noalias %arank, i64* noalias %"arank$sd") !dbg !5 {
|
||||||
|
L.entry:
|
||||||
|
call void @llvm.dbg.value(metadata i64* %arank, metadata !17, metadata !DIExpression()), !dbg !18
|
||||||
|
call void @llvm.dbg.declare(metadata i64* %"arank$sd", metadata !19, metadata !DIExpression()), !dbg !18
|
||||||
|
call void @llvm.dbg.declare(metadata i64* %"arank$sd", metadata !29, metadata !DIExpression()), !dbg !18
|
||||||
|
ret void, !dbg !18
|
||||||
|
}
|
||||||
|
|
||||||
|
; Function Attrs: nounwind readnone speculatable willreturn
|
||||||
|
declare void @llvm.dbg.declare(metadata, metadata, metadata)
|
||||||
|
|
||||||
|
; Function Attrs: nounwind readnone speculatable willreturn
|
||||||
|
declare void @llvm.dbg.value(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: "rank.f90", directory: "/dir")
|
||||||
|
!4 = !{}
|
||||||
|
!5 = distinct !DISubprogram(name: "sub", scope: !2, file: !3, line: 1, type: !6, scopeLine: 1, spFlags: DISPFlagDefinition, unit: !2)
|
||||||
|
!6 = !DISubroutineType(types: !7)
|
||||||
|
!7 = !{null, !8, !14}
|
||||||
|
!8 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 32, align: 32, elements: !10)
|
||||||
|
!9 = !DIBasicType(name: "real", size: 32, align: 32, encoding: DW_ATE_float)
|
||||||
|
!10 = !{!11}
|
||||||
|
!11 = !DISubrange(lowerBound: 1, upperBound: !12)
|
||||||
|
!12 = distinct !DILocalVariable(scope: !5, file: !3, type: !13, flags: DIFlagArtificial)
|
||||||
|
!13 = !DIBasicType(name: "integer*8", size: 64, align: 64, encoding: DW_ATE_signed)
|
||||||
|
!14 = !DICompositeType(tag: DW_TAG_array_type, baseType: !13, size: 1024, align: 64, elements: !15)
|
||||||
|
!15 = !{!16}
|
||||||
|
!16 = !DISubrange(lowerBound: 1, upperBound: 16)
|
||||||
|
!17 = distinct !DILocalVariable(scope: !5, file: !3, type: !13, flags: DIFlagArtificial)
|
||||||
|
!18 = !DILocation(line: 0, scope: !5)
|
||||||
|
!19 = !DILocalVariable(name: "arank", arg: 1, scope: !5, file: !3, line: 1, type: !20)
|
||||||
|
!20 = !DICompositeType(tag: DW_TAG_array_type, baseType: !9, size: 32, align: 32, elements: !21, dataLocation: !17, rank: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8, DW_OP_deref))
|
||||||
|
!21 = !{!22, !23, !24, !25, !26, !27, !28}
|
||||||
|
!22 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 80, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 120, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 112, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!23 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 128, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 168, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 160, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!24 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 176, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 216, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 208, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!25 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 224, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 264, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 256, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!26 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 272, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 312, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 304, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!27 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 320, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 360, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 352, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!28 = !DISubrange(lowerBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 368, DW_OP_deref), upperBound: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 408, DW_OP_deref), stride: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 400, DW_OP_deref, DW_OP_constu, 4, DW_OP_mul))
|
||||||
|
!29 = !DILocalVariable(arg: 2, scope: !5, file: !3, line: 1, type: !14, flags: DIFlagArtificial)
|
6
test/Verifier/array_rank.ll
Normal file
6
test/Verifier/array_rank.ll
Normal file
@ -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, rank: !DIExpression(DW_OP_push_object_address, DW_OP_plus_uconst, 8, DW_OP_deref))
|
||||||
|
|
||||||
|
; CHECK: rank can only appear in array type
|
@ -30,7 +30,7 @@ TEST(DebugTypeODRUniquingTest, getODRType) {
|
|||||||
EXPECT_FALSE(DICompositeType::getODRType(
|
EXPECT_FALSE(DICompositeType::getODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||||
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr,
|
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr,
|
||||||
nullptr, nullptr, nullptr));
|
nullptr, nullptr, nullptr, nullptr));
|
||||||
|
|
||||||
// Enable the mapping. There still shouldn't be a type.
|
// Enable the mapping. There still shouldn't be a type.
|
||||||
Context.enableDebugTypeODRUniquing();
|
Context.enableDebugTypeODRUniquing();
|
||||||
@ -40,20 +40,21 @@ TEST(DebugTypeODRUniquingTest, getODRType) {
|
|||||||
auto &CT = *DICompositeType::getODRType(
|
auto &CT = *DICompositeType::getODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||||
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr,
|
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr, nullptr, nullptr,
|
||||||
nullptr, nullptr, nullptr);
|
nullptr, nullptr, nullptr, nullptr);
|
||||||
EXPECT_EQ(UUID.getString(), CT.getIdentifier());
|
EXPECT_EQ(UUID.getString(), CT.getIdentifier());
|
||||||
|
|
||||||
// Check that we get it back, even if we change a field.
|
// Check that we get it back, even if we change a field.
|
||||||
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
|
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||||
EXPECT_EQ(&CT, DICompositeType::getODRType(
|
EXPECT_EQ(&CT,
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
DICompositeType::getODRType(
|
||||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
|
||||||
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
EXPECT_EQ(&CT, DICompositeType::getODRType(
|
EXPECT_EQ(&CT, DICompositeType::getODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type,
|
Context, UUID, dwarf::DW_TAG_class_type,
|
||||||
MDString::get(Context, "name"), nullptr, 0, nullptr,
|
MDString::get(Context, "name"), nullptr, 0, nullptr,
|
||||||
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr,
|
nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0, nullptr,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr));
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
|
|
||||||
// Check that it's discarded with the type map.
|
// Check that it's discarded with the type map.
|
||||||
Context.disableDebugTypeODRUniquing();
|
Context.disableDebugTypeODRUniquing();
|
||||||
@ -73,7 +74,7 @@ TEST(DebugTypeODRUniquingTest, buildODRType) {
|
|||||||
auto &CT = *DICompositeType::buildODRType(
|
auto &CT = *DICompositeType::buildODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0, nullptr,
|
||||||
nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr,
|
nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0, nullptr, nullptr,
|
||||||
nullptr, nullptr, nullptr, nullptr);
|
nullptr, nullptr, nullptr, nullptr, nullptr);
|
||||||
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
|
EXPECT_EQ(&CT, DICompositeType::getODRTypeIfExists(Context, UUID));
|
||||||
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
|
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
|
||||||
|
|
||||||
@ -82,7 +83,7 @@ TEST(DebugTypeODRUniquingTest, buildODRType) {
|
|||||||
DICompositeType::buildODRType(
|
DICompositeType::buildODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr,
|
Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr,
|
||||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0,
|
0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
|
EXPECT_EQ(dwarf::DW_TAG_class_type, CT.getTag());
|
||||||
|
|
||||||
// Update with a definition. This time we should see a change.
|
// Update with a definition. This time we should see a change.
|
||||||
@ -90,19 +91,21 @@ TEST(DebugTypeODRUniquingTest, buildODRType) {
|
|||||||
DICompositeType::buildODRType(
|
DICompositeType::buildODRType(
|
||||||
Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr,
|
Context, UUID, dwarf::DW_TAG_structure_type, nullptr, nullptr,
|
||||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
|
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
|
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
|
||||||
|
|
||||||
// Further updates should be ignored.
|
// Further updates should be ignored.
|
||||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
EXPECT_EQ(&CT,
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
DICompositeType::buildODRType(
|
||||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0,
|
||||||
0, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
nullptr, nullptr, 0, 0, 0, DINode::FlagFwdDecl, nullptr, 0,
|
||||||
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
|
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
|
||||||
EXPECT_EQ(&CT, DICompositeType::buildODRType(
|
EXPECT_EQ(&CT,
|
||||||
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr,
|
DICompositeType::buildODRType(
|
||||||
0, nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
|
Context, UUID, dwarf::DW_TAG_class_type, nullptr, nullptr, 0,
|
||||||
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
nullptr, nullptr, 0, 0, 0, DINode::FlagZero, nullptr, 0,
|
||||||
|
nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr));
|
||||||
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
|
EXPECT_EQ(dwarf::DW_TAG_structure_type, CT.getTag());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -115,7 +118,7 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {
|
|||||||
auto &CT = *DICompositeType::buildODRType(
|
auto &CT = *DICompositeType::buildODRType(
|
||||||
Context, UUID, 0, nullptr, nullptr, 0, nullptr, nullptr, 0, 0, 0,
|
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);
|
nullptr, nullptr, nullptr);
|
||||||
|
|
||||||
// Create macros for running through all the fields except Identifier and Flags.
|
// Create macros for running through all the fields except Identifier and Flags.
|
||||||
#define FOR_EACH_MDFIELD() \
|
#define FOR_EACH_MDFIELD() \
|
||||||
@ -149,7 +152,7 @@ TEST(DebugTypeODRUniquingTest, buildODRTypeFields) {
|
|||||||
Context, UUID, Tag, Name, File, Line, Scope, BaseType,
|
Context, UUID, Tag, Name, File, Line, Scope, BaseType,
|
||||||
SizeInBits, AlignInBits, OffsetInBits, DINode::FlagArtificial,
|
SizeInBits, AlignInBits, OffsetInBits, DINode::FlagArtificial,
|
||||||
Elements, RuntimeLang, VTableHolder, TemplateParams, nullptr,
|
Elements, RuntimeLang, VTableHolder, TemplateParams, nullptr,
|
||||||
nullptr, nullptr, nullptr));
|
nullptr, nullptr, nullptr, nullptr));
|
||||||
|
|
||||||
// Confirm that all the right fields got updated.
|
// Confirm that all the right fields got updated.
|
||||||
#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X());
|
#define DO_FOR_FIELD(X) EXPECT_EQ(X, CT.getRaw##X());
|
||||||
|
@ -1780,6 +1780,16 @@ TEST_F(DICompositeTypeTest, dynamicArray) {
|
|||||||
uint64_t Elements2[] = {dwarf::DW_OP_constu, 0};
|
uint64_t Elements2[] = {dwarf::DW_OP_constu, 0};
|
||||||
Metadata *DataLocation2 = DIExpression::get(Context, Elements2);
|
Metadata *DataLocation2 = DIExpression::get(Context, Elements2);
|
||||||
|
|
||||||
|
uint64_t Elements3[] = {dwarf::DW_OP_constu, 3};
|
||||||
|
Metadata *Rank1 = DIExpression::get(Context, Elements3);
|
||||||
|
|
||||||
|
uint64_t Elements4[] = {dwarf::DW_OP_constu, 4};
|
||||||
|
Metadata *Rank2 = DIExpression::get(Context, Elements4);
|
||||||
|
|
||||||
|
ConstantInt *RankInt1 = ConstantInt::get(Context, APInt(7, 0));
|
||||||
|
ConstantAsMetadata *RankConst1 = ConstantAsMetadata::get(RankInt1);
|
||||||
|
ConstantInt *RankInt2 = ConstantInt::get(Context, APInt(6, 0));
|
||||||
|
ConstantAsMetadata *RankConst2 = ConstantAsMetadata::get(RankInt2);
|
||||||
auto *N1 = DICompositeType::get(
|
auto *N1 = DICompositeType::get(
|
||||||
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
|
OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
|
||||||
@ -1817,6 +1827,44 @@ TEST_F(DICompositeTypeTest, dynamicArray) {
|
|||||||
EXPECT_EQ(N2, Same2);
|
EXPECT_EQ(N2, Same2);
|
||||||
EXPECT_NE(Same2, Other2);
|
EXPECT_NE(Same2, Other2);
|
||||||
EXPECT_EQ(N2->getDataLocationExp(), DataLocation1);
|
EXPECT_EQ(N2->getDataLocationExp(), DataLocation1);
|
||||||
|
|
||||||
|
auto *N3 = DICompositeType::get(
|
||||||
|
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
|
OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
|
||||||
|
nullptr, DataLocation1, nullptr, nullptr, Rank1);
|
||||||
|
|
||||||
|
auto *Same3 = DICompositeType::get(
|
||||||
|
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
|
OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
|
||||||
|
nullptr, DataLocation1, nullptr, nullptr, Rank1);
|
||||||
|
|
||||||
|
auto *Other3 = DICompositeType::get(
|
||||||
|
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
|
OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
|
||||||
|
nullptr, DataLocation1, nullptr, nullptr, Rank2);
|
||||||
|
|
||||||
|
EXPECT_EQ(N3, Same3);
|
||||||
|
EXPECT_NE(Same3, Other3);
|
||||||
|
EXPECT_EQ(N3->getRankExp(), Rank1);
|
||||||
|
|
||||||
|
auto *N4 = DICompositeType::get(
|
||||||
|
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
|
OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
|
||||||
|
nullptr, DataLocation1, nullptr, nullptr, RankConst1);
|
||||||
|
|
||||||
|
auto *Same4 = DICompositeType::get(
|
||||||
|
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
|
OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
|
||||||
|
nullptr, DataLocation1, nullptr, nullptr, RankConst1);
|
||||||
|
|
||||||
|
auto *Other4 = DICompositeType::get(
|
||||||
|
Context, Tag, Name, File, Line, Scope, BaseType, SizeInBits, AlignInBits,
|
||||||
|
OffsetInBits, Flags, nullptr, RuntimeLang, nullptr, nullptr, Identifier,
|
||||||
|
nullptr, DataLocation1, nullptr, nullptr, RankConst2);
|
||||||
|
|
||||||
|
EXPECT_EQ(N4, Same4);
|
||||||
|
EXPECT_NE(Same4, Other4);
|
||||||
|
EXPECT_EQ(N4->getRankConst(), RankInt1);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef MetadataTest DISubroutineTypeTest;
|
typedef MetadataTest DISubroutineTypeTest;
|
||||||
|
Loading…
Reference in New Issue
Block a user