[DebugInfo] Enhance DIImportedEntity to accept children entities

New field `elements` is added to '!DIImportedEntity', representing
list of aliased entities.
This is needed to dump optimized debugging information where all names
in a module are imported, but a few names are imported with overriding
aliases.

Reviewed By: dblaikie

Differential Revision: https://reviews.llvm.org/D109343
This commit is contained in:
Alok Kumar Sharma 2021-09-07 11:25:44 +05:30
parent a01f772d19
commit a5b72abc9e
20 changed files with 473 additions and 122 deletions

View File

@ -5790,12 +5790,16 @@ DIImportedEntity
""""""""""""""""
``DIImportedEntity`` nodes represent entities (such as modules) imported into a
compile unit.
compile unit. The ``elements`` field is a list of renamed entities (such as
variables and subprograms) in the imported entity (such as module).
.. code-block:: text
!2 = !DIImportedEntity(tag: DW_TAG_imported_module, name: "foo", scope: !0,
entity: !1, line: 7)
entity: !1, line: 7, elements: !3)
!3 = !{!4}
!4 = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "bar", scope: !0,
entity: !5, line: 7)
DIMacro
"""""""

View File

@ -389,48 +389,48 @@ LLVMDIBuilderCreateImportedModuleFromNamespace(LLVMDIBuilderRef Builder,
* \param ImportedEntity Previous imported entity to alias.
* \param File File where the declaration is located.
* \param Line Line number of the declaration.
* \param Elements Renamed elements.
* \param NumElements Number of renamed elements.
*/
LLVMMetadataRef
LLVMDIBuilderCreateImportedModuleFromAlias(LLVMDIBuilderRef Builder,
LLVMMetadataRef Scope,
LLVMMetadataRef ImportedEntity,
LLVMMetadataRef File,
unsigned Line);
LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromAlias(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope,
LLVMMetadataRef ImportedEntity, LLVMMetadataRef File, unsigned Line,
LLVMMetadataRef *Elements, unsigned NumElements);
/**
* Create a descriptor for an imported module.
* \param Builder The \c DIBuilder.
* \param Scope The scope this module is imported into
* \param M The module being imported here
* \param File File where the declaration is located.
* \param Line Line number of the declaration.
* \param Builder The \c DIBuilder.
* \param Scope The scope this module is imported into
* \param M The module being imported here
* \param File File where the declaration is located.
* \param Line Line number of the declaration.
* \param Elements Renamed elements.
* \param NumElements Number of renamed elements.
*/
LLVMMetadataRef
LLVMDIBuilderCreateImportedModuleFromModule(LLVMDIBuilderRef Builder,
LLVMMetadataRef Scope,
LLVMMetadataRef M,
LLVMMetadataRef File,
unsigned Line);
LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromModule(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef M,
LLVMMetadataRef File, unsigned Line, LLVMMetadataRef *Elements,
unsigned NumElements);
/**
* Create a descriptor for an imported function, type, or variable. Suitable
* for e.g. FORTRAN-style USE declarations.
* \param Builder The DIBuilder.
* \param Scope The scope this module is imported into.
* \param Decl The declaration (or definition) of a function, type,
or variable.
* \param File File where the declaration is located.
* \param Line Line number of the declaration.
* \param Name A name that uniquely identifies this imported declaration.
* \param NameLen The length of the C string passed to \c Name.
* \param Builder The DIBuilder.
* \param Scope The scope this module is imported into.
* \param Decl The declaration (or definition) of a function, type,
or variable.
* \param File File where the declaration is located.
* \param Line Line number of the declaration.
* \param Name A name that uniquely identifies this imported
declaration.
* \param NameLen The length of the C string passed to \c Name.
* \param Elements Renamed elements.
* \param NumElements Number of renamed elements.
*/
LLVMMetadataRef
LLVMDIBuilderCreateImportedDeclaration(LLVMDIBuilderRef Builder,
LLVMMetadataRef Scope,
LLVMMetadataRef Decl,
LLVMMetadataRef File,
unsigned Line,
const char *Name, size_t NameLen);
LLVMMetadataRef LLVMDIBuilderCreateImportedDeclaration(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef Decl,
LLVMMetadataRef File, unsigned Line, const char *Name, size_t NameLen,
LLVMMetadataRef *Elements, unsigned NumElements);
/**
* Creates a new DebugLocation that describes a source location.

View File

@ -827,29 +827,35 @@ namespace llvm {
unsigned Line, unsigned Col);
/// Create a descriptor for an imported module.
/// \param Context The scope this module is imported into
/// \param NS The namespace being imported here.
/// \param File File where the declaration is located.
/// \param Line Line number of the declaration.
/// \param Context The scope this module is imported into
/// \param NS The namespace being imported here.
/// \param File File where the declaration is located.
/// \param Line Line number of the declaration.
/// \param Elements Renamed elements.
DIImportedEntity *createImportedModule(DIScope *Context, DINamespace *NS,
DIFile *File, unsigned Line);
DIFile *File, unsigned Line,
DINodeArray Elements = nullptr);
/// Create a descriptor for an imported module.
/// \param Context The scope this module is imported into.
/// \param NS An aliased namespace.
/// \param File File where the declaration is located.
/// \param Line Line number of the declaration.
/// \param Elements Renamed elements.
DIImportedEntity *createImportedModule(DIScope *Context,
DIImportedEntity *NS, DIFile *File,
unsigned Line);
unsigned Line,
DINodeArray Elements = nullptr);
/// Create a descriptor for an imported module.
/// \param Context The scope this module is imported into.
/// \param M The module being imported here
/// \param File File where the declaration is located.
/// \param Line Line number of the declaration.
/// \param Context The scope this module is imported into.
/// \param M The module being imported here
/// \param File File where the declaration is located.
/// \param Line Line number of the declaration.
/// \param Elements Renamed elements.
DIImportedEntity *createImportedModule(DIScope *Context, DIModule *M,
DIFile *File, unsigned Line);
DIFile *File, unsigned Line,
DINodeArray Elements = nullptr);
/// Create a descriptor for an imported function.
/// \param Context The scope this module is imported into.
@ -857,9 +863,11 @@ namespace llvm {
/// variable.
/// \param File File where the declaration is located.
/// \param Line Line number of the declaration.
/// \param Elements Renamed elements.
DIImportedEntity *createImportedDeclaration(DIScope *Context, DINode *Decl,
DIFile *File, unsigned Line,
StringRef Name = "");
StringRef Name = "",
DINodeArray Elements = nullptr);
/// Insert a new llvm.dbg.declare intrinsic call.
/// \param Storage llvm::Value of the variable

View File

@ -3347,31 +3347,33 @@ class DIImportedEntity : public DINode {
static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
DIScope *Scope, DINode *Entity, DIFile *File,
unsigned Line, StringRef Name,
StorageType Storage,
DINodeArray Elements, StorageType Storage,
bool ShouldCreate = true) {
return getImpl(Context, Tag, Scope, Entity, File, Line,
getCanonicalMDString(Context, Name), Storage, ShouldCreate);
getCanonicalMDString(Context, Name), Elements.get(), Storage,
ShouldCreate);
}
static DIImportedEntity *getImpl(LLVMContext &Context, unsigned Tag,
Metadata *Scope, Metadata *Entity,
Metadata *File, unsigned Line,
MDString *Name, StorageType Storage,
bool ShouldCreate = true);
static DIImportedEntity *
getImpl(LLVMContext &Context, unsigned Tag, Metadata *Scope, Metadata *Entity,
Metadata *File, unsigned Line, MDString *Name, Metadata *Elements,
StorageType Storage, bool ShouldCreate = true);
TempDIImportedEntity cloneImpl() const {
return getTemporary(getContext(), getTag(), getScope(), getEntity(),
getFile(), getLine(), getName());
getFile(), getLine(), getName(), getElements());
}
public:
DEFINE_MDNODE_GET(DIImportedEntity,
(unsigned Tag, DIScope *Scope, DINode *Entity, DIFile *File,
unsigned Line, StringRef Name = ""),
(Tag, Scope, Entity, File, Line, Name))
unsigned Line, StringRef Name = "",
DINodeArray Elements = nullptr),
(Tag, Scope, Entity, File, Line, Name, Elements))
DEFINE_MDNODE_GET(DIImportedEntity,
(unsigned Tag, Metadata *Scope, Metadata *Entity,
Metadata *File, unsigned Line, MDString *Name),
(Tag, Scope, Entity, File, Line, Name))
Metadata *File, unsigned Line, MDString *Name,
Metadata *Elements = nullptr),
(Tag, Scope, Entity, File, Line, Name, Elements))
TempDIImportedEntity clone() const { return cloneImpl(); }
@ -3380,11 +3382,15 @@ public:
DINode *getEntity() const { return cast_or_null<DINode>(getRawEntity()); }
StringRef getName() const { return getStringOperand(2); }
DIFile *getFile() const { return cast_or_null<DIFile>(getRawFile()); }
DINodeArray getElements() const {
return cast_or_null<MDTuple>(getRawElements());
}
Metadata *getRawScope() const { return getOperand(0); }
Metadata *getRawEntity() const { return getOperand(1); }
MDString *getRawName() const { return getOperandAs<MDString>(2); }
Metadata *getRawFile() const { return getOperand(3); }
Metadata *getRawElements() const { return getOperand(4); }
static bool classof(const Metadata *MD) {
return MD->getMetadataID() == DIImportedEntityKind;

View File

@ -5114,7 +5114,7 @@ bool LLParser::parseDIObjCProperty(MDNode *&Result, bool IsDistinct) {
/// parseDIImportedEntity:
/// ::= !DIImportedEntity(tag: DW_TAG_imported_module, scope: !0, entity: !1,
/// line: 7, name: "foo")
/// line: 7, name: "foo", elements: !2)
bool LLParser::parseDIImportedEntity(MDNode *&Result, bool IsDistinct) {
#define VISIT_MD_FIELDS(OPTIONAL, REQUIRED) \
REQUIRED(tag, DwarfTagField, ); \
@ -5122,13 +5122,14 @@ bool LLParser::parseDIImportedEntity(MDNode *&Result, bool IsDistinct) {
OPTIONAL(entity, MDField, ); \
OPTIONAL(file, MDField, ); \
OPTIONAL(line, LineField, ); \
OPTIONAL(name, MDStringField, );
OPTIONAL(name, MDStringField, ); \
OPTIONAL(elements, MDField, );
PARSE_MD_FIELDS();
#undef VISIT_MD_FIELDS
Result = GET_OR_DISTINCT(
DIImportedEntity,
(Context, tag.Val, scope.Val, entity.Val, file.Val, line.Val, name.Val));
Result = GET_OR_DISTINCT(DIImportedEntity,
(Context, tag.Val, scope.Val, entity.Val, file.Val,
line.Val, name.Val, elements.Val));
return false;
}

View File

@ -2044,17 +2044,19 @@ Error MetadataLoader::MetadataLoaderImpl::parseOneMetadata(
break;
}
case bitc::METADATA_IMPORTED_ENTITY: {
if (Record.size() != 6 && Record.size() != 7)
if (Record.size() < 6 && Record.size() > 8)
return error("Invalid record");
IsDistinct = Record[0];
bool HasFile = (Record.size() == 7);
bool HasFile = (Record.size() >= 7);
bool HasElements = (Record.size() >= 8);
MetadataList.assignValue(
GET_OR_DISTINCT(DIImportedEntity,
(Context, Record[1], getMDOrNull(Record[2]),
getDITypeRefOrNull(Record[3]),
HasFile ? getMDOrNull(Record[6]) : nullptr,
HasFile ? Record[4] : 0, getMDString(Record[5]))),
HasFile ? Record[4] : 0, getMDString(Record[5]),
HasElements ? getMDOrNull(Record[7]) : nullptr)),
NextMetadataNo);
NextMetadataNo++;
break;

View File

@ -2062,6 +2062,7 @@ void ModuleBitcodeWriter::writeDIImportedEntity(
Record.push_back(N->getLine());
Record.push_back(VE.getMetadataOrNullID(N->getRawName()));
Record.push_back(VE.getMetadataOrNullID(N->getRawFile()));
Record.push_back(VE.getMetadataOrNullID(N->getElements().get()));
Stream.EmitRecord(bitc::METADATA_IMPORTED_ENTITY, Record, Abbrev);
Record.clear();

View File

@ -1269,6 +1269,16 @@ DIE *DwarfCompileUnit::constructImportedEntityDIE(
if (!Name.empty())
addString(*IMDie, dwarf::DW_AT_name, Name);
// This is for imported module with renamed entities (such as variables and
// subprograms).
DINodeArray Elements = Module->getElements();
for (const auto *Element : Elements) {
if (!Element)
continue;
IMDie->addChild(
constructImportedEntityDIE(cast<DIImportedEntity>(Element)));
}
return IMDie;
}

View File

@ -2411,6 +2411,7 @@ static void writeDIImportedEntity(raw_ostream &Out, const DIImportedEntity *N,
Printer.printMetadata("entity", N->getRawEntity());
Printer.printMetadata("file", N->getRawFile());
Printer.printInt("line", N->getLine());
Printer.printMetadata("elements", N->getRawElements());
Out << ")";
}

View File

@ -165,12 +165,13 @@ DICompileUnit *DIBuilder::createCompileUnit(
static DIImportedEntity *
createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context,
Metadata *NS, DIFile *File, unsigned Line, StringRef Name,
DINodeArray Elements,
SmallVectorImpl<TrackingMDNodeRef> &AllImportedModules) {
if (Line)
assert(File && "Source location has line number but no file");
unsigned EntitiesCount = C.pImpl->DIImportedEntitys.size();
auto *M = DIImportedEntity::get(C, Tag, Context, cast_or_null<DINode>(NS),
File, Line, Name);
File, Line, Name, Elements);
if (EntitiesCount < C.pImpl->DIImportedEntitys.size())
// A new Imported Entity was just added to the context.
// Add it to the Imported Modules list.
@ -180,36 +181,38 @@ createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context,
DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context,
DINamespace *NS, DIFile *File,
unsigned Line) {
unsigned Line,
DINodeArray Elements) {
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,
Context, NS, File, Line, StringRef(),
Context, NS, File, Line, StringRef(), Elements,
AllImportedModules);
}
DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context,
DIImportedEntity *NS,
DIFile *File, unsigned Line) {
DIFile *File, unsigned Line,
DINodeArray Elements) {
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,
Context, NS, File, Line, StringRef(),
Context, NS, File, Line, StringRef(), Elements,
AllImportedModules);
}
DIImportedEntity *DIBuilder::createImportedModule(DIScope *Context, DIModule *M,
DIFile *File, unsigned Line) {
DIFile *File, unsigned Line,
DINodeArray Elements) {
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_module,
Context, M, File, Line, StringRef(),
Context, M, File, Line, StringRef(), Elements,
AllImportedModules);
}
DIImportedEntity *DIBuilder::createImportedDeclaration(DIScope *Context,
DINode *Decl,
DIFile *File,
unsigned Line,
StringRef Name) {
DIImportedEntity *
DIBuilder::createImportedDeclaration(DIScope *Context, DINode *Decl,
DIFile *File, unsigned Line,
StringRef Name, DINodeArray Elements) {
// Make sure to use the unique identifier based metadata reference for
// types that have one.
return ::createImportedModule(VMContext, dwarf::DW_TAG_imported_declaration,
Context, Decl, File, Line, Name,
Context, Decl, File, Line, Name, Elements,
AllImportedModules);
}

View File

@ -1003,41 +1003,43 @@ LLVMDIBuilderCreateImportedModuleFromNamespace(LLVMDIBuilderRef Builder,
Line));
}
LLVMMetadataRef
LLVMDIBuilderCreateImportedModuleFromAlias(LLVMDIBuilderRef Builder,
LLVMMetadataRef Scope,
LLVMMetadataRef ImportedEntity,
LLVMMetadataRef File,
unsigned Line) {
LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromAlias(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope,
LLVMMetadataRef ImportedEntity, LLVMMetadataRef File, unsigned Line,
LLVMMetadataRef *Elements, unsigned NumElements) {
auto Elts =
(NumElements > 0)
? unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements})
: nullptr;
return wrap(unwrap(Builder)->createImportedModule(
unwrapDI<DIScope>(Scope),
unwrapDI<DIImportedEntity>(ImportedEntity),
unwrapDI<DIFile>(File), Line));
unwrapDI<DIScope>(Scope), unwrapDI<DIImportedEntity>(ImportedEntity),
unwrapDI<DIFile>(File), Line, Elts));
}
LLVMMetadataRef
LLVMDIBuilderCreateImportedModuleFromModule(LLVMDIBuilderRef Builder,
LLVMMetadataRef Scope,
LLVMMetadataRef M,
LLVMMetadataRef File,
unsigned Line) {
return wrap(unwrap(Builder)->createImportedModule(unwrapDI<DIScope>(Scope),
unwrapDI<DIModule>(M),
unwrapDI<DIFile>(File),
Line));
LLVMMetadataRef LLVMDIBuilderCreateImportedModuleFromModule(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef M,
LLVMMetadataRef File, unsigned Line, LLVMMetadataRef *Elements,
unsigned NumElements) {
auto Elts =
(NumElements > 0)
? unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements})
: nullptr;
return wrap(unwrap(Builder)->createImportedModule(
unwrapDI<DIScope>(Scope), unwrapDI<DIModule>(M), unwrapDI<DIFile>(File),
Line, Elts));
}
LLVMMetadataRef
LLVMDIBuilderCreateImportedDeclaration(LLVMDIBuilderRef Builder,
LLVMMetadataRef Scope,
LLVMMetadataRef Decl,
LLVMMetadataRef File,
unsigned Line,
const char *Name, size_t NameLen) {
LLVMMetadataRef LLVMDIBuilderCreateImportedDeclaration(
LLVMDIBuilderRef Builder, LLVMMetadataRef Scope, LLVMMetadataRef Decl,
LLVMMetadataRef File, unsigned Line, const char *Name, size_t NameLen,
LLVMMetadataRef *Elements, unsigned NumElements) {
auto Elts =
(NumElements > 0)
? unwrap(Builder)->getOrCreateArray({unwrap(Elements), NumElements})
: nullptr;
return wrap(unwrap(Builder)->createImportedDeclaration(
unwrapDI<DIScope>(Scope),
unwrapDI<DINode>(Decl),
unwrapDI<DIFile>(File), Line, {Name, NameLen}));
unwrapDI<DIScope>(Scope), unwrapDI<DINode>(Decl), unwrapDI<DIFile>(File),
Line, {Name, NameLen}, Elts));
}
LLVMMetadataRef

View File

@ -1602,12 +1602,13 @@ DIObjCProperty *DIObjCProperty::getImpl(
DIImportedEntity *DIImportedEntity::getImpl(LLVMContext &Context, unsigned Tag,
Metadata *Scope, Metadata *Entity,
Metadata *File, unsigned Line,
MDString *Name, StorageType Storage,
MDString *Name, Metadata *Elements,
StorageType Storage,
bool ShouldCreate) {
assert(isCanonical(Name) && "Expected canonical MDString");
DEFINE_GETIMPL_LOOKUP(DIImportedEntity,
(Tag, Scope, Entity, File, Line, Name));
Metadata *Ops[] = {Scope, Entity, Name, File};
(Tag, Scope, Entity, File, Line, Name, Elements));
Metadata *Ops[] = {Scope, Entity, Name, File, Elements};
DEFINE_GETIMPL_STORE(DIImportedEntity, (Tag, Line), Ops);
}

View File

@ -1169,23 +1169,26 @@ template <> struct MDNodeKeyImpl<DIImportedEntity> {
Metadata *File;
unsigned Line;
MDString *Name;
Metadata *Elements;
MDNodeKeyImpl(unsigned Tag, Metadata *Scope, Metadata *Entity, Metadata *File,
unsigned Line, MDString *Name)
unsigned Line, MDString *Name, Metadata *Elements)
: Tag(Tag), Scope(Scope), Entity(Entity), File(File), Line(Line),
Name(Name) {}
Name(Name), Elements(Elements) {}
MDNodeKeyImpl(const DIImportedEntity *N)
: Tag(N->getTag()), Scope(N->getRawScope()), Entity(N->getRawEntity()),
File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()) {}
File(N->getRawFile()), Line(N->getLine()), Name(N->getRawName()),
Elements(N->getRawElements()) {}
bool isKeyOf(const DIImportedEntity *RHS) const {
return Tag == RHS->getTag() && Scope == RHS->getRawScope() &&
Entity == RHS->getRawEntity() && File == RHS->getFile() &&
Line == RHS->getLine() && Name == RHS->getRawName();
Line == RHS->getLine() && Name == RHS->getRawName() &&
Elements == RHS->getRawElements();
}
unsigned getHashValue() const {
return hash_combine(Tag, Scope, Entity, File, Line, Name);
return hash_combine(Tag, Scope, Entity, File, Line, Name, Elements);
}
};

View File

@ -0,0 +1,81 @@
;; This test checks Backward compatibility of DIImportedEntity
; REQUIRES: x86_64-linux
; RUN: llvm-dis -o - %s.bc | FileCheck %s
;Test whether DIImportedEntity are generated correctly.
; CHECK: distinct !DICompileUnit(language: DW_LANG_Fortran90
; CHECK-SAME: imports: [[IMPORTS:![0-9]+]]
; CHECK: [[IMPORTS]] = !{[[IMPORT1:![0-9]+]], [[IMPORT2:![0-9]+]]}
; CHECK: [[IMPORT1]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: {{![0-9]+}}, entity: {{![0-9]+}}, file: {{![0-9]+}}, line: {{[0-9]+}})
; CHECK: [[IMPORT2]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "var4", scope: {{![0-9]+}}, entity: {{![0-9]+}}, file: {{![0-9]+}}, line: {{[0-9]+}})
; ModuleID = 'DIImportedEntity_backward.bc'
source_filename = "/tmp/usemodulealias.ll"
%struct_mymod_8_ = type <{ [12 x i8] }>
%struct.struct_ul_MAIN__348 = type { i8* }
@_mymod_8_ = global %struct_mymod_8_ <{ [12 x i8] c"\0B\00\00\00\0C\00\00\00\0D\00\00\00" }>, align 64, !dbg !0, !dbg !7, !dbg !10
@.C330_MAIN_ = internal constant i32 0
@.C364_main_use_renamed = internal constant i32 25
@.C330_main_use_renamed = internal constant i32 0
@.C331_main_use_renamed = internal constant i64 0
@.C359_main_use_renamed = internal constant i32 6
@.C357_main_use_renamed = internal constant [18 x i8] c"usemodulealias.f90"
@.C352_main_use_renamed = internal constant i32 12
define i32 @mymod_() {
.L.entry:
ret i32 undef
}
define void @MAIN_() !dbg !15 {
L.entry:
%.S0000_353 = alloca %struct.struct_ul_MAIN__348, align 8
%0 = bitcast i32* @.C330_MAIN_ to i8*
%1 = bitcast void (...)* @fort_init to void (i8*, ...)*
call void (i8*, ...) %1(i8* %0)
br label %L.LB2_357
L.LB2_357: ; preds = %L.entry
%2 = bitcast %struct.struct_ul_MAIN__348* %.S0000_353 to i64*, !dbg !22
call void @main_use_renamed(i64* %2), !dbg !22
ret void, !dbg !23
}
define internal void @main_use_renamed(i64* noalias %.S0000) !dbg !14 {
L.entry:
ret void, !dbg !24
}
declare void @fort_init(...)
!llvm.module.flags = !{!20, !21}
!llvm.dbg.cu = !{!4}
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "var1", scope: !2, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true)
!2 = !DIModule(scope: !4, name: "mymod", file: !3, line: 1)
!3 = !DIFile(filename: "DIImportedEntity_backward.f90", directory: "/tmp")
!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang usemodulealias.f90 -g -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !12, nameTableKind: None)
!5 = !{}
!6 = !{!0, !7, !10}
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression(DW_OP_plus_uconst, 4))
!8 = distinct !DIGlobalVariable(name: "var2", scope: !2, file: !3, line: 3, type: !9, isLocal: false, isDefinition: true)
!9 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed)
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression(DW_OP_plus_uconst, 8))
!11 = distinct !DIGlobalVariable(name: "var3", scope: !2, file: !3, line: 4, type: !9, isLocal: false, isDefinition: true)
!12 = !{!13, !19}
!13 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !14, entity: !2, file: !3, line: 10)
!14 = distinct !DISubprogram(name: "use_renamed", scope: !15, file: !3, line: 10, type: !18, scopeLine: 10, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !4)
!15 = distinct !DISubprogram(name: "main", scope: !4, file: !3, line: 7, type: !16, scopeLine: 7, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !4)
!16 = !DISubroutineType(cc: DW_CC_program, types: !17)
!17 = !{null}
!18 = !DISubroutineType(types: !17)
!19 = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "var4", scope: !14, entity: !1, file: !3, line: 10)
!20 = !{i32 2, !"Dwarf Version", i32 4}
!21 = !{i32 2, !"Debug Info Version", i32 3}
!22 = !DILocation(line: 8, column: 1, scope: !15)
!23 = !DILocation(line: 9, column: 1, scope: !15)
!24 = !DILocation(line: 13, column: 1, scope: !14)

Binary file not shown.

View File

@ -0,0 +1,98 @@
;; This test checks processing of DIImportedEntity with elements field.
; REQUIRES: x86_64-linux
; RUN: llvm-as < %s | llvm-dis | llvm-as | llvm-dis | FileCheck %s
; CHECK: !DIImportedEntity(tag: DW_TAG_imported_module
; CHECK-SAME: elements: [[ELEMENTS:![0-9]+]]
; CHECK: [[ELEMENTS]] = !{[[ELEMENT:![0-9]+]]}
; CHECK: [[ELEMENT]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "var4"
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;This test case is generated from
;;module mymod
;; integer :: var1 = 11
;; integer :: var2 = 12
;; integer :: var3 = 13
;;end module mymod
;;
;;Program main
;; call use_renamed()
;; contains
;; subroutine use_renamed()
;; use mymod, var4 => var1
;; print *, var4
;; end subroutine use_renamed
;;end program main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ModuleID = 'DIImportedEntity_elements.ll'
source_filename = "/tmp/usemodulealias.ll"
%struct_mymod_8_ = type <{ [12 x i8] }>
%struct.struct_ul_MAIN__348 = type { i8* }
@_mymod_8_ = global %struct_mymod_8_ <{ [12 x i8] c"\0B\00\00\00\0C\00\00\00\0D\00\00\00" }>, align 64, !dbg !0, !dbg !7, !dbg !10
@.C330_MAIN_ = internal constant i32 0
@.C364_main_use_renamed = internal constant i32 25
@.C330_main_use_renamed = internal constant i32 0
@.C331_main_use_renamed = internal constant i64 0
@.C359_main_use_renamed = internal constant i32 6
@.C357_main_use_renamed = internal constant [18 x i8] c"usemodulealias.f90"
@.C352_main_use_renamed = internal constant i32 12
define i32 @mymod_() {
.L.entry:
ret i32 undef
}
define void @MAIN_() !dbg !15 {
L.entry:
%.S0000_353 = alloca %struct.struct_ul_MAIN__348, align 8
%0 = bitcast i32* @.C330_MAIN_ to i8*
%1 = bitcast void (...)* @fort_init to void (i8*, ...)*
call void (i8*, ...) %1(i8* %0)
br label %L.LB2_357
L.LB2_357: ; preds = %L.entry
%2 = bitcast %struct.struct_ul_MAIN__348* %.S0000_353 to i64*, !dbg !23
call void @main_use_renamed(i64* %2), !dbg !23
ret void, !dbg !24
}
define internal void @main_use_renamed(i64* noalias %.S0000) !dbg !14 {
L.entry:
ret void, !dbg !25
}
declare void @fort_init(...)
!llvm.module.flags = !{!21, !22}
!llvm.dbg.cu = !{!4}
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "var1", scope: !2, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true)
!2 = !DIModule(scope: !4, name: "mymod", file: !3, line: 1)
!3 = !DIFile(filename: "DIImportedEntity_elements.f90", directory: "/tmp")
!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang usemodulealias.f90 -g -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !12, nameTableKind: None)
!5 = !{}
!6 = !{!0, !7, !10}
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression(DW_OP_plus_uconst, 4))
!8 = distinct !DIGlobalVariable(name: "var2", scope: !2, file: !3, line: 3, type: !9, isLocal: false, isDefinition: true)
!9 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed)
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression(DW_OP_plus_uconst, 8))
!11 = distinct !DIGlobalVariable(name: "var3", scope: !2, file: !3, line: 4, type: !9, isLocal: false, isDefinition: true)
!12 = !{!13}
!13 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !14, entity: !2, file: !3, line: 10, elements: !19)
!14 = distinct !DISubprogram(name: "use_renamed", scope: !15, file: !3, line: 10, type: !18, scopeLine: 10, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !4)
!15 = distinct !DISubprogram(name: "main", scope: !4, file: !3, line: 7, type: !16, scopeLine: 7, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !4)
!16 = !DISubroutineType(cc: DW_CC_program, types: !17)
!17 = !{null}
!18 = !DISubroutineType(types: !17)
!19 = !{!20}
!20 = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "var4", scope: !14, entity: !1, file: !3, line: 10)
!21 = !{i32 2, !"Dwarf Version", i32 4}
!22 = !{i32 2, !"Debug Info Version", i32 3}
!23 = !DILocation(line: 8, column: 1, scope: !15)
!24 = !DILocation(line: 9, column: 1, scope: !15)
!25 = !DILocation(line: 13, column: 1, scope: !14)

View File

@ -0,0 +1,108 @@
;; This test checks processing of DIImportedEntity with elements field.
; REQUIRES: x86_64-linux
; RUN: llc %s -filetype=obj -o - | llvm-dwarfdump - | FileCheck %s
; CHECK: [[MYMOD:0x[0-9a-f]+]]: DW_TAG_module
; CHECK: DW_AT_name ("mymod")
; CHECK: [[VAR1:0x[0-9a-f]+]]: DW_TAG_variable
; CHECK: DW_AT_name ("var1")
; CHECK: DW_TAG_subprogram
; CHECK: DW_AT_name ("main")
; CHECK: DW_TAG_subprogram
; CHECK: DW_AT_name ("use_renamed")
; CHECK: DW_TAG_imported_module
; CHECK: DW_AT_import ([[MYMOD]])
; CHECK: DW_TAG_imported_declaration
; CHECK: DW_AT_import ([[VAR1]])
; CHECK: DW_AT_name ("var4")
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;This test case is generated from
;;module mymod
;; integer :: var1 = 11
;; integer :: var2 = 12
;; integer :: var3 = 13
;;end module mymod
;;
;;Program main
;; call use_renamed()
;; contains
;; subroutine use_renamed()
;; use mymod, var4 => var1
;; print *, var4
;; end subroutine use_renamed
;;end program main
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ModuleID = 'DIImportedEntity_elements.ll'
source_filename = "/tmp/usemodulealias.ll"
%struct_mymod_8_ = type <{ [12 x i8] }>
%struct.struct_ul_MAIN__348 = type { i8* }
@_mymod_8_ = global %struct_mymod_8_ <{ [12 x i8] c"\0B\00\00\00\0C\00\00\00\0D\00\00\00" }>, align 64, !dbg !0, !dbg !7, !dbg !10
@.C330_MAIN_ = internal constant i32 0
@.C364_main_use_renamed = internal constant i32 25
@.C330_main_use_renamed = internal constant i32 0
@.C331_main_use_renamed = internal constant i64 0
@.C359_main_use_renamed = internal constant i32 6
@.C357_main_use_renamed = internal constant [18 x i8] c"usemodulealias.f90"
@.C352_main_use_renamed = internal constant i32 12
define i32 @mymod_() {
.L.entry:
ret i32 undef
}
define void @MAIN_() !dbg !15 {
L.entry:
%.S0000_353 = alloca %struct.struct_ul_MAIN__348, align 8
%0 = bitcast i32* @.C330_MAIN_ to i8*
%1 = bitcast void (...)* @fort_init to void (i8*, ...)*
call void (i8*, ...) %1(i8* %0)
br label %L.LB2_357
L.LB2_357: ; preds = %L.entry
%2 = bitcast %struct.struct_ul_MAIN__348* %.S0000_353 to i64*, !dbg !23
call void @main_use_renamed(i64* %2), !dbg !23
ret void, !dbg !24
}
define internal void @main_use_renamed(i64* noalias %.S0000) !dbg !14 {
L.entry:
ret void, !dbg !25
}
declare void @fort_init(...)
!llvm.module.flags = !{!21, !22}
!llvm.dbg.cu = !{!4}
!0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression())
!1 = distinct !DIGlobalVariable(name: "var1", scope: !2, file: !3, line: 2, type: !9, isLocal: false, isDefinition: true)
!2 = !DIModule(scope: !4, name: "mymod", file: !3, line: 1)
!3 = !DIFile(filename: "DIImportedEntity_elements.f90", directory: "/tmp")
!4 = distinct !DICompileUnit(language: DW_LANG_Fortran90, file: !3, producer: " F90 Flang - 1.5 2017-05-01", isOptimized: false, flags: "'+flang usemodulealias.f90 -g -S -emit-llvm'", runtimeVersion: 0, emissionKind: FullDebug, enums: !5, retainedTypes: !5, globals: !6, imports: !12, nameTableKind: None)
!5 = !{}
!6 = !{!0, !7, !10}
!7 = !DIGlobalVariableExpression(var: !8, expr: !DIExpression(DW_OP_plus_uconst, 4))
!8 = distinct !DIGlobalVariable(name: "var2", scope: !2, file: !3, line: 3, type: !9, isLocal: false, isDefinition: true)
!9 = !DIBasicType(name: "integer", size: 32, align: 32, encoding: DW_ATE_signed)
!10 = !DIGlobalVariableExpression(var: !11, expr: !DIExpression(DW_OP_plus_uconst, 8))
!11 = distinct !DIGlobalVariable(name: "var3", scope: !2, file: !3, line: 4, type: !9, isLocal: false, isDefinition: true)
!12 = !{!13}
!13 = !DIImportedEntity(tag: DW_TAG_imported_module, scope: !14, entity: !2, file: !3, line: 10, elements: !19)
!14 = distinct !DISubprogram(name: "use_renamed", scope: !15, file: !3, line: 10, type: !18, scopeLine: 10, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition, unit: !4)
!15 = distinct !DISubprogram(name: "main", scope: !4, file: !3, line: 7, type: !16, scopeLine: 7, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagMainSubprogram, unit: !4)
!16 = !DISubroutineType(cc: DW_CC_program, types: !17)
!17 = !{null}
!18 = !DISubroutineType(types: !17)
!19 = !{!20}
!20 = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "var4", scope: !14, entity: !1, file: !3, line: 10)
!21 = !{i32 2, !"Dwarf Version", i32 4}
!22 = !{i32 2, !"Debug Info Version", i32 3}
!23 = !DILocation(line: 8, column: 1, scope: !15)
!24 = !DILocation(line: 9, column: 1, scope: !15)
!25 = !DILocation(line: 13, column: 1, scope: !14)

View File

@ -53,11 +53,10 @@ int llvm_test_dibuilder(void) {
"", 0,
"/test/include/llvm-c-test-import.h", 34,
"", 0);
LLVMMetadataRef ImportedModule =
LLVMDIBuilderCreateImportedModuleFromModule(DIB, Module, OtherModule,
File, 42);
LLVMDIBuilderCreateImportedModuleFromAlias(DIB, Module, ImportedModule,
File, 42);
LLVMMetadataRef ImportedModule = LLVMDIBuilderCreateImportedModuleFromModule(
DIB, Module, OtherModule, File, 42, NULL, 0);
LLVMDIBuilderCreateImportedModuleFromAlias(DIB, Module, ImportedModule, File,
42, NULL, 0);
LLVMMetadataRef ClassTy = declare_objc_class(DIB, File);
LLVMMetadataRef GlobalClassValueExpr =

View File

@ -945,13 +945,17 @@ TEST_F(IRBuilderTest, DIImportedEntity) {
auto CU = DIB.createCompileUnit(dwarf::DW_LANG_Cobol74,
F, "llvm-cobol74",
true, "", 0);
MDTuple *Elements = MDTuple::getDistinct(Ctx, None);
DIB.createImportedDeclaration(CU, nullptr, F, 1);
DIB.createImportedDeclaration(CU, nullptr, F, 1);
DIB.createImportedModule(CU, (DIImportedEntity *)nullptr, F, 2);
DIB.createImportedModule(CU, (DIImportedEntity *)nullptr, F, 2);
DIB.createImportedModule(CU, (DIImportedEntity *)nullptr, F, 2, Elements);
DIB.createImportedModule(CU, (DIImportedEntity *)nullptr, F, 2, Elements);
DIB.finalize();
EXPECT_TRUE(verifyModule(*M));
EXPECT_TRUE(CU->getImportedEntities().size() == 2);
EXPECT_TRUE(CU->getImportedEntities().size() == 3);
}
// 0: #define M0 V0 <-- command line definition

View File

@ -3042,6 +3042,25 @@ TEST_F(DIImportedEntityTest, get) {
TempDIImportedEntity Temp = N->clone();
EXPECT_EQ(N, MDNode::replaceWithUniqued(std::move(Temp)));
MDTuple *Elements1 = getTuple();
MDTuple *Elements2 = getTuple();
auto *Ne = DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line,
Name, Elements1);
EXPECT_EQ(Elements1, Ne->getElements().get());
EXPECT_EQ(Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line,
Name, Elements1));
EXPECT_NE(Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line,
"ModOther", Elements1));
EXPECT_NE(Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line,
Name, Elements2));
EXPECT_NE(
Ne, DIImportedEntity::get(Context, Tag, Scope, Entity, File, Line, Name));
TempDIImportedEntity Tempe = Ne->clone();
EXPECT_EQ(Ne, MDNode::replaceWithUniqued(std::move(Tempe)));
}
typedef MetadataTest MetadataAsValueTest;