9#ifndef LLVM_DEBUGINFO_DWARF_DWARFTYPEPRINTER_H 
   10#define LLVM_DEBUGINFO_DWARF_DWARFTYPEPRINTER_H 
   44                                      std::string *OriginalFullName = 
nullptr);
 
   47                                  bool SkipFirstParamIfArtificial = 
false);
 
   58                             std::string *OriginalFullName = 
nullptr);
 
   61                                 bool SkipFirstParamIfArtificial, 
bool Const,
 
   69    case dwarf::DW_TAG_structure_type:
 
   70    case dwarf::DW_TAG_class_type:
 
   71    case dwarf::DW_TAG_union_type:
 
   72    case dwarf::DW_TAG_namespace:
 
   73    case dwarf::DW_TAG_enumeration_type:
 
   74    case dwarf::DW_TAG_typedef:
 
 
   83template <
typename DieType>
 
   86  static constexpr StringRef Prefix = 
"DW_TAG_";
 
   87  static constexpr StringRef Suffix = 
"_type";
 
   91                      TagStr.
size() - (Prefix.size() + Suffix.
size()))
 
 
   95template <
typename DieType>
 
   97  for (
const DieType &
C : 
D.children()) {
 
   98    if (
C.getTag() != dwarf::DW_TAG_subrange_type)
 
  100    std::optional<uint64_t> LB;
 
  101    std::optional<uint64_t> 
Count;
 
  102    std::optional<uint64_t> UB;
 
  103    std::optional<unsigned> DefaultLB;
 
  104    if (std::optional<typename DieType::DWARFFormValue> L =
 
  105            C.find(dwarf::DW_AT_lower_bound))
 
  106      LB = L->getAsUnsignedConstant();
 
  107    if (std::optional<typename DieType::DWARFFormValue> CountV =
 
  108            C.find(dwarf::DW_AT_count))
 
  109      Count = CountV->getAsUnsignedConstant();
 
  110    if (std::optional<typename DieType::DWARFFormValue> UpperV =
 
  111            C.find(dwarf::DW_AT_upper_bound))
 
  112      UB = UpperV->getAsUnsignedConstant();
 
  113    if (std::optional<uint64_t> LV = 
D.getLanguage())
 
  116        if (LB && *LB == *DefaultLB)
 
  118    if (!LB && !
Count && !UB)
 
  120    else if (!LB && (
Count || UB) && DefaultLB)
 
  121      OS << 
'[' << (
Count ? *
Count : *UB - *DefaultLB + 1) << 
']';
 
 
  145template <
typename DieType>
 
  148  return D.resolveReferencedType(Attr);
 
 
  150template <
typename DieType>
 
  152  return D.resolveReferencedType(
F);
 
 
  154template <
typename DWARFFormValueType>
 
  155const char *
toString(std::optional<DWARFFormValueType> 
F) {
 
 
  166template <
typename DieType>
 
  168  while (
D && (
D.getTag() == dwarf::DW_TAG_const_type ||
 
  169               D.getTag() == dwarf::DW_TAG_volatile_type))
 
 
  174template <
typename DieType>
 
  177  return D && (
D.getTag() == dwarf::DW_TAG_subroutine_type ||
 
  178               D.getTag() == dwarf::DW_TAG_array_type);
 
 
  181template <
typename DieType>
 
  195template <
typename DieType>
 
  197    DieType 
D, std::string *OriginalFullName) {
 
  207  case dwarf::DW_TAG_pointer_type: {
 
  211  case dwarf::DW_TAG_subroutine_type: {
 
  219  case dwarf::DW_TAG_array_type: {
 
  223  case dwarf::DW_TAG_reference_type:
 
  226  case dwarf::DW_TAG_rvalue_reference_type:
 
  229  case dwarf::DW_TAG_ptr_to_member_type: {
 
  245  case dwarf::DW_TAG_LLVM_ptrauth_type:
 
  248  case dwarf::DW_TAG_const_type:
 
  249  case dwarf::DW_TAG_volatile_type:
 
  252  case dwarf::DW_TAG_namespace: {
 
  256      OS << 
"(anonymous namespace)";
 
  259  case dwarf::DW_TAG_unspecified_type: {
 
  261    if (TypeName == 
"decltype(nullptr)")
 
  262      TypeName = 
"std::nullptr_t";
 
  282    static constexpr StringRef MangledPrefix = 
"_STN|";
 
  283    if (Name.consume_front(MangledPrefix)) {
 
  284      auto Separator = Name.find(
'|');
 
  286      StringRef BaseName = Name.substr(0, Separator);
 
  288      if (OriginalFullName)
 
  297    if (Name.ends_with(
">"))
 
 
  313template <
typename DieType>
 
  315    DieType 
D, DieType Inner, 
bool SkipFirstParamIfArtificial) {
 
  318  switch (
D.getTag()) {
 
  319  case dwarf::DW_TAG_subroutine_type: {
 
  324  case dwarf::DW_TAG_array_type: {
 
  328  case dwarf::DW_TAG_const_type:
 
  329  case dwarf::DW_TAG_volatile_type:
 
  332  case dwarf::DW_TAG_ptr_to_member_type:
 
  333  case dwarf::DW_TAG_reference_type:
 
  334  case dwarf::DW_TAG_rvalue_reference_type:
 
  335  case dwarf::DW_TAG_pointer_type: {
 
  340                                   dwarf::DW_TAG_ptr_to_member_type);
 
  343  case dwarf::DW_TAG_LLVM_ptrauth_type: {
 
  345      if (
auto Form = 
D.find(Attr))
 
  346        return *Form->getAsUnsignedConstant();
 
  350    if (getValOrNull(dwarf::DW_AT_LLVM_ptrauth_isa_pointer))
 
  352    if (getValOrNull(dwarf::DW_AT_LLVM_ptrauth_authenticates_null_values))
 
  353      optionsVec.
push_back(
"authenticates-null-values");
 
  354    if (
auto AuthenticationMode =
 
  355            D.find(dwarf::DW_AT_LLVM_ptrauth_authentication_mode)) {
 
  356      switch (*AuthenticationMode->getAsUnsignedConstant()) {
 
  370    for (
const auto *option : optionsVec) {
 
  376      options = 
", \"" + options + 
"\"";
 
  377    std::string PtrauthString;
 
  380        << 
"__ptrauth(" << getValOrNull(dwarf::DW_AT_LLVM_ptrauth_key) << 
", " 
  381        << getValOrNull(dwarf::DW_AT_LLVM_ptrauth_address_discriminated)
 
  384               getValOrNull(dwarf::DW_AT_LLVM_ptrauth_extra_discriminator),
 
  387    OS << PtrauthStream.
str();
 
 
  402template <
typename DieType>
 
  404  if (
D && scopedTAGs(
D.getTag()))
 
 
  409template <
typename DieType>
 
  411  if (
D && scopedTAGs(
D.getTag()))
 
 
  416template <
typename DieType>
 
  418                                                         bool *FirstParameter) {
 
  419  bool FirstParameterValue = 
true;
 
  420  bool IsTemplate = 
false;
 
  422    FirstParameter = &FirstParameterValue;
 
  423  for (
const DieType &
C : 
D) {
 
  431      *FirstParameter = 
false;
 
  433    if (
C.getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
 
  437    if (
C.getTag() == dwarf::DW_TAG_template_value_parameter) {
 
  440      if (
T.getTag() == dwarf::DW_TAG_enumeration_type) {
 
  444        auto V = 
C.find(dwarf::DW_AT_const_value);
 
  445        OS << std::to_string(*V->getAsSignedConstant());
 
  451      if (
T.getTag() == dwarf::DW_TAG_pointer_type ||
 
  452          T.getTag() == dwarf::DW_TAG_reference_type)
 
  457      auto V = 
C.find(dwarf::DW_AT_const_value);
 
  458      bool IsQualifiedChar = 
false;
 
  459      if (Name == 
"bool") {
 
  460        OS << (*V->getAsUnsignedConstant() ? 
"true" : 
"false");
 
  461      } 
else if (Name == 
"short") {
 
  463        OS << std::to_string(*V->getAsSignedConstant());
 
  464      } 
else if (Name == 
"unsigned short") {
 
  465        OS << 
"(unsigned short)";
 
  466        OS << std::to_string(*V->getAsSignedConstant());
 
  467      } 
else if (Name == 
"int")
 
  468        OS << std::to_string(*V->getAsSignedConstant());
 
  469      else if (Name == 
"long") {
 
  470        OS << std::to_string(*V->getAsSignedConstant());
 
  472      } 
else if (Name == 
"long long") {
 
  473        OS << std::to_string(*V->getAsSignedConstant());
 
  475      } 
else if (Name == 
"unsigned int") {
 
  476        OS << std::to_string(*V->getAsUnsignedConstant());
 
  478      } 
else if (Name == 
"unsigned long") {
 
  479        OS << std::to_string(*V->getAsUnsignedConstant());
 
  481      } 
else if (Name == 
"unsigned long long") {
 
  482        OS << std::to_string(*V->getAsUnsignedConstant());
 
  484      } 
else if (Name == 
"char" ||
 
  486                      (Name == 
"unsigned char" || Name == 
"signed char"))) {
 
  489        auto Val = *V->getAsSignedConstant();
 
  494        if (IsQualifiedChar) {
 
  529          if ((Val & ~0xFFu) == ~0xFFu)
 
  531          if (Val < 127 && Val >= 32) {
 
  535          } 
else if (Val < 256)
 
  537          else if (Val <= 0xFFFF)
 
  545    if (
C.getTag() == dwarf::DW_TAG_GNU_template_template_param) {
 
  546      const char *RawName =
 
  554    if (
C.getTag() != dwarf::DW_TAG_template_type_parameter)
 
  556    auto TypeAttr = 
C.find(dwarf::DW_AT_type);
 
  561  if (IsTemplate && *FirstParameter && FirstParameter == &FirstParameterValue) {
 
 
  568template <
typename DieType>
 
  582template <
typename DieType>
 
  584                                                       DieType &
C, DieType &V) {
 
  585  (
N.getTag() == dwarf::DW_TAG_const_type ? 
C : V) = 
N;
 
  588    auto Tag = 
T.getTag();
 
  589    if (
Tag == dwarf::DW_TAG_const_type) {
 
  592    } 
else if (
Tag == dwarf::DW_TAG_volatile_type) {
 
 
  599template <
typename DieType>
 
  605  if (
T && 
T.getTag() == dwarf::DW_TAG_subroutine_type)
 
  607                              static_cast<bool>(
C), 
static_cast<bool>(V));
 
 
  612template <
typename DieType>
 
  618  bool Subroutine = 
T && 
T.getTag() == dwarf::DW_TAG_subroutine_type;
 
  620  while (
A && 
A.getTag() == dwarf::DW_TAG_array_type)
 
  623      (!
A || (
A.getTag() != dwarf::DW_TAG_pointer_type &&
 
  624              A.getTag() != llvm::dwarf::DW_TAG_ptr_to_member_type)) &&
 
  633  if (!Leading && !Subroutine) {
 
 
  645template <
typename DieType>
 
  647    DieType 
D, std::string *OriginalFullName) {
 
 
  654template <
typename DieType>
 
  656    DieType 
D, DieType Inner, 
bool SkipFirstParamIfArtificial, 
bool Const,
 
  658  DieType FirstParamIfArtificial;
 
  662  bool RealFirst = 
true;
 
  663  for (DieType 
P : 
D) {
 
  664    if (
P.getTag() != dwarf::DW_TAG_formal_parameter &&
 
  665        P.getTag() != dwarf::DW_TAG_unspecified_parameters)
 
  668    if (SkipFirstParamIfArtificial && RealFirst &&
 
  669        P.find(dwarf::DW_AT_artificial)) {
 
  670      FirstParamIfArtificial = 
T;
 
  678    if (
P.getTag() == dwarf::DW_TAG_unspecified_parameters)
 
  685  if (FirstParamIfArtificial) {
 
  686    if (DieType 
P = FirstParamIfArtificial) {
 
  687      if (
P.getTag() == dwarf::DW_TAG_pointer_type) {
 
  688        auto CVStep = [&](DieType CV) {
 
  690            Const |= U.getTag() == dwarf::DW_TAG_const_type;
 
  691            Volatile |= U.getTag() == dwarf::DW_TAG_volatile_type;
 
  696        if (DieType CV = CVStep(
P)) {
 
  703  if (
auto CC = 
D.find(dwarf::DW_AT_calling_convention)) {
 
  704    switch (*CC->getAsUnsignedConstant()) {
 
  705    case dwarf::CallingConvention::DW_CC_BORLAND_stdcall:
 
  706      OS << 
" __attribute__((stdcall))";
 
  708    case dwarf::CallingConvention::DW_CC_BORLAND_msfastcall:
 
  709      OS << 
" __attribute__((fastcall))";
 
  711    case dwarf::CallingConvention::DW_CC_BORLAND_thiscall:
 
  712      OS << 
" __attribute__((thiscall))";
 
  714    case dwarf::CallingConvention::DW_CC_LLVM_vectorcall:
 
  715      OS << 
" __attribute__((vectorcall))";
 
  717    case dwarf::CallingConvention::DW_CC_BORLAND_pascal:
 
  718      OS << 
" __attribute__((pascal))";
 
  720    case dwarf::CallingConvention::DW_CC_LLVM_Win64:
 
  721      OS << 
" __attribute__((ms_abi))";
 
  723    case dwarf::CallingConvention::DW_CC_LLVM_X86_64SysV:
 
  724      OS << 
" __attribute__((sysv_abi))";
 
  726    case dwarf::CallingConvention::DW_CC_LLVM_AAPCS:
 
  728      OS << 
" __attribute__((pcs(\"aapcs\")))";
 
  730    case dwarf::CallingConvention::DW_CC_LLVM_AAPCS_VFP:
 
  731      OS << 
" __attribute__((pcs(\"aapcs-vfp\")))";
 
  733    case dwarf::CallingConvention::DW_CC_LLVM_IntelOclBicc:
 
  734      OS << 
" __attribute__((intel_ocl_bicc))";
 
  736    case dwarf::CallingConvention::DW_CC_LLVM_SpirFunction:
 
  743    case dwarf::CallingConvention::DW_CC_LLVM_DeviceKernel:
 
  744      OS << 
" __attribute__((device_kernel))";
 
  746    case dwarf::CallingConvention::DW_CC_LLVM_Swift:
 
  748      OS << 
" __attribute__((swiftcall))";
 
  750    case dwarf::CallingConvention::DW_CC_LLVM_PreserveMost:
 
  751      OS << 
" __attribute__((preserve_most))";
 
  753    case dwarf::CallingConvention::DW_CC_LLVM_PreserveAll:
 
  754      OS << 
" __attribute__((preserve_all))";
 
  756    case dwarf::CallingConvention::DW_CC_LLVM_PreserveNone:
 
  757      OS << 
" __attribute__((preserve_none))";
 
  759    case dwarf::CallingConvention::DW_CC_LLVM_X86RegCall:
 
  760      OS << 
" __attribute__((regcall))";
 
  762    case dwarf::CallingConvention::DW_CC_LLVM_M68kRTD:
 
  763      OS << 
" __attribute__((m68k_rtd))";
 
  772  if (
D.find(dwarf::DW_AT_reference))
 
  774  if (
D.find(dwarf::DW_AT_rvalue_reference))
 
 
  780template <
typename DieType>
 
  782  if (
D.getTag() == dwarf::DW_TAG_compile_unit)
 
  784  if (
D.getTag() == dwarf::DW_TAG_type_unit)
 
  786  if (
D.getTag() == dwarf::DW_TAG_skeleton_unit)
 
  788  if (
D.getTag() == dwarf::DW_TAG_subprogram)
 
  790  if (
D.getTag() == dwarf::DW_TAG_lexical_block)
 
  792  D = 
D.resolveTypeUnitReference();
 
  793  if (DieType 
P = 
D.getParent())
 
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
 
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
 
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
 
This file contains constants used for implementing Dwarf debug support.
 
static dwarf::Attribute TypeAttr[]
 
Tagged union holding either a T or a Error.
 
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.
 
static constexpr size_t npos
 
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.
 
This class implements an extremely fast bulk output stream that can only output to a stream.
 
A raw_ostream that writes to an std::string.
 
std::string & str()
Returns the string's reference.
 
@ C
The default llvm calling convention, compatible with C.
 
const char * toString(std::optional< DWARFFormValueType > F)
 
DieType resolveReferencedType(DieType D, dwarf::Attribute Attr=dwarf::DW_AT_type)
 
This is an optimization pass for GlobalISel generic memory operations.
 
std::string utohexstr(uint64_t X, bool LowerCase=false, unsigned Width=0)
 
FunctionAddr VTableAddr Count
 
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.
 
void consumeError(Error Err)
Consume a Error without doing anything.
 
void appendTypeTagName(dwarf::Tag T)
Dump the name encoded in the type tag.
 
bool needsParens(DieType D)
 
void appendArrayType(const DieType &D)
 
DieType appendQualifiedNameBefore(DieType D)
 
void appendQualifiedName(DieType D)
 
void decomposeConstVolatile(DieType &N, DieType &T, DieType &C, DieType &V)
 
DieType skipQualifiers(DieType D)
 
void appendUnqualifiedName(DieType D, std::string *OriginalFullName=nullptr)
Recursively append the DIE type name when applicable.
 
void appendConstVolatileQualifierBefore(DieType N)
 
void appendScopes(DieType D)
 
DWARFTypePrinter(raw_ostream &OS)
 
void appendSubroutineNameAfter(DieType D, DieType Inner, bool SkipFirstParamIfArtificial, bool Const, bool Volatile)
 
bool appendTemplateParameters(DieType D, bool *FirstParameter=nullptr)
 
void appendConstVolatileQualifierAfter(DieType N)
 
void appendAndTerminateTemplateParameters(DieType D)
 
void appendPointerLikeTypeBefore(DieType D, DieType Inner, StringRef Ptr)
 
void appendUnqualifiedNameAfter(DieType D, DieType Inner, bool SkipFirstParamIfArtificial=false)
 
DieType appendUnqualifiedNameBefore(DieType D, std::string *OriginalFullName=nullptr)