summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp80
-rw-r--r--lib/DebugInfo/DWARFContext.cpp42
-rw-r--r--test/DebugInfo/X86/generate-odr-hash.ll12
3 files changed, 75 insertions, 59 deletions
diff --git a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
index abb550e0d1..2316301b40 100644
--- a/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
+++ b/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp
@@ -929,6 +929,40 @@ DIE *CompileUnit::createTypeDIE(DICompositeType Ty) {
return TyDIE;
}
+/// Return true if the type is appropriately scoped to be contained inside
+/// its own type unit.
+static bool isTypeUnitScoped(DIType Ty, const DwarfDebug *DD) {
+ DIScope Parent = DD->resolve(Ty.getContext());
+ while (Parent) {
+ // Don't generate a hash for anything scoped inside a function.
+ if (Parent.isSubprogram())
+ return false;
+ Parent = DD->resolve(Parent.getContext());
+ }
+ return true;
+}
+
+/// Return true if the type should be split out into a type unit.
+static bool shouldCreateTypeUnit(DICompositeType CTy, const DwarfDebug *DD) {
+ if (!GenerateTypeUnits)
+ return false;
+
+ uint16_t Tag = CTy.getTag();
+
+ switch (Tag) {
+ case dwarf::DW_TAG_structure_type:
+ case dwarf::DW_TAG_union_type:
+ case dwarf::DW_TAG_enumeration_type:
+ case dwarf::DW_TAG_class_type:
+ // If this is a class, structure, union, or enumeration type
+ // that is a definition (not a declaration), and not scoped
+ // inside a function then separate this out as a type unit.
+ return !CTy.isForwardDecl() && isTypeUnitScoped(CTy, DD);
+ default:
+ return false;
+ }
+}
+
/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
/// given DIType.
DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
@@ -953,9 +987,15 @@ DIE *CompileUnit::getOrCreateTypeDIE(const MDNode *TyNode) {
if (Ty.isBasicType())
constructTypeDIE(*TyDIE, DIBasicType(Ty));
- else if (Ty.isCompositeType())
- constructTypeDIE(*TyDIE, DICompositeType(Ty));
- else {
+ else if (Ty.isCompositeType()) {
+ DICompositeType CTy(Ty);
+ if (shouldCreateTypeUnit(CTy, DD)) {
+ DD->addTypeUnitType(TyDIE, CTy);
+ // Skip updating the accellerator tables since this is not the full type
+ return TyDIE;
+ }
+ constructTypeDIEImpl(*TyDIE, CTy);
+ } else {
assert(Ty.isDerivedType() && "Unknown kind of DIType");
constructTypeDIE(*TyDIE, DIDerivedType(Ty));
}
@@ -1127,40 +1167,6 @@ void CompileUnit::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
addSourceLine(&Buffer, DTy);
}
-/// Return true if the type is appropriately scoped to be contained inside
-/// its own type unit.
-static bool isTypeUnitScoped(DIType Ty, const DwarfDebug *DD) {
- DIScope Parent = DD->resolve(Ty.getContext());
- while (Parent) {
- // Don't generate a hash for anything scoped inside a function.
- if (Parent.isSubprogram())
- return false;
- Parent = DD->resolve(Parent.getContext());
- }
- return true;
-}
-
-/// Return true if the type should be split out into a type unit.
-static bool shouldCreateTypeUnit(DICompositeType CTy, const DwarfDebug *DD) {
- if (!GenerateTypeUnits)
- return false;
-
- uint16_t Tag = CTy.getTag();
-
- switch (Tag) {
- case dwarf::DW_TAG_structure_type:
- case dwarf::DW_TAG_union_type:
- case dwarf::DW_TAG_enumeration_type:
- case dwarf::DW_TAG_class_type:
- // If this is a class, structure, union, or enumeration type
- // that is a definition (not a declaration), and not scoped
- // inside a function then separate this out as a type unit.
- return !CTy.isForwardDecl() && isTypeUnitScoped(CTy, DD);
- default:
- return false;
- }
-}
-
/// constructTypeDIE - Construct type DIE from DICompositeType.
void CompileUnit::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
// If this is a type applicable to a type unit it then add it to the
diff --git a/lib/DebugInfo/DWARFContext.cpp b/lib/DebugInfo/DWARFContext.cpp
index e47719025c..eaeb2dcc1c 100644
--- a/lib/DebugInfo/DWARFContext.cpp
+++ b/lib/DebugInfo/DWARFContext.cpp
@@ -34,27 +34,29 @@ static void dumpPubSection(raw_ostream &OS, StringRef Name, StringRef Data,
OS << "\n." << Name << " contents:\n";
DataExtractor pubNames(Data, LittleEndian, 0);
uint32_t offset = 0;
- OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
- OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
- OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
- OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
- if (GnuStyle)
- OS << "Offset Linkage Kind Name\n";
- else
- OS << "Offset Name\n";
-
- while (offset < Data.size()) {
- uint32_t dieRef = pubNames.getU32(&offset);
- if (dieRef == 0)
- break;
- OS << format("0x%8.8x ", dieRef);
- if (GnuStyle) {
- PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
- OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage))
- << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind))
- << ' ';
+ while (pubNames.isValidOffset(offset)) {
+ OS << "length = " << format("0x%08x", pubNames.getU32(&offset));
+ OS << " version = " << format("0x%04x", pubNames.getU16(&offset));
+ OS << " unit_offset = " << format("0x%08x", pubNames.getU32(&offset));
+ OS << " unit_size = " << format("0x%08x", pubNames.getU32(&offset)) << '\n';
+ if (GnuStyle)
+ OS << "Offset Linkage Kind Name\n";
+ else
+ OS << "Offset Name\n";
+
+ while (offset < Data.size()) {
+ uint32_t dieRef = pubNames.getU32(&offset);
+ if (dieRef == 0)
+ break;
+ OS << format("0x%8.8x ", dieRef);
+ if (GnuStyle) {
+ PubIndexEntryDescriptor desc(pubNames.getU8(&offset));
+ OS << format("%-8s", dwarf::GDBIndexEntryLinkageString(desc.Linkage))
+ << ' ' << format("%-8s", dwarf::GDBIndexEntryKindString(desc.Kind))
+ << ' ';
+ }
+ OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
}
- OS << '\"' << pubNames.getCStr(&offset) << "\"\n";
}
}
diff --git a/test/DebugInfo/X86/generate-odr-hash.ll b/test/DebugInfo/X86/generate-odr-hash.ll
index f167c86180..8ff367fa67 100644
--- a/test/DebugInfo/X86/generate-odr-hash.ll
+++ b/test/DebugInfo/X86/generate-odr-hash.ll
@@ -1,8 +1,8 @@
; REQUIRES: object-emission
; RUN: llc %s -o %t -filetype=obj -O0 -generate-type-units -generate-odr-hash -mtriple=x86_64-unknown-linux-gnu
-; RUN: llvm-dwarfdump -debug-dump=info %t | FileCheck %s
-;
+; RUN: llvm-dwarfdump %t | FileCheck %s
+
; Generated from:
; struct bar {};
@@ -43,6 +43,8 @@
; wombat wom;
+; CHECK-LABEL: .debug_info contents:
+
; Check that we generate a hash for bar and the value.
; CHECK-LABEL: DW_AT_GNU_odr_signature [DW_FORM_data8] (0x200520c0d5b90eff)
; CHECK: DW_TAG_structure_type
@@ -89,6 +91,12 @@
; CHECK: DW_TAG_structure_type
; CHECK-NEXT: debug_str{{.*}}"wombat"
+; Don't emit pubtype entries for type DIEs in the compile unit that just indirect to a type unit.
+; CHECK-LABEL: .debug_pubtypes contents:
+; CHECK-NEXT: unit_offset = 0x00000000
+; CHECK-NEXT: Offset
+; CHECK-NEXT: {{^$}}
+
%struct.bar = type { i8 }
%"class.echidna::capybara::mongoose::fluffy" = type { i32, i32 }
%"struct.<anonymous namespace>::walrus" = type { i8 }