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.consume_front(MangledPrefix)) {
185 auto Separator =
Name.find(
'|');
189 if (OriginalFullName)
198 if (
Name.ends_with(
">"))
218 switch (
D.getTag()) {
219 case DW_TAG_subroutine_type: {
224 case DW_TAG_array_type: {
228 case DW_TAG_const_type:
229 case DW_TAG_volatile_type:
232 case DW_TAG_ptr_to_member_type:
233 case DW_TAG_reference_type:
234 case DW_TAG_rvalue_reference_type:
235 case DW_TAG_pointer_type: {
240 DW_TAG_ptr_to_member_type);
243 case DW_TAG_LLVM_ptrauth_type: {
245 if (
auto Form =
D.find(Attr))
246 return *
Form->getAsUnsignedConstant();
250 if (getValOrNull(DW_AT_LLVM_ptrauth_isa_pointer))
252 if (getValOrNull(DW_AT_LLVM_ptrauth_authenticates_null_values))
253 optionsVec.
push_back(
"authenticates-null-values");
254 if (
auto AuthenticationMode =
255 D.find(DW_AT_LLVM_ptrauth_authentication_mode)) {
256 switch (*AuthenticationMode->getAsUnsignedConstant()) {
270 for (
const auto *option : optionsVec) {
276 options =
", \"" + options +
"\"";
277 std::string PtrauthString;
280 <<
"__ptrauth(" << getValOrNull(DW_AT_LLVM_ptrauth_key) <<
", "
281 << getValOrNull(DW_AT_LLVM_ptrauth_address_discriminated) <<
", 0x0"
282 << utohexstr(getValOrNull(DW_AT_LLVM_ptrauth_extra_discriminator),
true)
284 OS << PtrauthStream.
str();
302 case dwarf::DW_TAG_structure_type:
303 case dwarf::DW_TAG_class_type:
304 case dwarf::DW_TAG_union_type:
305 case dwarf::DW_TAG_namespace:
306 case dwarf::DW_TAG_enumeration_type:
324 bool *FirstParameter) {
325 bool FirstParameterValue =
true;
326 bool IsTemplate =
false;
328 FirstParameter = &FirstParameterValue;
337 *FirstParameter =
false;
339 if (
C.getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
343 if (
C.getTag() == dwarf::DW_TAG_template_value_parameter) {
346 if (
T.getTag() == DW_TAG_enumeration_type) {
350 auto V =
C.find(DW_AT_const_value);
351 OS << std::to_string(*V->getAsSignedConstant());
357 if (
T.getTag() == DW_TAG_pointer_type ||
358 T.getTag() == DW_TAG_reference_type)
363 auto V =
C.find(DW_AT_const_value);
364 bool IsQualifiedChar =
false;
365 if (
Name ==
"bool") {
366 OS << (*V->getAsUnsignedConstant() ?
"true" :
"false");
367 }
else if (
Name ==
"short") {
369 OS << std::to_string(*V->getAsSignedConstant());
370 }
else if (
Name ==
"unsigned short") {
371 OS <<
"(unsigned short)";
372 OS << std::to_string(*V->getAsSignedConstant());
373 }
else if (
Name ==
"int")
374 OS << std::to_string(*V->getAsSignedConstant());
375 else if (
Name ==
"long") {
376 OS << std::to_string(*V->getAsSignedConstant());
378 }
else if (
Name ==
"long long") {
379 OS << std::to_string(*V->getAsSignedConstant());
381 }
else if (
Name ==
"unsigned int") {
382 OS << std::to_string(*V->getAsUnsignedConstant());
384 }
else if (
Name ==
"unsigned long") {
385 OS << std::to_string(*V->getAsUnsignedConstant());
387 }
else if (
Name ==
"unsigned long long") {
388 OS << std::to_string(*V->getAsUnsignedConstant());
390 }
else if (
Name ==
"char" ||
392 (
Name ==
"unsigned char" ||
Name ==
"signed char"))) {
395 auto Val = *V->getAsSignedConstant();
400 if (IsQualifiedChar) {
435 if ((Val & ~0xFFu) == ~0xFFu)
437 if (Val < 127 && Val >= 32) {
441 }
else if (Val < 256)
443 else if (Val <= 0xFFFF)
451 if (
C.getTag() == dwarf::DW_TAG_GNU_template_template_param) {
452 const char *RawName =
460 if (
C.getTag() != dwarf::DW_TAG_template_type_parameter)
467 if (IsTemplate && *FirstParameter && FirstParameter == &FirstParameterValue) {
475 (
N.getTag() == DW_TAG_const_type ?
C : V) =
N;
478 auto Tag =
T.getTag();
479 if (
Tag == DW_TAG_const_type) {
482 }
else if (
Tag == DW_TAG_volatile_type) {
493 if (
T &&
T.getTag() == DW_TAG_subroutine_type)
504 bool Subroutine =
T &&
T.getTag() == DW_TAG_subroutine_type;
506 while (
A &&
A.getTag() == DW_TAG_array_type)
509 (!
A || (
A.getTag() != DW_TAG_pointer_type &&
510 A.getTag() != llvm::dwarf::DW_TAG_ptr_to_member_type)) &&
519 if (!Leading && !Subroutine) {
531 std::string *OriginalFullName) {
544 bool RealFirst =
true;
546 if (
P.getTag() != DW_TAG_formal_parameter &&
547 P.getTag() != DW_TAG_unspecified_parameters)
550 if (SkipFirstParamIfArtificial && RealFirst &&
P.find(DW_AT_artificial)) {
551 FirstParamIfArtificial =
T;
559 if (
P.getTag() == DW_TAG_unspecified_parameters)
566 if (FirstParamIfArtificial) {
567 if (
DWARFDie P = FirstParamIfArtificial) {
568 if (
P.getTag() == DW_TAG_pointer_type) {
571 Const |= U.getTag() == DW_TAG_const_type;
572 Volatile |= U.getTag() == DW_TAG_volatile_type;
584 if (
auto CC =
D.find(DW_AT_calling_convention)) {
585 switch (*
CC->getAsUnsignedConstant()) {
586 case CallingConvention::DW_CC_BORLAND_stdcall:
587 OS <<
" __attribute__((stdcall))";
589 case CallingConvention::DW_CC_BORLAND_msfastcall:
590 OS <<
" __attribute__((fastcall))";
592 case CallingConvention::DW_CC_BORLAND_thiscall:
593 OS <<
" __attribute__((thiscall))";
595 case CallingConvention::DW_CC_LLVM_vectorcall:
596 OS <<
" __attribute__((vectorcall))";
598 case CallingConvention::DW_CC_BORLAND_pascal:
599 OS <<
" __attribute__((pascal))";
601 case CallingConvention::DW_CC_LLVM_Win64:
602 OS <<
" __attribute__((ms_abi))";
604 case CallingConvention::DW_CC_LLVM_X86_64SysV:
605 OS <<
" __attribute__((sysv_abi))";
607 case CallingConvention::DW_CC_LLVM_AAPCS:
609 OS <<
" __attribute__((pcs(\"aapcs\")))";
611 case CallingConvention::DW_CC_LLVM_AAPCS_VFP:
612 OS <<
" __attribute__((pcs(\"aapcs-vfp\")))";
614 case CallingConvention::DW_CC_LLVM_IntelOclBicc:
615 OS <<
" __attribute__((intel_ocl_bicc))";
617 case CallingConvention::DW_CC_LLVM_SpirFunction:
618 case CallingConvention::DW_CC_LLVM_OpenCLKernel:
625 case CallingConvention::DW_CC_LLVM_Swift:
627 OS <<
" __attribute__((swiftcall))";
629 case CallingConvention::DW_CC_LLVM_PreserveMost:
630 OS <<
" __attribute__((preserve_most))";
632 case CallingConvention::DW_CC_LLVM_PreserveAll:
633 OS <<
" __attribute__((preserve_all))";
635 case CallingConvention::DW_CC_LLVM_PreserveNone:
636 OS <<
" __attribute__((preserve_none))";
638 case CallingConvention::DW_CC_LLVM_X86RegCall:
639 OS <<
" __attribute__((regcall))";
641 case CallingConvention::DW_CC_LLVM_M68kRTD:
642 OS <<
" __attribute__((m68k_rtd))";
651 if (
D.find(DW_AT_reference))
653 if (
D.find(DW_AT_rvalue_reference))
659 if (
D.getTag() == DW_TAG_compile_unit)
661 if (
D.getTag() == DW_TAG_type_unit)
663 if (
D.getTag() == DW_TAG_skeleton_unit)
665 if (
D.getTag() == DW_TAG_subprogram)
667 if (
D.getTag() == DW_TAG_lexical_block)
669 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())
static dwarf::Attribute TypeAttr[]
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).
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
constexpr size_t size() const
size - Get the string size.
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
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.
format_object< Ts... > format(const char *Fmt, const Ts &... Vals)
These are helper functions used to produce formatted output.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
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)