[llvm] r341123 - dsymutil: Avoid pruning non-type forward declarations inside DW_TAG_module

Adrian Prantl via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 30 14:21:16 PDT 2018


Author: adrian
Date: Thu Aug 30 14:21:16 2018
New Revision: 341123

URL: http://llvm.org/viewvc/llvm-project?rev=341123&view=rev
Log:
dsymutil: Avoid pruning non-type forward declarations inside DW_TAG_module
forward declarations.

Especially with template instantiations, there are legitimate reasons
why for declarations might be emitted into a DW_TAG_module skeleton /
forward-declaration sub-tree, that are not forward declarations in the
sense of that there is a more complete definition over in a .pcm file.

The example in the testcase is a constant DW_TAG_member of a
DW_TAG_class template instatiation.

rdar://problem/43623196

Added:
    llvm/trunk/test/tools/dsymutil/Inputs/modules-pruning/
    llvm/trunk/test/tools/dsymutil/Inputs/modules-pruning/1.o
    llvm/trunk/test/tools/dsymutil/Inputs/modules-pruning/Outer.pcm
    llvm/trunk/test/tools/dsymutil/X86/modules-pruning.cpp
Modified:
    llvm/trunk/tools/dsymutil/DwarfLinker.cpp

Added: llvm/trunk/test/tools/dsymutil/Inputs/modules-pruning/1.o
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/modules-pruning/1.o?rev=341123&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/dsymutil/Inputs/modules-pruning/1.o (added) and llvm/trunk/test/tools/dsymutil/Inputs/modules-pruning/1.o Thu Aug 30 14:21:16 2018 differ

Added: llvm/trunk/test/tools/dsymutil/Inputs/modules-pruning/Outer.pcm
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/Inputs/modules-pruning/Outer.pcm?rev=341123&view=auto
==============================================================================
Binary files llvm/trunk/test/tools/dsymutil/Inputs/modules-pruning/Outer.pcm (added) and llvm/trunk/test/tools/dsymutil/Inputs/modules-pruning/Outer.pcm Thu Aug 30 14:21:16 2018 differ

Added: llvm/trunk/test/tools/dsymutil/X86/modules-pruning.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/dsymutil/X86/modules-pruning.cpp?rev=341123&view=auto
==============================================================================
--- llvm/trunk/test/tools/dsymutil/X86/modules-pruning.cpp (added)
+++ llvm/trunk/test/tools/dsymutil/X86/modules-pruning.cpp Thu Aug 30 14:21:16 2018
@@ -0,0 +1,59 @@
+// RUN: dsymutil -f -oso-prepend-path=%p/../Inputs/modules-pruning \
+// RUN:   -y %p/dummy-debug-map.map -o - \
+// RUN:     | llvm-dwarfdump --name isRef -p - | FileCheck %s
+
+/* Compile with:
+   cat >modules.modulemap <<EOF
+   module Outer {
+     module Template {
+       header "template.h"
+       export *
+     }
+   }
+EOF
+   clang++ -D TEMPLATE_H -E -o template.h modules-pruning.cpp
+   clang++ -c -fcxx-modules -fmodules -fmodule-map-file=modules.modulemap \
+     -g -gmodules -fmodules-cache-path=. \
+     -Xclang -fdisable-module-hash modules-pruning.cpp -o 1.o
+*/
+
+// CHECK: DW_TAG_compile_unit
+// CHECK:   DW_TAG_module
+// CHECK:     DW_TAG_module
+// CHECK:       DW_TAG_class
+// CHECK:         DW_TAG_member
+// CHECK:           DW_AT_name ("isRef")
+// CHECK:           DW_AT_declaration (true)
+// CHECK:           DW_AT_const_value (1)
+// CHECK-NOT: DW_TAG
+
+#ifdef TEMPLATE_H
+
+namespace M {
+struct false_type {
+  static const bool value = false;
+};
+struct true_type {
+  static const bool value = true;
+};
+
+template <class T> struct is_reference      : false_type {};
+template <class T> struct is_reference<T&>  : true_type {};
+
+template<class T>
+class Template {
+public:
+  static const bool isRef = is_reference<T>::value;
+  Template() {}
+};
+}
+#else
+
+#include "template.h"
+
+void foo() {
+  M::Template<bool&> TB1;
+  TB1.isRef;
+}
+
+#endif

Modified: llvm/trunk/tools/dsymutil/DwarfLinker.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/dsymutil/DwarfLinker.cpp?rev=341123&r1=341122&r2=341123&view=diff
==============================================================================
--- llvm/trunk/tools/dsymutil/DwarfLinker.cpp (original)
+++ llvm/trunk/tools/dsymutil/DwarfLinker.cpp Thu Aug 30 14:21:16 2018
@@ -155,6 +155,40 @@ static bool isODRAttribute(uint16_t Attr
   llvm_unreachable("Improper attribute.");
 }
 
+static bool isTypeTag(uint16_t Tag) {
+  switch (Tag) {
+  case dwarf::DW_TAG_array_type:
+  case dwarf::DW_TAG_class_type:
+  case dwarf::DW_TAG_enumeration_type:
+  case dwarf::DW_TAG_pointer_type:
+  case dwarf::DW_TAG_reference_type:
+  case dwarf::DW_TAG_string_type:
+  case dwarf::DW_TAG_structure_type:
+  case dwarf::DW_TAG_subroutine_type:
+  case dwarf::DW_TAG_typedef:
+  case dwarf::DW_TAG_union_type:
+  case dwarf::DW_TAG_ptr_to_member_type:
+  case dwarf::DW_TAG_set_type:
+  case dwarf::DW_TAG_subrange_type:
+  case dwarf::DW_TAG_base_type:
+  case dwarf::DW_TAG_const_type:
+  case dwarf::DW_TAG_constant:
+  case dwarf::DW_TAG_file_type:
+  case dwarf::DW_TAG_namelist:
+  case dwarf::DW_TAG_packed_type:
+  case dwarf::DW_TAG_volatile_type:
+  case dwarf::DW_TAG_restrict_type:
+  case dwarf::DW_TAG_atomic_type:
+  case dwarf::DW_TAG_interface_type:
+  case dwarf::DW_TAG_unspecified_type:
+  case dwarf::DW_TAG_shared_type:
+    return true;
+  default:
+    break;
+  }
+  return false;
+}
+
 bool DwarfLinker::DIECloner::getDIENames(const DWARFDie &Die,
                                          AttributesInfo &Info,
                                          OffsetsStringPool &StringPool,
@@ -269,7 +303,8 @@ static bool analyzeContextInfo(const DWA
   // DW_TAG_module or a DW_TAG_module that contains nothing but
   // forward declarations.
   Info.Prune &= (DIE.getTag() == dwarf::DW_TAG_module) ||
-                dwarf::toUnsigned(DIE.find(dwarf::DW_AT_declaration), 0);
+                (isTypeTag(DIE.getTag()) &&
+                 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();
@@ -1258,40 +1293,6 @@ bool DwarfLinker::RelocationManager::app
   return Applied;
 }
 
-static bool isTypeTag(uint16_t Tag) {
-  switch (Tag) {
-  case dwarf::DW_TAG_array_type:
-  case dwarf::DW_TAG_class_type:
-  case dwarf::DW_TAG_enumeration_type:
-  case dwarf::DW_TAG_pointer_type:
-  case dwarf::DW_TAG_reference_type:
-  case dwarf::DW_TAG_string_type:
-  case dwarf::DW_TAG_structure_type:
-  case dwarf::DW_TAG_subroutine_type:
-  case dwarf::DW_TAG_typedef:
-  case dwarf::DW_TAG_union_type:
-  case dwarf::DW_TAG_ptr_to_member_type:
-  case dwarf::DW_TAG_set_type:
-  case dwarf::DW_TAG_subrange_type:
-  case dwarf::DW_TAG_base_type:
-  case dwarf::DW_TAG_const_type:
-  case dwarf::DW_TAG_constant:
-  case dwarf::DW_TAG_file_type:
-  case dwarf::DW_TAG_namelist:
-  case dwarf::DW_TAG_packed_type:
-  case dwarf::DW_TAG_volatile_type:
-  case dwarf::DW_TAG_restrict_type:
-  case dwarf::DW_TAG_atomic_type:
-  case dwarf::DW_TAG_interface_type:
-  case dwarf::DW_TAG_unspecified_type:
-  case dwarf::DW_TAG_shared_type:
-    return true;
-  default:
-    break;
-  }
-  return false;
-}
-
 static bool isObjCSelector(StringRef Name) {
   return Name.size() > 2 && (Name[0] == '-' || Name[0] == '+') &&
          (Name[1] == '[');




More information about the llvm-commits mailing list