Index: llvm/docs/LangRef.rst =================================================================== --- llvm/docs/LangRef.rst +++ llvm/docs/LangRef.rst @@ -5790,12 +5790,16 @@ """""""""""""""" ``DIImportedEntity`` nodes represent entities (such as modules) imported into a -compile unit. +compile unit. The ``elements`` field is list of renamed entities (such as +variables and subprograms) in 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 """"""" Index: llvm/include/llvm-c/DebugInfo.h =================================================================== --- llvm/include/llvm-c/DebugInfo.h +++ llvm/include/llvm-c/DebugInfo.h @@ -389,48 +389,48 @@ * \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. - */ -LLVMMetadataRef -LLVMDIBuilderCreateImportedDeclaration(LLVMDIBuilderRef Builder, - LLVMMetadataRef Scope, - LLVMMetadataRef Decl, - LLVMMetadataRef File, - unsigned Line, - const char *Name, size_t NameLen); + * \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 *Elements, unsigned NumElements); /** * Creates a new DebugLocation that describes a source location. Index: llvm/include/llvm/IR/DIBuilder.h =================================================================== --- llvm/include/llvm/IR/DIBuilder.h +++ llvm/include/llvm/IR/DIBuilder.h @@ -827,29 +827,35 @@ 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 @@ /// 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 Index: llvm/include/llvm/IR/DebugInfoMetadata.h =================================================================== --- llvm/include/llvm/IR/DebugInfoMetadata.h +++ llvm/include/llvm/IR/DebugInfoMetadata.h @@ -3347,31 +3347,33 @@ 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 @@ DINode *getEntity() const { return cast_or_null(getRawEntity()); } StringRef getName() const { return getStringOperand(2); } DIFile *getFile() const { return cast_or_null(getRawFile()); } + DINodeArray getElements() const { + return cast_or_null(getRawElements()); + } Metadata *getRawScope() const { return getOperand(0); } Metadata *getRawEntity() const { return getOperand(1); } MDString *getRawName() const { return getOperandAs(2); } Metadata *getRawFile() const { return getOperand(3); } + Metadata *getRawElements() const { return getOperand(4); } static bool classof(const Metadata *MD) { return MD->getMetadataID() == DIImportedEntityKind; Index: llvm/lib/AsmParser/LLParser.cpp =================================================================== --- llvm/lib/AsmParser/LLParser.cpp +++ llvm/lib/AsmParser/LLParser.cpp @@ -5114,7 +5114,7 @@ /// 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 @@ 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; } Index: llvm/lib/Bitcode/Reader/MetadataLoader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/MetadataLoader.cpp +++ llvm/lib/Bitcode/Reader/MetadataLoader.cpp @@ -2044,17 +2044,19 @@ 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; Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -2062,6 +2062,7 @@ 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(); Index: llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp +++ llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp @@ -1269,6 +1269,16 @@ 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(Element))); + } + return IMDie; } Index: llvm/lib/IR/AsmWriter.cpp =================================================================== --- llvm/lib/IR/AsmWriter.cpp +++ llvm/lib/IR/AsmWriter.cpp @@ -2411,6 +2411,7 @@ Printer.printMetadata("entity", N->getRawEntity()); Printer.printMetadata("file", N->getRawFile()); Printer.printInt("line", N->getLine()); + Printer.printMetadata("elements", N->getRawElements()); Out << ")"; } Index: llvm/lib/IR/DIBuilder.cpp =================================================================== --- llvm/lib/IR/DIBuilder.cpp +++ llvm/lib/IR/DIBuilder.cpp @@ -165,12 +165,13 @@ static DIImportedEntity * createImportedModule(LLVMContext &C, dwarf::Tag Tag, DIScope *Context, Metadata *NS, DIFile *File, unsigned Line, StringRef Name, + DINodeArray Elements, SmallVectorImpl &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(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 @@ 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); } Index: llvm/lib/IR/DebugInfo.cpp =================================================================== --- llvm/lib/IR/DebugInfo.cpp +++ llvm/lib/IR/DebugInfo.cpp @@ -1003,41 +1003,43 @@ 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(Scope), - unwrapDI(ImportedEntity), - unwrapDI(File), Line)); -} - -LLVMMetadataRef -LLVMDIBuilderCreateImportedModuleFromModule(LLVMDIBuilderRef Builder, - LLVMMetadataRef Scope, - LLVMMetadataRef M, - LLVMMetadataRef File, - unsigned Line) { - return wrap(unwrap(Builder)->createImportedModule(unwrapDI(Scope), - unwrapDI(M), - unwrapDI(File), - Line)); -} - -LLVMMetadataRef -LLVMDIBuilderCreateImportedDeclaration(LLVMDIBuilderRef Builder, - LLVMMetadataRef Scope, - LLVMMetadataRef Decl, - LLVMMetadataRef File, - unsigned Line, - const char *Name, size_t NameLen) { + unwrapDI(Scope), unwrapDI(ImportedEntity), + unwrapDI(File), Line, Elts)); +} + +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(Scope), unwrapDI(M), unwrapDI(File), + Line, Elts)); +} + +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(Scope), - unwrapDI(Decl), - unwrapDI(File), Line, {Name, NameLen})); + unwrapDI(Scope), unwrapDI(Decl), unwrapDI(File), + Line, {Name, NameLen}, Elts)); } LLVMMetadataRef Index: llvm/lib/IR/DebugInfoMetadata.cpp =================================================================== --- llvm/lib/IR/DebugInfoMetadata.cpp +++ llvm/lib/IR/DebugInfoMetadata.cpp @@ -1602,12 +1602,13 @@ 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); } Index: llvm/lib/IR/LLVMContextImpl.h =================================================================== --- llvm/lib/IR/LLVMContextImpl.h +++ llvm/lib/IR/LLVMContextImpl.h @@ -1169,23 +1169,26 @@ 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); } }; Index: llvm/test/Bitcode/DIImportedEntity_backward.ll =================================================================== --- /dev/null +++ llvm/test/Bitcode/DIImportedEntity_backward.ll @@ -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) Index: llvm/test/Bitcode/DIImportedEntity_elements.ll =================================================================== --- /dev/null +++ llvm/test/Bitcode/DIImportedEntity_elements.ll @@ -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) Index: llvm/test/DebugInfo/X86/dwarfdump-DIImportedEntity_elements.ll =================================================================== --- /dev/null +++ llvm/test/DebugInfo/X86/dwarfdump-DIImportedEntity_elements.ll @@ -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) Index: llvm/tools/llvm-c-test/debuginfo.c =================================================================== --- llvm/tools/llvm-c-test/debuginfo.c +++ llvm/tools/llvm-c-test/debuginfo.c @@ -53,11 +53,10 @@ "", 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 = Index: llvm/unittests/IR/IRBuilderTest.cpp =================================================================== --- llvm/unittests/IR/IRBuilderTest.cpp +++ llvm/unittests/IR/IRBuilderTest.cpp @@ -945,13 +945,17 @@ 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 Index: llvm/unittests/IR/MetadataTest.cpp =================================================================== --- llvm/unittests/IR/MetadataTest.cpp +++ llvm/unittests/IR/MetadataTest.cpp @@ -3042,6 +3042,25 @@ 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;