--- /dev/null
+// 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
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,
// 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();
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] == '[');