dsymutil: Don't prune forward declarations inside of an imported TAG_module

if there exists not definition for the type.
For this to work, we need to clone the imported modules before building
the decl context chains of the DIEs in the non-skeleton CUs.

llvm-svn: 249362
This commit is contained in:
Adrian Prantl 2015-10-05 23:11:20 +00:00
parent b3788eaf99
commit d2793a030b
4 changed files with 26 additions and 7 deletions

View File

@ -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

View File

@ -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