dsymutil: Don't prune forward declarations inside of an imported TAG_module
authorAdrian Prantl <aprantl@apple.com>
Mon, 5 Oct 2015 23:11:20 +0000 (23:11 +0000)
committerAdrian Prantl <aprantl@apple.com>
Mon, 5 Oct 2015 23:11:20 +0000 (23:11 +0000)
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.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@249362 91177308-0d34-0410-b5e6-96231b3b80d8

test/tools/dsymutil/Inputs/submodules/1.o
test/tools/dsymutil/Inputs/submodules/Parent.pcm
test/tools/dsymutil/X86/submodules.m
tools/dsymutil/DwarfLinker.cpp

index f95b70cd05cd20746926f53cecef077746164d19..d38e30f67c2c4f8031669ae48cdde5743400ef9b 100644 (file)
Binary files a/test/tools/dsymutil/Inputs/submodules/1.o and b/test/tools/dsymutil/Inputs/submodules/1.o differ
index dca33af4268d83f58cb316342eb551485cb89d18..e6909d7afa5e3c2801623df405f418a7ff572900 100644 (file)
Binary files a/test/tools/dsymutil/Inputs/submodules/Parent.pcm and b/test/tools/dsymutil/Inputs/submodules/Parent.pcm differ
index 64efc2f54bafb66bbf760ea027d84c4659a395c7..4cb5bcfaee2b45c7c9c29c9434e577526781b5c7 100644 (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
index c877264a067f7adbd8a1d57e67cf662f3cdcb249..52c480ec4f1d1ced022f27411ede0aa6558bb8bd 100644 (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