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)
362 auto V =
C.find(DW_AT_const_value);
363 bool IsQualifiedChar =
false;
364 if (
Name ==
"bool") {
365 OS << (*V->getAsUnsignedConstant() ?
"true" :
"false");
366 }
else if (
Name ==
"short") {
368 OS << std::to_string(*V->getAsSignedConstant());
369 }
else if (
Name ==
"unsigned short") {
370 OS <<
"(unsigned short)";
371 OS << std::to_string(*V->getAsSignedConstant());
372 }
else if (
Name ==
"int")
373 OS << std::to_string(*V->getAsSignedConstant());
374 else if (
Name ==
"long") {
375 OS << std::to_string(*V->getAsSignedConstant());
377 }
else if (
Name ==
"long long") {
378 OS << std::to_string(*V->getAsSignedConstant());
380 }
else if (
Name ==
"unsigned int") {
381 OS << std::to_string(*V->getAsUnsignedConstant());
383 }
else if (
Name ==
"unsigned long") {
384 OS << std::to_string(*V->getAsUnsignedConstant());
386 }
else if (
Name ==
"unsigned long long") {
387 OS << std::to_string(*V->getAsUnsignedConstant());
389 }
else if (
Name ==
"char" ||
391 (
Name ==
"unsigned char" ||
Name ==
"signed char"))) {
394 auto Val = *V->getAsSignedConstant();
399 if (IsQualifiedChar) {
434 if ((Val & ~0xFFu) == ~0xFFu)
436 if (Val < 127 && Val >= 32) {
440 }
else if (Val < 256)
442 else if (Val <= 0xFFFF)
450 if (
C.getTag() == dwarf::DW_TAG_GNU_template_template_param) {
451 const char *RawName =
459 if (
C.getTag() != dwarf::DW_TAG_template_type_parameter)
466 if (IsTemplate && *FirstParameter && FirstParameter == &FirstParameterValue) {
474 (
N.getTag() == DW_TAG_const_type ?
C : V) =
N;
477 auto Tag =
T.getTag();
478 if (
Tag == DW_TAG_const_type) {
481 }
else if (
Tag == DW_TAG_volatile_type) {
492 if (
T &&
T.getTag() == DW_TAG_subroutine_type)
503 bool Subroutine =
T &&
T.getTag() == DW_TAG_subroutine_type;
505 while (
A &&
A.getTag() == DW_TAG_array_type)
508 (!
A || (
A.getTag() != DW_TAG_pointer_type &&
509 A.getTag() != llvm::dwarf::DW_TAG_ptr_to_member_type)) &&
518 if (!Leading && !Subroutine) {
530 std::string *OriginalFullName) {
543 bool RealFirst =
true;
545 if (
P.getTag() != DW_TAG_formal_parameter &&
546 P.getTag() != DW_TAG_unspecified_parameters)
549 if (SkipFirstParamIfArtificial && RealFirst &&
P.find(DW_AT_artificial)) {
550 FirstParamIfArtificial =
T;
558 if (
P.getTag() == DW_TAG_unspecified_parameters)
565 if (FirstParamIfArtificial) {
566 if (
DWARFDie P = FirstParamIfArtificial) {
567 if (
P.getTag() == DW_TAG_pointer_type) {
570 Const |= U.getTag() == DW_TAG_const_type;
571 Volatile |= U.getTag() == DW_TAG_volatile_type;
583 if (
auto CC =
D.find(DW_AT_calling_convention)) {
584 switch (*
CC->getAsUnsignedConstant()) {
585 case CallingConvention::DW_CC_BORLAND_stdcall:
586 OS <<
" __attribute__((stdcall))";
588 case CallingConvention::DW_CC_BORLAND_msfastcall:
589 OS <<
" __attribute__((fastcall))";
591 case CallingConvention::DW_CC_BORLAND_thiscall:
592 OS <<
" __attribute__((thiscall))";
594 case CallingConvention::DW_CC_LLVM_vectorcall:
595 OS <<
" __attribute__((vectorcall))";
597 case CallingConvention::DW_CC_BORLAND_pascal:
598 OS <<
" __attribute__((pascal))";
600 case CallingConvention::DW_CC_LLVM_Win64:
601 OS <<
" __attribute__((ms_abi))";
603 case CallingConvention::DW_CC_LLVM_X86_64SysV:
604 OS <<
" __attribute__((sysv_abi))";
606 case CallingConvention::DW_CC_LLVM_AAPCS:
608 OS <<
" __attribute__((pcs(\"aapcs\")))";
610 case CallingConvention::DW_CC_LLVM_AAPCS_VFP:
611 OS <<
" __attribute__((pcs(\"aapcs-vfp\")))";
613 case CallingConvention::DW_CC_LLVM_IntelOclBicc:
614 OS <<
" __attribute__((intel_ocl_bicc))";
616 case CallingConvention::DW_CC_LLVM_SpirFunction:
617 case CallingConvention::DW_CC_LLVM_OpenCLKernel:
624 case CallingConvention::DW_CC_LLVM_Swift:
626 OS <<
" __attribute__((swiftcall))";
628 case CallingConvention::DW_CC_LLVM_PreserveMost:
629 OS <<
" __attribute__((preserve_most))";
631 case CallingConvention::DW_CC_LLVM_PreserveAll:
632 OS <<
" __attribute__((preserve_all))";
634 case CallingConvention::DW_CC_LLVM_PreserveNone:
635 OS <<
" __attribute__((preserve_none))";
637 case CallingConvention::DW_CC_LLVM_X86RegCall:
638 OS <<
" __attribute__((regcall))";
640 case CallingConvention::DW_CC_LLVM_M68kRTD:
641 OS <<
" __attribute__((m68k_rtd))";
650 if (
D.find(DW_AT_reference))
652 if (
D.find(DW_AT_rvalue_reference))
658 if (
D.getTag() == DW_TAG_compile_unit)
660 if (
D.getTag() == DW_TAG_type_unit)
662 if (
D.getTag() == DW_TAG_skeleton_unit)
664 if (
D.getTag() == DW_TAG_subprogram)
666 if (
D.getTag() == DW_TAG_lexical_block)
668 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)