[llvm] 4cabaf5 - NFC: DebugInfo: refactor pretty printing into a utility class
David Blaikie via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 14 15:54:49 PDT 2021
Author: David Blaikie
Date: 2021-09-14T15:54:29-07:00
New Revision: 4cabaf594aa272b02c0d227ae16a2aced687d796
URL: https://github.com/llvm/llvm-project/commit/4cabaf594aa272b02c0d227ae16a2aced687d796
DIFF: https://github.com/llvm/llvm-project/commit/4cabaf594aa272b02c0d227ae16a2aced687d796.diff
LOG: NFC: DebugInfo: refactor pretty printing into a utility class
Laying more foundation for full template name rebuilding - more complex
type printing benefits from an object to carry some state rather than
passing it around as parameters to every function.
Added:
Modified:
llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
Removed:
################################################################################
diff --git a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
index 535a2e280b22..31db690ba7a1 100644
--- a/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
+++ b/llvm/lib/DebugInfo/DWARF/DWARFDie.cpp
@@ -108,207 +108,211 @@ static void dumpLocationExpr(raw_ostream &OS, const DWARFFormValue &FormValue,
return;
}
-/// Dump the name encoded in the type tag.
-static void dumpTypeTagName(raw_ostream &OS, dwarf::Tag T) {
- StringRef TagStr = TagString(T);
- if (!TagStr.startswith("DW_TAG_") || !TagStr.endswith("_type"))
- return;
- OS << TagStr.substr(7, TagStr.size() - 12) << " ";
-}
-
-static void dumpArrayType(raw_ostream &OS, const DWARFDie &D) {
- for (const DWARFDie &C : D.children())
- if (C.getTag() == DW_TAG_subrange_type) {
- Optional<uint64_t> LB;
- Optional<uint64_t> Count;
- Optional<uint64_t> UB;
- Optional<unsigned> DefaultLB;
- if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound))
- LB = L->getAsUnsignedConstant();
- if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count))
- Count = CountV->getAsUnsignedConstant();
- if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound))
- UB = UpperV->getAsUnsignedConstant();
- if (Optional<DWARFFormValue> LV =
- D.getDwarfUnit()->getUnitDIE().find(DW_AT_language))
- if (Optional<uint64_t> LC = LV->getAsUnsignedConstant())
- if ((DefaultLB =
- LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC))))
- if (LB && *LB == *DefaultLB)
- LB = None;
- if (!LB && !Count && !UB)
- OS << "[]";
- else if (!LB && (Count || UB) && DefaultLB)
- OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']';
- else {
- OS << "[[";
- if (LB)
- OS << *LB;
- else
- OS << '?';
- OS << ", ";
- if (Count)
+namespace {
+
+// FIXME: We should have pretty printers per language. Currently we print
+// everything as if it was C++ and fall back to the TAG type name.
+struct DWARFTypePrinter {
+ raw_ostream &OS;
+ bool Word = true;
+ bool EndedWithTemplate = false;
+
+ DWARFTypePrinter(raw_ostream &OS) : OS(OS) {}
+
+ /// Dump the name encoded in the type tag.
+ void appendTypeTagName(dwarf::Tag T) {
+ StringRef TagStr = TagString(T);
+ if (!TagStr.startswith("DW_TAG_") || !TagStr.endswith("_type"))
+ return;
+ OS << TagStr.substr(7, TagStr.size() - 12) << " ";
+ }
+
+ void appendArrayType(const DWARFDie &D) {
+ for (const DWARFDie &C : D.children())
+ if (C.getTag() == DW_TAG_subrange_type) {
+ Optional<uint64_t> LB;
+ Optional<uint64_t> Count;
+ Optional<uint64_t> UB;
+ Optional<unsigned> DefaultLB;
+ if (Optional<DWARFFormValue> L = C.find(DW_AT_lower_bound))
+ LB = L->getAsUnsignedConstant();
+ if (Optional<DWARFFormValue> CountV = C.find(DW_AT_count))
+ Count = CountV->getAsUnsignedConstant();
+ if (Optional<DWARFFormValue> UpperV = C.find(DW_AT_upper_bound))
+ UB = UpperV->getAsUnsignedConstant();
+ if (Optional<DWARFFormValue> LV =
+ D.getDwarfUnit()->getUnitDIE().find(DW_AT_language))
+ if (Optional<uint64_t> LC = LV->getAsUnsignedConstant())
+ if ((DefaultLB = LanguageLowerBound(
+ static_cast<dwarf::SourceLanguage>(*LC))))
+ if (LB && *LB == *DefaultLB)
+ LB = None;
+ if (!LB && !Count && !UB)
+ OS << "[]";
+ else if (!LB && (Count || UB) && DefaultLB)
+ OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']';
+ else {
+ OS << "[[";
if (LB)
- OS << *LB + *Count;
+ OS << *LB;
else
- OS << "? + " << *Count;
- else if (UB)
- OS << *UB + 1;
- else
- OS << '?';
- OS << ")]";
+ OS << '?';
+ OS << ", ";
+ if (Count)
+ if (LB)
+ OS << *LB + *Count;
+ else
+ OS << "? + " << *Count;
+ else if (UB)
+ OS << *UB + 1;
+ else
+ OS << '?';
+ OS << ")]";
+ }
}
- }
-}
-
-static void dumpTypeName(raw_ostream &OS, const DWARFDie &D, bool SkipFirstParamIfArtificial = false);
-static DWARFDie dumpTypeNameBefore(raw_ostream &OS, DWARFDie D, bool *Word = nullptr);
+ }
-static void dumpPointerLikeTypeBefore(raw_ostream &OS, DWARFDie D, DWARFDie Inner, StringRef Ptr, bool *Word) {
- bool SubWord;
- dumpTypeNameBefore(OS, Inner, &SubWord);
+ void appendPointerLikeTypeBefore(DWARFDie D, DWARFDie Inner, StringRef Ptr) {
+ appendUnqualifiedTypeNameBefore(Inner);
bool NeedsParens =
Inner && (Inner.getTag() == llvm::dwarf::DW_TAG_subroutine_type ||
Inner.getTag() == llvm::dwarf::DW_TAG_array_type);
if (NeedsParens)
OS << '(';
- else if (SubWord)
+ else if (Word)
OS << ' ';
OS << Ptr;
- if (Word)
- *Word = false;
-}
-
-static DWARFDie dumpTypeNameBefore(raw_ostream &OS, DWARFDie D, bool *Word) {
- if (Word)
- *Word = true;
- if (!D) {
- OS << "void";
- return DWARFDie();
- }
- if (const char *Name = D.getName(DINameKind::LinkageName)) {
- OS << Name;
- return DWARFDie();
+ Word = false;
}
- DWARFDie Inner = D.getAttributeValueAsReferencedDie(DW_AT_type);
- const dwarf::Tag T = D.getTag();
- switch (T) {
- case DW_TAG_pointer_type: {
- dumpPointerLikeTypeBefore(OS, D, Inner, "*", Word);
- break;
- }
- case DW_TAG_subroutine_type: {
- bool SubWord;
- dumpTypeNameBefore(OS, Inner, &SubWord);
- if (SubWord) {
- OS << ' ';
+ DWARFDie appendUnqualifiedTypeNameBefore(DWARFDie D) {
+ Word = true;
+ if (!D) {
+ OS << "void";
+ return DWARFDie();
}
- if (Word)
- *Word = false;
- break;
- }
- case DW_TAG_array_type: {
- bool SubWord;
- dumpTypeNameBefore(OS, Inner, &SubWord);
- if (SubWord)
- OS << ' ';
- if (Word)
- *Word = false;
- break;
- }
- case DW_TAG_reference_type:
- dumpPointerLikeTypeBefore(OS, D, Inner, "&", Word);
- break;
- case DW_TAG_rvalue_reference_type:
- dumpPointerLikeTypeBefore(OS, D, Inner, "&&", Word);
- break;
- case DW_TAG_ptr_to_member_type: {
- bool SubWord;
- dumpTypeNameBefore(OS, Inner, &SubWord);
- bool NeedsParens =
- Inner && (Inner.getTag() == llvm::dwarf::DW_TAG_subroutine_type ||
- Inner.getTag() == llvm::dwarf::DW_TAG_array_type);
- if (NeedsParens)
- OS << '(';
- else if (SubWord)
- OS << ' ';
- if (DWARFDie Cont =
- D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) {
- dumpTypeName(OS, Cont);
- OS << "::";
+ if (const char *Name = D.getName(DINameKind::LinkageName)) {
+ OS << Name;
+ return DWARFDie();
}
- OS << "*";
- if (Word)
- *Word = false;
- break;
- }
- default:
- dumpTypeTagName(OS, T);
- dumpTypeNameBefore(OS, Inner);
- break;
- }
- return Inner;
-}
-static void dumpTypeNameAfter(raw_ostream &OS, DWARFDie D, DWARFDie Inner,
- bool SkipFirstParamIfArtificial = false) {
- if (!D)
- return;
- switch(D.getTag()) {
- case DW_TAG_subroutine_type: {
- OS << '(';
- bool First = true;
- bool RealFirst = true;
- for (const DWARFDie &C : D.children()) {
- if (C.getTag() == DW_TAG_formal_parameter) {
- if (SkipFirstParamIfArtificial && RealFirst &&
- C.find(DW_AT_artificial)) {
- RealFirst = false;
- continue;
- }
- if (!First)
- OS << ", ";
- First = false;
- dumpTypeName(OS, C.getAttributeValueAsReferencedDie(DW_AT_type));
+ DWARFDie Inner = D.getAttributeValueAsReferencedDie(DW_AT_type);
+ const dwarf::Tag T = D.getTag();
+ switch (T) {
+ case DW_TAG_pointer_type: {
+ appendPointerLikeTypeBefore(D, Inner, "*");
+ break;
+ }
+ case DW_TAG_subroutine_type: {
+ appendUnqualifiedTypeNameBefore(Inner);
+ if (Word) {
+ OS << ' ';
}
+ Word = false;
+ break;
}
- OS << ')';
- break;
- }
- case DW_TAG_array_type: {
- dumpArrayType(OS, D);
- break;
+ case DW_TAG_array_type: {
+ appendUnqualifiedTypeNameBefore(Inner);
+ if (Word)
+ OS << ' ';
+ Word = false;
+ break;
+ }
+ case DW_TAG_reference_type:
+ appendPointerLikeTypeBefore(D, Inner, "&");
+ break;
+ case DW_TAG_rvalue_reference_type:
+ appendPointerLikeTypeBefore(D, Inner, "&&");
+ break;
+ case DW_TAG_ptr_to_member_type: {
+ appendUnqualifiedTypeNameBefore(Inner);
+ bool NeedsParens =
+ Inner && (Inner.getTag() == llvm::dwarf::DW_TAG_subroutine_type ||
+ Inner.getTag() == llvm::dwarf::DW_TAG_array_type);
+ if (NeedsParens)
+ OS << '(';
+ else if (Word)
+ OS << ' ';
+ if (DWARFDie Cont =
+ D.getAttributeValueAsReferencedDie(DW_AT_containing_type)) {
+ appendUnqualifiedTypeName(Cont);
+ OS << "::";
+ }
+ OS << "*";
+ Word = false;
+ break;
+ }
+ default:
+ appendTypeTagName(T);
+ appendUnqualifiedTypeNameBefore(Inner);
+ break;
+ }
+ return Inner;
}
- case DW_TAG_ptr_to_member_type:
- case DW_TAG_reference_type:
- case DW_TAG_rvalue_reference_type:
- case DW_TAG_pointer_type: {
- bool NeedsParens =
- Inner && (Inner.getTag() == llvm::dwarf::DW_TAG_subroutine_type ||
- Inner.getTag() == llvm::dwarf::DW_TAG_array_type);
- if (NeedsParens)
+
+ void appendUnqualifiedTypeNameAfter(DWARFDie D, DWARFDie Inner,
+ bool SkipFirstParamIfArtificial = false) {
+ if (!D)
+ return;
+ switch (D.getTag()) {
+ case DW_TAG_subroutine_type: {
+ OS << '(';
+ bool First = true;
+ bool RealFirst = true;
+ for (const DWARFDie &C : D.children()) {
+ if (C.getTag() == DW_TAG_formal_parameter) {
+ if (SkipFirstParamIfArtificial && RealFirst &&
+ C.find(DW_AT_artificial)) {
+ RealFirst = false;
+ continue;
+ }
+ if (!First)
+ OS << ", ";
+ First = false;
+ appendUnqualifiedTypeName(
+ C.getAttributeValueAsReferencedDie(DW_AT_type));
+ }
+ }
OS << ')';
- dumpTypeNameAfter(OS, Inner, D.getAttributeValueAsReferencedDie(DW_AT_type),
- /*SkipFirstParamIfArtificial=*/D.getTag() ==
- DW_TAG_ptr_to_member_type);
- break;
- }
- default:
- break;
+ break;
+ }
+ case DW_TAG_array_type: {
+ appendArrayType(D);
+ break;
+ }
+ case DW_TAG_ptr_to_member_type:
+ case DW_TAG_reference_type:
+ case DW_TAG_rvalue_reference_type:
+ case DW_TAG_pointer_type: {
+ bool NeedsParens =
+ Inner && (Inner.getTag() == llvm::dwarf::DW_TAG_subroutine_type ||
+ Inner.getTag() == llvm::dwarf::DW_TAG_array_type);
+ if (NeedsParens)
+ OS << ')';
+ appendUnqualifiedTypeNameAfter(
+ Inner, D.getAttributeValueAsReferencedDie(DW_AT_type),
+ /*SkipFirstParamIfArtificial=*/D.getTag() ==
+ DW_TAG_ptr_to_member_type);
+ break;
+ }
+ default:
+ break;
+ }
}
-}
-/// Recursively dump the DIE type name when applicable.
-static void dumpTypeName(raw_ostream &OS, const DWARFDie &D, bool SkipFirstParamIfArtificial) {
- if (!D.isValid() || D.isNULL())
- return;
+ /// Recursively append the DIE type name when applicable.
+ void appendUnqualifiedTypeName(const DWARFDie &D,
+ bool SkipFirstParamIfArtificial = false) {
+ if (!D.isValid() || D.isNULL())
+ return;
- // FIXME: We should have pretty printers per language. Currently we print
- // everything as if it was C++ and fall back to the TAG type name.
- DWARFDie Inner = dumpTypeNameBefore(OS, D);
- dumpTypeNameAfter(OS, D, Inner, SkipFirstParamIfArtificial);
-}
+ // FIXME: We should have pretty printers per language. Currently we print
+ // everything as if it was C++ and fall back to the TAG type name.
+ DWARFDie Inner = appendUnqualifiedTypeNameBefore(D);
+ appendUnqualifiedTypeNameAfter(D, Inner, SkipFirstParamIfArtificial);
+ }
+};
+} // anonymous namespace
static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
const DWARFAttribute &AttrValue, unsigned Indent,
@@ -394,7 +398,8 @@ static void dumpAttribute(raw_ostream &OS, const DWARFDie &Die,
OS << Space << "\"" << Name << '\"';
} else if (Attr == DW_AT_type) {
OS << Space << "\"";
- dumpTypeName(OS, Die.getAttributeValueAsReferencedDie(FormValue));
+ DWARFTypePrinter(OS).appendUnqualifiedTypeName(
+ Die.getAttributeValueAsReferencedDie(FormValue));
OS << '"';
} else if (Attr == DW_AT_APPLE_property_attribute) {
if (Optional<uint64_t> OptVal = FormValue.getAsUnsignedConstant())
More information about the llvm-commits
mailing list