9 static constexpr StringRef Prefix =
"DW_TAG_";
10 static constexpr StringRef Suffix =
"_type";
14 TagStr.
size() - (Prefix.size() + Suffix.
size()))
20 if (
C.getTag() != DW_TAG_subrange_type)
22 std::optional<uint64_t> LB;
23 std::optional<uint64_t> Count;
24 std::optional<uint64_t> UB;
25 std::optional<unsigned> DefaultLB;
26 if (std::optional<DWARFFormValue> L =
C.find(DW_AT_lower_bound))
27 LB = L->getAsUnsignedConstant();
28 if (std::optional<DWARFFormValue> CountV =
C.find(DW_AT_count))
29 Count = CountV->getAsUnsignedConstant();
30 if (std::optional<DWARFFormValue> UpperV =
C.find(DW_AT_upper_bound))
31 UB = UpperV->getAsUnsignedConstant();
32 if (std::optional<DWARFFormValue> LV =
33 D.getDwarfUnit()->getUnitDIE().find(DW_AT_language))
34 if (std::optional<uint64_t> LC = LV->getAsUnsignedConstant())
37 if (LB && *LB == *DefaultLB)
39 if (!LB && !Count && !UB)
41 else if (!LB && (Count || UB) && DefaultLB)
42 OS <<
'[' << (Count ? *Count : *UB - *DefaultLB + 1) <<
']';
54 OS <<
"? + " << *Count;
67 return D.getAttributeValueAsReferencedDie(Attr).resolveTypeUnitReference();
70 return D.getAttributeValueAsReferencedDie(
F).resolveTypeUnitReference();
73 while (
D && (
D.getTag() == DW_TAG_const_type ||
74 D.getTag() == DW_TAG_volatile_type))
81 return D && (
D.getTag() == DW_TAG_subroutine_type ||
82 D.getTag() == DW_TAG_array_type);
99 std::string *OriginalFullName) {
109 case DW_TAG_pointer_type: {
113 case DW_TAG_subroutine_type: {
121 case DW_TAG_array_type: {
125 case DW_TAG_reference_type:
128 case DW_TAG_rvalue_reference_type:
131 case DW_TAG_ptr_to_member_type: {
146 case DW_TAG_LLVM_ptrauth_type:
149 case DW_TAG_const_type:
150 case DW_TAG_volatile_type:
153 case DW_TAG_namespace: {
157 OS <<
"(anonymous namespace)";
160 case DW_TAG_unspecified_type: {
162 if (TypeName ==
"decltype(nullptr)")
163 TypeName =
"std::nullptr_t";
183 static constexpr StringRef MangledPrefix =
"_STN|";
184 if (
Name.startswith(MangledPrefix)) {
186 auto Separator =
Name.find(
'|');
190 if (OriginalFullName)
199 if (
Name.endswith(
">"))
219 switch (
D.getTag()) {
220 case DW_TAG_subroutine_type: {
225 case DW_TAG_array_type: {
229 case DW_TAG_const_type:
230 case DW_TAG_volatile_type:
233 case DW_TAG_ptr_to_member_type:
234 case DW_TAG_reference_type:
235 case DW_TAG_rvalue_reference_type:
236 case DW_TAG_pointer_type: {
241 DW_TAG_ptr_to_member_type);
244 case DW_TAG_LLVM_ptrauth_type: {
246 if (
auto Form =
D.find(Attr))
247 return *
Form->getAsUnsignedConstant();
251 if (getValOrNull(DW_AT_LLVM_ptrauth_isa_pointer))
253 if (getValOrNull(DW_AT_LLVM_ptrauth_authenticates_null_values))
254 optionsVec.
push_back(
"authenticates-null-values");
256 for (
const auto *option : optionsVec) {
262 options =
", \"" + options +
"\"";
263 std::string PtrauthString;
266 <<
"__ptrauth(" << getValOrNull(DW_AT_LLVM_ptrauth_key) <<
", "
267 << getValOrNull(DW_AT_LLVM_ptrauth_address_discriminated) <<
", 0x0"
268 << utohexstr(getValOrNull(DW_AT_LLVM_ptrauth_extra_discriminator),
true)
270 OS << PtrauthStream.
str();
288 case dwarf::DW_TAG_structure_type:
289 case dwarf::DW_TAG_class_type:
290 case dwarf::DW_TAG_union_type:
291 case dwarf::DW_TAG_namespace:
292 case dwarf::DW_TAG_enumeration_type:
310 bool *FirstParameter) {
311 bool FirstParameterValue =
true;
312 bool IsTemplate =
false;
314 FirstParameter = &FirstParameterValue;
323 *FirstParameter =
false;
325 if (
C.getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
329 if (
C.getTag() == dwarf::DW_TAG_template_value_parameter) {
332 if (
T.getTag() == DW_TAG_enumeration_type) {
336 auto V =
C.find(DW_AT_const_value);
337 OS << std::to_string(*V->getAsSignedConstant());
343 if (
T.getTag() == DW_TAG_pointer_type)
348 auto V =
C.find(DW_AT_const_value);
349 bool IsQualifiedChar =
false;
350 if (
Name ==
"bool") {
351 OS << (*V->getAsUnsignedConstant() ?
"true" :
"false");
352 }
else if (
Name ==
"short") {
354 OS << std::to_string(*V->getAsSignedConstant());
355 }
else if (
Name ==
"unsigned short") {
356 OS <<
"(unsigned short)";
357 OS << std::to_string(*V->getAsSignedConstant());
358 }
else if (
Name ==
"int")
359 OS << std::to_string(*V->getAsSignedConstant());
360 else if (
Name ==
"long") {
361 OS << std::to_string(*V->getAsSignedConstant());
363 }
else if (
Name ==
"long long") {
364 OS << std::to_string(*V->getAsSignedConstant());
366 }
else if (
Name ==
"unsigned int") {
367 OS << std::to_string(*V->getAsUnsignedConstant());
369 }
else if (
Name ==
"unsigned long") {
370 OS << std::to_string(*V->getAsUnsignedConstant());
372 }
else if (
Name ==
"unsigned long long") {
373 OS << std::to_string(*V->getAsUnsignedConstant());
375 }
else if (
Name ==
"char" ||
377 (
Name ==
"unsigned char" ||
Name ==
"signed char"))) {
380 auto Val = *V->getAsSignedConstant();
385 if (IsQualifiedChar) {
420 if ((Val & ~0xFFu) == ~0xFFu)
422 if (Val < 127 && Val >= 32) {
426 }
else if (Val < 256)
428 else if (Val <= 0xFFFF)
436 if (
C.getTag() == dwarf::DW_TAG_GNU_template_template_param) {
437 const char *RawName =
445 if (
C.getTag() != dwarf::DW_TAG_template_type_parameter)
447 auto TypeAttr =
C.find(DW_AT_type);
452 if (IsTemplate && *FirstParameter && FirstParameter == &FirstParameterValue) {
460 (
N.getTag() == DW_TAG_const_type ?
C : V) =
N;
463 auto Tag =
T.getTag();
464 if (
Tag == DW_TAG_const_type) {
467 }
else if (
Tag == DW_TAG_volatile_type) {
478 if (
T &&
T.getTag() == DW_TAG_subroutine_type)
489 bool Subroutine =
T &&
T.getTag() == DW_TAG_subroutine_type;
491 while (
A &&
A.getTag() == DW_TAG_array_type)
494 (!
A || (
A.getTag() != DW_TAG_pointer_type &&
495 A.getTag() != llvm::dwarf::DW_TAG_ptr_to_member_type)) &&
504 if (!Leading && !Subroutine) {
516 std::string *OriginalFullName) {
529 bool RealFirst =
true;
531 if (
P.getTag() != DW_TAG_formal_parameter &&
532 P.getTag() != DW_TAG_unspecified_parameters)
535 if (SkipFirstParamIfArtificial && RealFirst &&
P.find(DW_AT_artificial)) {
536 FirstParamIfArtificial =
T;
544 if (
P.getTag() == DW_TAG_unspecified_parameters)
551 if (FirstParamIfArtificial) {
552 if (
DWARFDie P = FirstParamIfArtificial) {
553 if (
P.getTag() == DW_TAG_pointer_type) {
556 Const |= U.getTag() == DW_TAG_const_type;
557 Volatile |= U.getTag() == DW_TAG_volatile_type;
569 if (
auto CC =
D.find(DW_AT_calling_convention)) {
570 switch (*
CC->getAsUnsignedConstant()) {
571 case CallingConvention::DW_CC_BORLAND_stdcall:
572 OS <<
" __attribute__((stdcall))";
574 case CallingConvention::DW_CC_BORLAND_msfastcall:
575 OS <<
" __attribute__((fastcall))";
577 case CallingConvention::DW_CC_BORLAND_thiscall:
578 OS <<
" __attribute__((thiscall))";
580 case CallingConvention::DW_CC_LLVM_vectorcall:
581 OS <<
" __attribute__((vectorcall))";
583 case CallingConvention::DW_CC_BORLAND_pascal:
584 OS <<
" __attribute__((pascal))";
586 case CallingConvention::DW_CC_LLVM_Win64:
587 OS <<
" __attribute__((ms_abi))";
589 case CallingConvention::DW_CC_LLVM_X86_64SysV:
590 OS <<
" __attribute__((sysv_abi))";
592 case CallingConvention::DW_CC_LLVM_AAPCS:
594 OS <<
" __attribute__((pcs(\"aapcs\")))";
596 case CallingConvention::DW_CC_LLVM_AAPCS_VFP:
597 OS <<
" __attribute__((pcs(\"aapcs-vfp\")))";
599 case CallingConvention::DW_CC_LLVM_IntelOclBicc:
600 OS <<
" __attribute__((intel_ocl_bicc))";
602 case CallingConvention::DW_CC_LLVM_SpirFunction:
603 case CallingConvention::DW_CC_LLVM_OpenCLKernel:
610 case CallingConvention::DW_CC_LLVM_Swift:
612 OS <<
" __attribute__((swiftcall))";
614 case CallingConvention::DW_CC_LLVM_PreserveMost:
615 OS <<
" __attribute__((preserve_most))";
617 case CallingConvention::DW_CC_LLVM_PreserveAll:
618 OS <<
" __attribute__((preserve_all))";
620 case CallingConvention::DW_CC_LLVM_X86RegCall:
621 OS <<
" __attribute__((regcall))";
630 if (
D.find(DW_AT_reference))
632 if (
D.find(DW_AT_rvalue_reference))
638 if (
D.getTag() == DW_TAG_compile_unit)
640 if (
D.getTag() == DW_TAG_type_unit)
642 if (
D.getTag() == DW_TAG_skeleton_unit)
644 if (
D.getTag() == DW_TAG_subprogram)
646 if (
D.getTag() == DW_TAG_lexical_block)
648 D =
D.resolveTypeUnitReference();
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Utility class that carries the DWARF compile/type unit and the debug info entry in an object.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr size_t size() const
size - Get the string size.
bool startswith(StringRef Prefix) const
bool endswith(StringRef Suffix) const
static constexpr size_t npos
A raw_ostream that writes to an std::string.
std::string & str()
Returns the string's reference.
StringRef TagString(unsigned Tag)
@ C
The default llvm calling convention, compatible with C.
std::optional< unsigned > LanguageLowerBound(SourceLanguage L)
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
This is an optimization pass for GlobalISel generic memory operations.
std::string to_string(const T &Value)
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
static DWARFDie resolveReferencedType(DWARFDie D, dwarf::Attribute Attr=DW_AT_type)
static bool scopedTAGs(dwarf::Tag Tag)
Returns True if the DIE TAG is one of the ones that is scopped.
void appendQualifiedName(DWARFDie D)
void appendUnqualifiedNameAfter(DWARFDie D, DWARFDie Inner, bool SkipFirstParamIfArtificial=false)
void appendUnqualifiedName(DWARFDie D, std::string *OriginalFullName=nullptr)
Recursively append the DIE type name when applicable.
DWARFDie appendUnqualifiedNameBefore(DWARFDie D, std::string *OriginalFullName=nullptr)
void appendSubroutineNameAfter(DWARFDie D, DWARFDie Inner, bool SkipFirstParamIfArtificial, bool Const, bool Volatile)
bool appendTemplateParameters(DWARFDie D, bool *FirstParameter=nullptr)
bool needsParens(DWARFDie D)
void appendConstVolatileQualifierBefore(DWARFDie N)
void appendPointerLikeTypeBefore(DWARFDie D, DWARFDie Inner, StringRef Ptr)
DWARFDie appendQualifiedNameBefore(DWARFDie D)
void decomposeConstVolatile(DWARFDie &N, DWARFDie &T, DWARFDie &C, DWARFDie &V)
void appendConstVolatileQualifierAfter(DWARFDie N)
DWARFDie skipQualifiers(DWARFDie D)
void appendTypeTagName(dwarf::Tag T)
Dump the name encoded in the type tag.
void appendScopes(DWARFDie D)
void appendArrayType(const DWARFDie &D)