xref: /freebsd/contrib/llvm-project/llvm/lib/DebugInfo/DWARF/DWARFTypePrinter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 #include "llvm/DebugInfo/DWARF/DWARFTypePrinter.h"
2 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
3 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
4 #include "llvm/Support/ScopedPrinter.h"
5 namespace llvm {
6 using namespace dwarf;
appendTypeTagName(dwarf::Tag T)7 void DWARFTypePrinter::appendTypeTagName(dwarf::Tag T) {
8   StringRef TagStr = TagString(T);
9   static constexpr StringRef Prefix = "DW_TAG_";
10   static constexpr StringRef Suffix = "_type";
11   if (!TagStr.starts_with(Prefix) || !TagStr.ends_with(Suffix))
12     return;
13   OS << TagStr.substr(Prefix.size(),
14                       TagStr.size() - (Prefix.size() + Suffix.size()))
15      << " ";
16 }
17 
appendArrayType(const DWARFDie & D)18 void DWARFTypePrinter::appendArrayType(const DWARFDie &D) {
19   for (const DWARFDie &C : D.children()) {
20     if (C.getTag() != DW_TAG_subrange_type)
21       continue;
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())
35         if ((DefaultLB =
36                  LanguageLowerBound(static_cast<dwarf::SourceLanguage>(*LC))))
37           if (LB && *LB == *DefaultLB)
38             LB = std::nullopt;
39     if (!LB && !Count && !UB)
40       OS << "[]";
41     else if (!LB && (Count || UB) && DefaultLB)
42       OS << '[' << (Count ? *Count : *UB - *DefaultLB + 1) << ']';
43     else {
44       OS << "[[";
45       if (LB)
46         OS << *LB;
47       else
48         OS << '?';
49       OS << ", ";
50       if (Count)
51         if (LB)
52           OS << *LB + *Count;
53         else
54           OS << "? + " << *Count;
55       else if (UB)
56         OS << *UB + 1;
57       else
58         OS << '?';
59       OS << ")]";
60     }
61   }
62   EndedWithTemplate = false;
63 }
64 
resolveReferencedType(DWARFDie D,dwarf::Attribute Attr=DW_AT_type)65 static DWARFDie resolveReferencedType(DWARFDie D,
66                                       dwarf::Attribute Attr = DW_AT_type) {
67   return D.getAttributeValueAsReferencedDie(Attr).resolveTypeUnitReference();
68 }
resolveReferencedType(DWARFDie D,DWARFFormValue F)69 static DWARFDie resolveReferencedType(DWARFDie D, DWARFFormValue F) {
70   return D.getAttributeValueAsReferencedDie(F).resolveTypeUnitReference();
71 }
skipQualifiers(DWARFDie D)72 DWARFDie DWARFTypePrinter::skipQualifiers(DWARFDie D) {
73   while (D && (D.getTag() == DW_TAG_const_type ||
74                D.getTag() == DW_TAG_volatile_type))
75     D = resolveReferencedType(D);
76   return D;
77 }
78 
needsParens(DWARFDie D)79 bool DWARFTypePrinter::needsParens(DWARFDie D) {
80   D = skipQualifiers(D);
81   return D && (D.getTag() == DW_TAG_subroutine_type ||
82                D.getTag() == DW_TAG_array_type);
83 }
84 
appendPointerLikeTypeBefore(DWARFDie D,DWARFDie Inner,StringRef Ptr)85 void DWARFTypePrinter::appendPointerLikeTypeBefore(DWARFDie D, DWARFDie Inner,
86                                                    StringRef Ptr) {
87   appendQualifiedNameBefore(Inner);
88   if (Word)
89     OS << ' ';
90   if (needsParens(Inner))
91     OS << '(';
92   OS << Ptr;
93   Word = false;
94   EndedWithTemplate = false;
95 }
96 
97 DWARFDie
appendUnqualifiedNameBefore(DWARFDie D,std::string * OriginalFullName)98 DWARFTypePrinter::appendUnqualifiedNameBefore(DWARFDie D,
99                                               std::string *OriginalFullName) {
100   Word = true;
101   if (!D) {
102     OS << "void";
103     return DWARFDie();
104   }
105   DWARFDie InnerDIE;
106   auto Inner = [&] { return InnerDIE = resolveReferencedType(D); };
107   const dwarf::Tag T = D.getTag();
108   switch (T) {
109   case DW_TAG_pointer_type: {
110     appendPointerLikeTypeBefore(D, Inner(), "*");
111     break;
112   }
113   case DW_TAG_subroutine_type: {
114     appendQualifiedNameBefore(Inner());
115     if (Word) {
116       OS << ' ';
117     }
118     Word = false;
119     break;
120   }
121   case DW_TAG_array_type: {
122     appendQualifiedNameBefore(Inner());
123     break;
124   }
125   case DW_TAG_reference_type:
126     appendPointerLikeTypeBefore(D, Inner(), "&");
127     break;
128   case DW_TAG_rvalue_reference_type:
129     appendPointerLikeTypeBefore(D, Inner(), "&&");
130     break;
131   case DW_TAG_ptr_to_member_type: {
132     appendQualifiedNameBefore(Inner());
133     if (needsParens(InnerDIE))
134       OS << '(';
135     else if (Word)
136       OS << ' ';
137     if (DWARFDie Cont = resolveReferencedType(D, DW_AT_containing_type)) {
138       appendQualifiedName(Cont);
139       EndedWithTemplate = false;
140       OS << "::";
141     }
142     OS << "*";
143     Word = false;
144     break;
145   }
146   case DW_TAG_LLVM_ptrauth_type:
147     appendQualifiedNameBefore(Inner());
148     break;
149   case DW_TAG_const_type:
150   case DW_TAG_volatile_type:
151     appendConstVolatileQualifierBefore(D);
152     break;
153   case DW_TAG_namespace: {
154     if (const char *Name = dwarf::toString(D.find(DW_AT_name), nullptr))
155       OS << Name;
156     else
157       OS << "(anonymous namespace)";
158     break;
159   }
160   case DW_TAG_unspecified_type: {
161     StringRef TypeName = D.getShortName();
162     if (TypeName == "decltype(nullptr)")
163       TypeName = "std::nullptr_t";
164     Word = true;
165     OS << TypeName;
166     EndedWithTemplate = false;
167     break;
168   }
169     /*
170   case DW_TAG_structure_type:
171   case DW_TAG_class_type:
172   case DW_TAG_enumeration_type:
173   case DW_TAG_base_type:
174   */
175   default: {
176     const char *NamePtr = dwarf::toString(D.find(DW_AT_name), nullptr);
177     if (!NamePtr) {
178       appendTypeTagName(D.getTag());
179       return DWARFDie();
180     }
181     Word = true;
182     StringRef Name = NamePtr;
183     static constexpr StringRef MangledPrefix = "_STN|";
184     if (Name.consume_front(MangledPrefix)) {
185       auto Separator = Name.find('|');
186       assert(Separator != StringRef::npos);
187       StringRef BaseName = Name.substr(0, Separator);
188       StringRef TemplateArgs = Name.substr(Separator + 1);
189       if (OriginalFullName)
190         *OriginalFullName = (BaseName + TemplateArgs).str();
191       Name = BaseName;
192     } else
193       EndedWithTemplate = Name.ends_with(">");
194     OS << Name;
195     // This check would be insufficient for operator overloads like
196     // "operator>>" - but for now Clang doesn't try to simplify them, so this
197     // is OK. Add more nuanced operator overload handling here if/when needed.
198     if (Name.ends_with(">"))
199       break;
200     if (!appendTemplateParameters(D))
201       break;
202 
203     if (EndedWithTemplate)
204       OS << ' ';
205     OS << '>';
206     EndedWithTemplate = true;
207     Word = true;
208     break;
209   }
210   }
211   return InnerDIE;
212 }
213 
appendUnqualifiedNameAfter(DWARFDie D,DWARFDie Inner,bool SkipFirstParamIfArtificial)214 void DWARFTypePrinter::appendUnqualifiedNameAfter(
215     DWARFDie D, DWARFDie Inner, bool SkipFirstParamIfArtificial) {
216   if (!D)
217     return;
218   switch (D.getTag()) {
219   case DW_TAG_subroutine_type: {
220     appendSubroutineNameAfter(D, Inner, SkipFirstParamIfArtificial, false,
221                               false);
222     break;
223   }
224   case DW_TAG_array_type: {
225     appendArrayType(D);
226     break;
227   }
228   case DW_TAG_const_type:
229   case DW_TAG_volatile_type:
230     appendConstVolatileQualifierAfter(D);
231     break;
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: {
236     if (needsParens(Inner))
237       OS << ')';
238     appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner),
239                                /*SkipFirstParamIfArtificial=*/D.getTag() ==
240                                    DW_TAG_ptr_to_member_type);
241     break;
242   }
243   case DW_TAG_LLVM_ptrauth_type: {
244     auto getValOrNull = [&](dwarf::Attribute Attr) -> uint64_t {
245       if (auto Form = D.find(Attr))
246         return *Form->getAsUnsignedConstant();
247       return 0;
248     };
249     SmallVector<const char *, 2> optionsVec;
250     if (getValOrNull(DW_AT_LLVM_ptrauth_isa_pointer))
251       optionsVec.push_back("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()) {
257       case 0:
258       case 1:
259         optionsVec.push_back("strip");
260         break;
261       case 2:
262         optionsVec.push_back("sign-and-strip");
263         break;
264       default:
265         // Default authentication policy
266         break;
267       }
268     }
269     std::string options;
270     for (const auto *option : optionsVec) {
271       if (options.size())
272         options += ",";
273       options += option;
274     }
275     if (options.size())
276       options = ", \"" + options + "\"";
277     std::string PtrauthString;
278     llvm::raw_string_ostream PtrauthStream(PtrauthString);
279     PtrauthStream
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)
283         << options << ")";
284     OS << PtrauthStream.str();
285     break;
286   }
287     /*
288   case DW_TAG_structure_type:
289   case DW_TAG_class_type:
290   case DW_TAG_enumeration_type:
291   case DW_TAG_base_type:
292   case DW_TAG_namespace:
293   */
294   default:
295     break;
296   }
297 }
298 
299 /// Returns True if the DIE TAG is one of the ones that is scopped.
scopedTAGs(dwarf::Tag Tag)300 static bool scopedTAGs(dwarf::Tag Tag) {
301   switch (Tag) {
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:
307     return true;
308   default:
309     break;
310   }
311   return false;
312 }
appendQualifiedName(DWARFDie D)313 void DWARFTypePrinter::appendQualifiedName(DWARFDie D) {
314   if (D && scopedTAGs(D.getTag()))
315     appendScopes(D.getParent());
316   appendUnqualifiedName(D);
317 }
appendQualifiedNameBefore(DWARFDie D)318 DWARFDie DWARFTypePrinter::appendQualifiedNameBefore(DWARFDie D) {
319   if (D && scopedTAGs(D.getTag()))
320     appendScopes(D.getParent());
321   return appendUnqualifiedNameBefore(D);
322 }
appendTemplateParameters(DWARFDie D,bool * FirstParameter)323 bool DWARFTypePrinter::appendTemplateParameters(DWARFDie D,
324                                                 bool *FirstParameter) {
325   bool FirstParameterValue = true;
326   bool IsTemplate = false;
327   if (!FirstParameter)
328     FirstParameter = &FirstParameterValue;
329   for (const DWARFDie &C : D) {
330     auto Sep = [&] {
331       if (*FirstParameter)
332         OS << '<';
333       else
334         OS << ", ";
335       IsTemplate = true;
336       EndedWithTemplate = false;
337       *FirstParameter = false;
338     };
339     if (C.getTag() == dwarf::DW_TAG_GNU_template_parameter_pack) {
340       IsTemplate = true;
341       appendTemplateParameters(C, FirstParameter);
342     }
343     if (C.getTag() == dwarf::DW_TAG_template_value_parameter) {
344       DWARFDie T = resolveReferencedType(C);
345       Sep();
346       if (T.getTag() == DW_TAG_enumeration_type) {
347         OS << '(';
348         appendQualifiedName(T);
349         OS << ')';
350         auto V = C.find(DW_AT_const_value);
351         OS << std::to_string(*V->getAsSignedConstant());
352         continue;
353       }
354       // /Maybe/ we could do pointer/reference type parameters, looking for the
355       // symbol in the ELF symbol table to get back to the variable...
356       // but probably not worth it.
357       if (T.getTag() == DW_TAG_pointer_type ||
358           T.getTag() == DW_TAG_reference_type)
359         continue;
360       const char *RawName = dwarf::toString(T.find(DW_AT_name), nullptr);
361       assert(RawName);
362       StringRef Name = RawName;
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") {
368         OS << "(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());
377         OS << "L";
378       } else if (Name == "long long") {
379         OS << std::to_string(*V->getAsSignedConstant());
380         OS << "LL";
381       } else if (Name == "unsigned int") {
382         OS << std::to_string(*V->getAsUnsignedConstant());
383         OS << "U";
384       } else if (Name == "unsigned long") {
385         OS << std::to_string(*V->getAsUnsignedConstant());
386         OS << "UL";
387       } else if (Name == "unsigned long long") {
388         OS << std::to_string(*V->getAsUnsignedConstant());
389         OS << "ULL";
390       } else if (Name == "char" ||
391                  (IsQualifiedChar =
392                       (Name == "unsigned char" || Name == "signed char"))) {
393         // FIXME: check T's DW_AT_type to see if it's signed or not (since
394         // char signedness is implementation defined).
395         auto Val = *V->getAsSignedConstant();
396         // Copied/hacked up from Clang's CharacterLiteral::print - incomplete
397         // (doesn't actually support different character types/widths, sign
398         // handling's not done, and doesn't correctly test if a character is
399         // printable or needs to use a numeric escape sequence instead)
400         if (IsQualifiedChar) {
401           OS << '(';
402           OS << Name;
403           OS << ')';
404         }
405         switch (Val) {
406         case '\\':
407           OS << "'\\\\'";
408           break;
409         case '\'':
410           OS << "'\\''";
411           break;
412         case '\a':
413           // TODO: K&R: the meaning of '\\a' is different in traditional C
414           OS << "'\\a'";
415           break;
416         case '\b':
417           OS << "'\\b'";
418           break;
419         case '\f':
420           OS << "'\\f'";
421           break;
422         case '\n':
423           OS << "'\\n'";
424           break;
425         case '\r':
426           OS << "'\\r'";
427           break;
428         case '\t':
429           OS << "'\\t'";
430           break;
431         case '\v':
432           OS << "'\\v'";
433           break;
434         default:
435           if ((Val & ~0xFFu) == ~0xFFu)
436             Val &= 0xFFu;
437           if (Val < 127 && Val >= 32) {
438             OS << "'";
439             OS << (char)Val;
440             OS << "'";
441           } else if (Val < 256)
442             OS << llvm::format("'\\x%02" PRIx64 "'", Val);
443           else if (Val <= 0xFFFF)
444             OS << llvm::format("'\\u%04" PRIx64 "'", Val);
445           else
446             OS << llvm::format("'\\U%08" PRIx64 "'", Val);
447         }
448       }
449       continue;
450     }
451     if (C.getTag() == dwarf::DW_TAG_GNU_template_template_param) {
452       const char *RawName =
453           dwarf::toString(C.find(DW_AT_GNU_template_name), nullptr);
454       assert(RawName);
455       StringRef Name = RawName;
456       Sep();
457       OS << Name;
458       continue;
459     }
460     if (C.getTag() != dwarf::DW_TAG_template_type_parameter)
461       continue;
462     auto TypeAttr = C.find(DW_AT_type);
463     Sep();
464     appendQualifiedName(TypeAttr ? resolveReferencedType(C, *TypeAttr)
465                                  : DWARFDie());
466   }
467   if (IsTemplate && *FirstParameter && FirstParameter == &FirstParameterValue) {
468     OS << '<';
469     EndedWithTemplate = false;
470   }
471   return IsTemplate;
472 }
decomposeConstVolatile(DWARFDie & N,DWARFDie & T,DWARFDie & C,DWARFDie & V)473 void DWARFTypePrinter::decomposeConstVolatile(DWARFDie &N, DWARFDie &T,
474                                               DWARFDie &C, DWARFDie &V) {
475   (N.getTag() == DW_TAG_const_type ? C : V) = N;
476   T = resolveReferencedType(N);
477   if (T) {
478     auto Tag = T.getTag();
479     if (Tag == DW_TAG_const_type) {
480       C = T;
481       T = resolveReferencedType(T);
482     } else if (Tag == DW_TAG_volatile_type) {
483       V = T;
484       T = resolveReferencedType(T);
485     }
486   }
487 }
appendConstVolatileQualifierAfter(DWARFDie N)488 void DWARFTypePrinter::appendConstVolatileQualifierAfter(DWARFDie N) {
489   DWARFDie C;
490   DWARFDie V;
491   DWARFDie T;
492   decomposeConstVolatile(N, T, C, V);
493   if (T && T.getTag() == DW_TAG_subroutine_type)
494     appendSubroutineNameAfter(T, resolveReferencedType(T), false, C.isValid(),
495                               V.isValid());
496   else
497     appendUnqualifiedNameAfter(T, resolveReferencedType(T));
498 }
appendConstVolatileQualifierBefore(DWARFDie N)499 void DWARFTypePrinter::appendConstVolatileQualifierBefore(DWARFDie N) {
500   DWARFDie C;
501   DWARFDie V;
502   DWARFDie T;
503   decomposeConstVolatile(N, T, C, V);
504   bool Subroutine = T && T.getTag() == DW_TAG_subroutine_type;
505   DWARFDie A = T;
506   while (A && A.getTag() == DW_TAG_array_type)
507     A = resolveReferencedType(A);
508   bool Leading =
509       (!A || (A.getTag() != DW_TAG_pointer_type &&
510               A.getTag() != llvm::dwarf::DW_TAG_ptr_to_member_type)) &&
511       !Subroutine;
512   if (Leading) {
513     if (C)
514       OS << "const ";
515     if (V)
516       OS << "volatile ";
517   }
518   appendQualifiedNameBefore(T);
519   if (!Leading && !Subroutine) {
520     Word = true;
521     if (C)
522       OS << "const";
523     if (V) {
524       if (C)
525         OS << ' ';
526       OS << "volatile";
527     }
528   }
529 }
appendUnqualifiedName(DWARFDie D,std::string * OriginalFullName)530 void DWARFTypePrinter::appendUnqualifiedName(DWARFDie D,
531                                              std::string *OriginalFullName) {
532   // FIXME: We should have pretty printers per language. Currently we print
533   // everything as if it was C++ and fall back to the TAG type name.
534   DWARFDie Inner = appendUnqualifiedNameBefore(D, OriginalFullName);
535   appendUnqualifiedNameAfter(D, Inner);
536 }
appendSubroutineNameAfter(DWARFDie D,DWARFDie Inner,bool SkipFirstParamIfArtificial,bool Const,bool Volatile)537 void DWARFTypePrinter::appendSubroutineNameAfter(
538     DWARFDie D, DWARFDie Inner, bool SkipFirstParamIfArtificial, bool Const,
539     bool Volatile) {
540   DWARFDie FirstParamIfArtificial;
541   OS << '(';
542   EndedWithTemplate = false;
543   bool First = true;
544   bool RealFirst = true;
545   for (DWARFDie P : D) {
546     if (P.getTag() != DW_TAG_formal_parameter &&
547         P.getTag() != DW_TAG_unspecified_parameters)
548       return;
549     DWARFDie T = resolveReferencedType(P);
550     if (SkipFirstParamIfArtificial && RealFirst && P.find(DW_AT_artificial)) {
551       FirstParamIfArtificial = T;
552       RealFirst = false;
553       continue;
554     }
555     if (!First) {
556       OS << ", ";
557     }
558     First = false;
559     if (P.getTag() == DW_TAG_unspecified_parameters)
560       OS << "...";
561     else
562       appendQualifiedName(T);
563   }
564   EndedWithTemplate = false;
565   OS << ')';
566   if (FirstParamIfArtificial) {
567     if (DWARFDie P = FirstParamIfArtificial) {
568       if (P.getTag() == DW_TAG_pointer_type) {
569         auto CVStep = [&](DWARFDie CV) {
570           if (DWARFDie U = resolveReferencedType(CV)) {
571             Const |= U.getTag() == DW_TAG_const_type;
572             Volatile |= U.getTag() == DW_TAG_volatile_type;
573             return U;
574           }
575           return DWARFDie();
576         };
577         if (DWARFDie CV = CVStep(P)) {
578           CVStep(CV);
579         }
580       }
581     }
582   }
583 
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))";
588       break;
589     case CallingConvention::DW_CC_BORLAND_msfastcall:
590       OS << " __attribute__((fastcall))";
591       break;
592     case CallingConvention::DW_CC_BORLAND_thiscall:
593       OS << " __attribute__((thiscall))";
594       break;
595     case CallingConvention::DW_CC_LLVM_vectorcall:
596       OS << " __attribute__((vectorcall))";
597       break;
598     case CallingConvention::DW_CC_BORLAND_pascal:
599       OS << " __attribute__((pascal))";
600       break;
601     case CallingConvention::DW_CC_LLVM_Win64:
602       OS << " __attribute__((ms_abi))";
603       break;
604     case CallingConvention::DW_CC_LLVM_X86_64SysV:
605       OS << " __attribute__((sysv_abi))";
606       break;
607     case CallingConvention::DW_CC_LLVM_AAPCS:
608       // AArch64VectorCall missing?
609       OS << " __attribute__((pcs(\"aapcs\")))";
610       break;
611     case CallingConvention::DW_CC_LLVM_AAPCS_VFP:
612       OS << " __attribute__((pcs(\"aapcs-vfp\")))";
613       break;
614     case CallingConvention::DW_CC_LLVM_IntelOclBicc:
615       OS << " __attribute__((intel_ocl_bicc))";
616       break;
617     case CallingConvention::DW_CC_LLVM_SpirFunction:
618     case CallingConvention::DW_CC_LLVM_OpenCLKernel:
619       // These aren't available as attributes, but maybe we should still
620       // render them somehow? (Clang doesn't render them, but that's an issue
621       // for template names too - since then the DWARF names of templates
622       // instantiated with function types with these calling conventions won't
623       // have distinct names - so we'd need to fix that too)
624       break;
625     case CallingConvention::DW_CC_LLVM_Swift:
626       // SwiftAsync missing
627       OS << " __attribute__((swiftcall))";
628       break;
629     case CallingConvention::DW_CC_LLVM_PreserveMost:
630       OS << " __attribute__((preserve_most))";
631       break;
632     case CallingConvention::DW_CC_LLVM_PreserveAll:
633       OS << " __attribute__((preserve_all))";
634       break;
635     case CallingConvention::DW_CC_LLVM_PreserveNone:
636       OS << " __attribute__((preserve_none))";
637       break;
638     case CallingConvention::DW_CC_LLVM_X86RegCall:
639       OS << " __attribute__((regcall))";
640       break;
641     case CallingConvention::DW_CC_LLVM_M68kRTD:
642       OS << " __attribute__((m68k_rtd))";
643       break;
644     }
645   }
646 
647   if (Const)
648     OS << " const";
649   if (Volatile)
650     OS << " volatile";
651   if (D.find(DW_AT_reference))
652     OS << " &";
653   if (D.find(DW_AT_rvalue_reference))
654     OS << " &&";
655 
656   appendUnqualifiedNameAfter(Inner, resolveReferencedType(Inner));
657 }
appendScopes(DWARFDie D)658 void DWARFTypePrinter::appendScopes(DWARFDie D) {
659   if (D.getTag() == DW_TAG_compile_unit)
660     return;
661   if (D.getTag() == DW_TAG_type_unit)
662     return;
663   if (D.getTag() == DW_TAG_skeleton_unit)
664     return;
665   if (D.getTag() == DW_TAG_subprogram)
666     return;
667   if (D.getTag() == DW_TAG_lexical_block)
668     return;
669   D = D.resolveTypeUnitReference();
670   if (DWARFDie P = D.getParent())
671     appendScopes(P);
672   appendUnqualifiedName(D);
673   OS << "::";
674 }
675 } // namespace llvm
676