Index: llvm/tools/dsymutil/DwarfLinker.cpp =================================================================== --- llvm/tools/dsymutil/DwarfLinker.cpp +++ llvm/tools/dsymutil/DwarfLinker.cpp @@ -271,12 +271,30 @@ Info.Prune &= (DIE.getTag() == dwarf::DW_TAG_module) || dwarf::toUnsigned(DIE.find(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; } +/// The canonical DIE offset is calculated when cloning a DIE. Therefore we +/// cannot do it during analysis, but rather have to fix it up at the beginning +/// of the clone step. +static void updatePruning(CompileUnit::DIEInfo &Info, CompileUnit &CU) { + // Don't prune forward declarations inside a DW_TAG_module if no definition + // exists elsewhere. + if (!Info.Prune || !Info.Ctxt || !Info.Ctxt->getCanonicalDIEOffset()) + return; + + Info.Prune = false; + + unsigned int ParentIdx = Info.ParentIdx; + while (ParentIdx != 0) { + CompileUnit::DIEInfo &ParentInfo = CU.getInfo(ParentIdx); + if (!ParentInfo.Prune) + return; + ParentInfo.Prune = false; + ParentIdx = ParentInfo.ParentIdx; + } +} + static bool dieNeedsChildrenToBeMeaningful(uint32_t Tag) { switch (Tag) { default: @@ -840,6 +858,9 @@ if (!Worklist.empty()) Worklist.back().ChildInfo = &MyInfo; + if (!Current.Flags) + updatePruning(MyInfo, CU); + if (MyInfo.Prune) continue; @@ -2512,14 +2533,13 @@ *CU, UnitID++, !Options.NoODR && !Options.Update, "")); } } - + // Now build the DIE parent links that we will use during the next phase. for (auto &CurrentUnit : LinkContext.CompileUnits) { auto CUDie = CurrentUnit->getOrigUnit().getUnitDIE(); if (!CUDie) continue; - analyzeContextInfo(CurrentUnit->getOrigUnit().getUnitDIE(), 0, - *CurrentUnit, &ODRContexts.getRoot(), + analyzeContextInfo(CUDie, 0, *CurrentUnit, &ODRContexts.getRoot(), UniquingStringPool, ODRContexts); }