diff --git a/llvm/test/tools/dsymutil/Inputs/submodules/1.o b/llvm/test/tools/dsymutil/Inputs/submodules/1.o index f95b70cd05cd..d38e30f67c2c 100644 Binary files a/llvm/test/tools/dsymutil/Inputs/submodules/1.o and b/llvm/test/tools/dsymutil/Inputs/submodules/1.o differ diff --git a/llvm/test/tools/dsymutil/Inputs/submodules/Parent.pcm b/llvm/test/tools/dsymutil/Inputs/submodules/Parent.pcm index dca33af4268d..e6909d7afa5e 100644 Binary files a/llvm/test/tools/dsymutil/Inputs/submodules/Parent.pcm and b/llvm/test/tools/dsymutil/Inputs/submodules/Parent.pcm differ diff --git a/llvm/test/tools/dsymutil/X86/submodules.m b/llvm/test/tools/dsymutil/X86/submodules.m index 64efc2f54baf..4cb5bcfaee2b 100644 --- a/llvm/test/tools/dsymutil/X86/submodules.m +++ b/llvm/test/tools/dsymutil/X86/submodules.m @@ -4,9 +4,13 @@ module Child { header "Child.h" } + module Empty { + header "Empty.h" + } } EOF clang -D CHILD_H -E -o Child.h submodules.m + touch empty.h clang -cc1 -emit-obj -fmodules -fmodule-map-file=modules.modulemap \ -fmodule-format=obj -g -dwarf-ext-refs -fmodules-cache-path=. \ -fdisable-module-hash submodules.m -o 1.o @@ -19,6 +23,7 @@ EOF // --------------------------------------------------------------------- #ifdef CHILD_H // --------------------------------------------------------------------- + // CHECK: DW_TAG_compile_unit // CHECK-NOT: DW_TAG // CHECK: DW_TAG_module @@ -28,13 +33,22 @@ EOF // CHECK: DW_TAG_structure_type // CHECK-NOT: DW_TAG // CHECK: DW_AT_name {{.*}}"PruneMeNot" - struct PruneMeNot; // --------------------------------------------------------------------- #else // --------------------------------------------------------------------- +// CHECK: DW_TAG_compile_unit +// CHECK: DW_TAG_module +// CHECK-NEXT: DW_AT_name{{.*}}"Parent" +// CHECK: DW_TAG_module +// CHECK-NEXT: DW_AT_name{{.*}}"Child" +// CHECK: 0x0[[EMPTY:.*]]: DW_TAG_module +// CHECK-NEXT: DW_AT_name{{.*}}"Empty" + +// CHECK: DW_AT_import {{.*}}0x{{0*}}[[EMPTY]] @import Parent.Child; +@import Parent.Empty; int main(int argc, char **argv) { return 0; } #endif diff --git a/llvm/tools/dsymutil/DwarfLinker.cpp b/llvm/tools/dsymutil/DwarfLinker.cpp index c877264a067f..52c480ec4f1d 100644 --- a/llvm/tools/dsymutil/DwarfLinker.cpp +++ b/llvm/tools/dsymutil/DwarfLinker.cpp @@ -1807,6 +1807,9 @@ static bool analyzeContextInfo(const DWARFDebugInfoEntryMinimal *DIE, DIE->getAttributeValueAsUnsignedConstant( &CU.getOrigUnit(), dwarf::DW_AT_declaration, 0); + // Don't prune it if there is no definition for the DIE. + Info.Prune &= Info.Ctxt && Info.Ctxt->getCanonicalDIEOffset(); + return Info.Prune; } @@ -3338,21 +3341,23 @@ bool DwarfLinker::link(const DebugMap &Map) { DWARFContextInMemory DwarfContext(*ErrOrObj); startDebugObject(DwarfContext, *Obj); - // In a first phase, just read in the debug info and store the DIE - // parent links that we will use during the next phase. + // In a first phase, just read in the debug info and load all clang modules. for (const auto &CU : DwarfContext.compile_units()) { auto *CUDie = CU->getUnitDIE(false); if (Options.Verbose) { outs() << "Input compilation unit:"; CUDie->dump(outs(), CU.get(), 0); } - if (!registerModuleReference(*CUDie, *CU, ModuleMap)) { + + if (!registerModuleReference(*CUDie, *CU, ModuleMap)) Units.emplace_back(*CU, UnitID++, !Options.NoODR, ""); - analyzeContextInfo(CUDie, 0, Units.back(), &ODRContexts.getRoot(), - StringPool, ODRContexts); - } } + // Now build the DIE parent links that we will use during the next phase. + for (auto &CurrentUnit : Units) + analyzeContextInfo(CurrentUnit.getOrigUnit().getUnitDIE(), 0, CurrentUnit, + &ODRContexts.getRoot(), StringPool, ODRContexts); + // Then mark all the DIEs that need to be present in the linked // output and collect some information about them. Note that this // loop can not be merged with the previous one becaue cross-cu