xref: /freebsd/contrib/llvm-project/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
10b57cec5SDimitry Andric //===- MicrosoftDemangle.cpp ----------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines a demangler for MSVC-style mangled symbols.
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #include "llvm/Demangle/MicrosoftDemangleNodes.h"
140b57cec5SDimitry Andric #include "llvm/Demangle/DemangleConfig.h"
150b57cec5SDimitry Andric #include "llvm/Demangle/Utility.h"
160b57cec5SDimitry Andric #include <cctype>
170b57cec5SDimitry Andric #include <string>
180b57cec5SDimitry Andric 
190b57cec5SDimitry Andric using namespace llvm;
200b57cec5SDimitry Andric using namespace ms_demangle;
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric #define OUTPUT_ENUM_CLASS_VALUE(Enum, Value, Desc)                             \
230b57cec5SDimitry Andric   case Enum::Value:                                                            \
240b57cec5SDimitry Andric     OS << Desc;                                                                \
250b57cec5SDimitry Andric     break;
260b57cec5SDimitry Andric 
270b57cec5SDimitry Andric // Writes a space if the last token does not end with a punctuation.
280b57cec5SDimitry Andric static void outputSpaceIfNecessary(OutputStream &OS) {
290b57cec5SDimitry Andric   if (OS.empty())
300b57cec5SDimitry Andric     return;
310b57cec5SDimitry Andric 
320b57cec5SDimitry Andric   char C = OS.back();
330b57cec5SDimitry Andric   if (std::isalnum(C) || C == '>')
340b57cec5SDimitry Andric     OS << " ";
350b57cec5SDimitry Andric }
360b57cec5SDimitry Andric 
370b57cec5SDimitry Andric static void outputSingleQualifier(OutputStream &OS, Qualifiers Q) {
380b57cec5SDimitry Andric   switch (Q) {
390b57cec5SDimitry Andric   case Q_Const:
400b57cec5SDimitry Andric     OS << "const";
410b57cec5SDimitry Andric     break;
420b57cec5SDimitry Andric   case Q_Volatile:
430b57cec5SDimitry Andric     OS << "volatile";
440b57cec5SDimitry Andric     break;
450b57cec5SDimitry Andric   case Q_Restrict:
460b57cec5SDimitry Andric     OS << "__restrict";
470b57cec5SDimitry Andric     break;
480b57cec5SDimitry Andric   default:
490b57cec5SDimitry Andric     break;
500b57cec5SDimitry Andric   }
510b57cec5SDimitry Andric }
520b57cec5SDimitry Andric 
530b57cec5SDimitry Andric static bool outputQualifierIfPresent(OutputStream &OS, Qualifiers Q,
540b57cec5SDimitry Andric                                      Qualifiers Mask, bool NeedSpace) {
550b57cec5SDimitry Andric   if (!(Q & Mask))
560b57cec5SDimitry Andric     return NeedSpace;
570b57cec5SDimitry Andric 
580b57cec5SDimitry Andric   if (NeedSpace)
590b57cec5SDimitry Andric     OS << " ";
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric   outputSingleQualifier(OS, Mask);
620b57cec5SDimitry Andric   return true;
630b57cec5SDimitry Andric }
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric static void outputQualifiers(OutputStream &OS, Qualifiers Q, bool SpaceBefore,
660b57cec5SDimitry Andric                              bool SpaceAfter) {
670b57cec5SDimitry Andric   if (Q == Q_None)
680b57cec5SDimitry Andric     return;
690b57cec5SDimitry Andric 
700b57cec5SDimitry Andric   size_t Pos1 = OS.getCurrentPosition();
710b57cec5SDimitry Andric   SpaceBefore = outputQualifierIfPresent(OS, Q, Q_Const, SpaceBefore);
720b57cec5SDimitry Andric   SpaceBefore = outputQualifierIfPresent(OS, Q, Q_Volatile, SpaceBefore);
730b57cec5SDimitry Andric   SpaceBefore = outputQualifierIfPresent(OS, Q, Q_Restrict, SpaceBefore);
740b57cec5SDimitry Andric   size_t Pos2 = OS.getCurrentPosition();
750b57cec5SDimitry Andric   if (SpaceAfter && Pos2 > Pos1)
760b57cec5SDimitry Andric     OS << " ";
770b57cec5SDimitry Andric }
780b57cec5SDimitry Andric 
790b57cec5SDimitry Andric static void outputCallingConvention(OutputStream &OS, CallingConv CC) {
800b57cec5SDimitry Andric   outputSpaceIfNecessary(OS);
810b57cec5SDimitry Andric 
820b57cec5SDimitry Andric   switch (CC) {
830b57cec5SDimitry Andric   case CallingConv::Cdecl:
840b57cec5SDimitry Andric     OS << "__cdecl";
850b57cec5SDimitry Andric     break;
860b57cec5SDimitry Andric   case CallingConv::Fastcall:
870b57cec5SDimitry Andric     OS << "__fastcall";
880b57cec5SDimitry Andric     break;
890b57cec5SDimitry Andric   case CallingConv::Pascal:
900b57cec5SDimitry Andric     OS << "__pascal";
910b57cec5SDimitry Andric     break;
920b57cec5SDimitry Andric   case CallingConv::Regcall:
930b57cec5SDimitry Andric     OS << "__regcall";
940b57cec5SDimitry Andric     break;
950b57cec5SDimitry Andric   case CallingConv::Stdcall:
960b57cec5SDimitry Andric     OS << "__stdcall";
970b57cec5SDimitry Andric     break;
980b57cec5SDimitry Andric   case CallingConv::Thiscall:
990b57cec5SDimitry Andric     OS << "__thiscall";
1000b57cec5SDimitry Andric     break;
1010b57cec5SDimitry Andric   case CallingConv::Eabi:
1020b57cec5SDimitry Andric     OS << "__eabi";
1030b57cec5SDimitry Andric     break;
1040b57cec5SDimitry Andric   case CallingConv::Vectorcall:
1050b57cec5SDimitry Andric     OS << "__vectorcall";
1060b57cec5SDimitry Andric     break;
1070b57cec5SDimitry Andric   case CallingConv::Clrcall:
1080b57cec5SDimitry Andric     OS << "__clrcall";
1090b57cec5SDimitry Andric     break;
110*fe6060f1SDimitry Andric   case CallingConv::Swift:
111*fe6060f1SDimitry Andric     OS << "__attribute__((__swiftcall__)) ";
112*fe6060f1SDimitry Andric     break;
113*fe6060f1SDimitry Andric   case CallingConv::SwiftAsync:
114*fe6060f1SDimitry Andric     OS << "__attribute__((__swiftasynccall__)) ";
115*fe6060f1SDimitry Andric     break;
1160b57cec5SDimitry Andric   default:
1170b57cec5SDimitry Andric     break;
1180b57cec5SDimitry Andric   }
1190b57cec5SDimitry Andric }
1200b57cec5SDimitry Andric 
1210b57cec5SDimitry Andric std::string Node::toString(OutputFlags Flags) const {
1220b57cec5SDimitry Andric   OutputStream OS;
1230b57cec5SDimitry Andric   initializeOutputStream(nullptr, nullptr, OS, 1024);
1240b57cec5SDimitry Andric   this->output(OS, Flags);
1250b57cec5SDimitry Andric   OS << '\0';
126*fe6060f1SDimitry Andric   std::string Owned(OS.getBuffer());
127*fe6060f1SDimitry Andric   std::free(OS.getBuffer());
128*fe6060f1SDimitry Andric   return Owned;
1290b57cec5SDimitry Andric }
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric void PrimitiveTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
1320b57cec5SDimitry Andric   switch (PrimKind) {
1330b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Void, "void");
1340b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Bool, "bool");
1350b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char, "char");
1360b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Schar, "signed char");
1370b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uchar, "unsigned char");
1380b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char8, "char8_t");
1390b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char16, "char16_t");
1400b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char32, "char32_t");
1410b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Short, "short");
1420b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ushort, "unsigned short");
1430b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Int, "int");
1440b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uint, "unsigned int");
1450b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Long, "long");
1460b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ulong, "unsigned long");
1470b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Int64, "__int64");
1480b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uint64, "unsigned __int64");
1490b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Wchar, "wchar_t");
1500b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Float, "float");
1510b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Double, "double");
1520b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ldouble, "long double");
1530b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Nullptr, "std::nullptr_t");
1540b57cec5SDimitry Andric   }
1550b57cec5SDimitry Andric   outputQualifiers(OS, Quals, true, false);
1560b57cec5SDimitry Andric }
1570b57cec5SDimitry Andric 
1580b57cec5SDimitry Andric void NodeArrayNode::output(OutputStream &OS, OutputFlags Flags) const {
1590b57cec5SDimitry Andric   output(OS, Flags, ", ");
1600b57cec5SDimitry Andric }
1610b57cec5SDimitry Andric 
1620b57cec5SDimitry Andric void NodeArrayNode::output(OutputStream &OS, OutputFlags Flags,
1630b57cec5SDimitry Andric                            StringView Separator) const {
1640b57cec5SDimitry Andric   if (Count == 0)
1650b57cec5SDimitry Andric     return;
1660b57cec5SDimitry Andric   if (Nodes[0])
1670b57cec5SDimitry Andric     Nodes[0]->output(OS, Flags);
1680b57cec5SDimitry Andric   for (size_t I = 1; I < Count; ++I) {
1690b57cec5SDimitry Andric     OS << Separator;
1700b57cec5SDimitry Andric     Nodes[I]->output(OS, Flags);
1710b57cec5SDimitry Andric   }
1720b57cec5SDimitry Andric }
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric void EncodedStringLiteralNode::output(OutputStream &OS,
1750b57cec5SDimitry Andric                                       OutputFlags Flags) const {
1760b57cec5SDimitry Andric   switch (Char) {
1770b57cec5SDimitry Andric   case CharKind::Wchar:
1780b57cec5SDimitry Andric     OS << "L\"";
1790b57cec5SDimitry Andric     break;
1800b57cec5SDimitry Andric   case CharKind::Char:
1810b57cec5SDimitry Andric     OS << "\"";
1820b57cec5SDimitry Andric     break;
1830b57cec5SDimitry Andric   case CharKind::Char16:
1840b57cec5SDimitry Andric     OS << "u\"";
1850b57cec5SDimitry Andric     break;
1860b57cec5SDimitry Andric   case CharKind::Char32:
1870b57cec5SDimitry Andric     OS << "U\"";
1880b57cec5SDimitry Andric     break;
1890b57cec5SDimitry Andric   }
1900b57cec5SDimitry Andric   OS << DecodedString << "\"";
1910b57cec5SDimitry Andric   if (IsTruncated)
1920b57cec5SDimitry Andric     OS << "...";
1930b57cec5SDimitry Andric }
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric void IntegerLiteralNode::output(OutputStream &OS, OutputFlags Flags) const {
1960b57cec5SDimitry Andric   if (IsNegative)
1970b57cec5SDimitry Andric     OS << '-';
1980b57cec5SDimitry Andric   OS << Value;
1990b57cec5SDimitry Andric }
2000b57cec5SDimitry Andric 
2010b57cec5SDimitry Andric void TemplateParameterReferenceNode::output(OutputStream &OS,
2020b57cec5SDimitry Andric                                             OutputFlags Flags) const {
2030b57cec5SDimitry Andric   if (ThunkOffsetCount > 0)
2040b57cec5SDimitry Andric     OS << "{";
2050b57cec5SDimitry Andric   else if (Affinity == PointerAffinity::Pointer)
2060b57cec5SDimitry Andric     OS << "&";
2070b57cec5SDimitry Andric 
2080b57cec5SDimitry Andric   if (Symbol) {
2090b57cec5SDimitry Andric     Symbol->output(OS, Flags);
2100b57cec5SDimitry Andric     if (ThunkOffsetCount > 0)
2110b57cec5SDimitry Andric       OS << ", ";
2120b57cec5SDimitry Andric   }
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   if (ThunkOffsetCount > 0)
2150b57cec5SDimitry Andric     OS << ThunkOffsets[0];
2160b57cec5SDimitry Andric   for (int I = 1; I < ThunkOffsetCount; ++I) {
2170b57cec5SDimitry Andric     OS << ", " << ThunkOffsets[I];
2180b57cec5SDimitry Andric   }
2190b57cec5SDimitry Andric   if (ThunkOffsetCount > 0)
2200b57cec5SDimitry Andric     OS << "}";
2210b57cec5SDimitry Andric }
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric void IdentifierNode::outputTemplateParameters(OutputStream &OS,
2240b57cec5SDimitry Andric                                               OutputFlags Flags) const {
2250b57cec5SDimitry Andric   if (!TemplateParams)
2260b57cec5SDimitry Andric     return;
2270b57cec5SDimitry Andric   OS << "<";
2280b57cec5SDimitry Andric   TemplateParams->output(OS, Flags);
2290b57cec5SDimitry Andric   OS << ">";
2300b57cec5SDimitry Andric }
2310b57cec5SDimitry Andric 
2320b57cec5SDimitry Andric void DynamicStructorIdentifierNode::output(OutputStream &OS,
2330b57cec5SDimitry Andric                                            OutputFlags Flags) const {
2340b57cec5SDimitry Andric   if (IsDestructor)
2350b57cec5SDimitry Andric     OS << "`dynamic atexit destructor for ";
2360b57cec5SDimitry Andric   else
2370b57cec5SDimitry Andric     OS << "`dynamic initializer for ";
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric   if (Variable) {
2400b57cec5SDimitry Andric     OS << "`";
2410b57cec5SDimitry Andric     Variable->output(OS, Flags);
2420b57cec5SDimitry Andric     OS << "''";
2430b57cec5SDimitry Andric   } else {
2440b57cec5SDimitry Andric     OS << "'";
2450b57cec5SDimitry Andric     Name->output(OS, Flags);
2460b57cec5SDimitry Andric     OS << "''";
2470b57cec5SDimitry Andric   }
2480b57cec5SDimitry Andric }
2490b57cec5SDimitry Andric 
2500b57cec5SDimitry Andric void NamedIdentifierNode::output(OutputStream &OS, OutputFlags Flags) const {
2510b57cec5SDimitry Andric   OS << Name;
2520b57cec5SDimitry Andric   outputTemplateParameters(OS, Flags);
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric void IntrinsicFunctionIdentifierNode::output(OutputStream &OS,
2560b57cec5SDimitry Andric                                              OutputFlags Flags) const {
2570b57cec5SDimitry Andric   switch (Operator) {
2580b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, New, "operator new");
2590b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Delete, "operator delete");
2600b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Assign, "operator=");
2610b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, RightShift, "operator>>");
2620b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LeftShift, "operator<<");
2630b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalNot, "operator!");
2640b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Equals, "operator==");
2650b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, NotEquals, "operator!=");
2660b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArraySubscript,
2670b57cec5SDimitry Andric                             "operator[]");
2680b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Pointer, "operator->");
2690b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Increment, "operator++");
2700b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Decrement, "operator--");
2710b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Minus, "operator-");
2720b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Plus, "operator+");
2730b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Dereference, "operator*");
2740b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseAnd, "operator&");
2750b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, MemberPointer,
2760b57cec5SDimitry Andric                             "operator->*");
2770b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Divide, "operator/");
2780b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Modulus, "operator%");
2790b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LessThan, "operator<");
2800b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LessThanEqual, "operator<=");
2810b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, GreaterThan, "operator>");
2820b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, GreaterThanEqual,
2830b57cec5SDimitry Andric                             "operator>=");
2840b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Comma, "operator,");
2850b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Parens, "operator()");
2860b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseNot, "operator~");
2870b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseXor, "operator^");
2880b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseOr, "operator|");
2890b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalAnd, "operator&&");
2900b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalOr, "operator||");
2910b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, TimesEqual, "operator*=");
2920b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, PlusEqual, "operator+=");
2930b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, MinusEqual, "operator-=");
2940b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, DivEqual, "operator/=");
2950b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ModEqual, "operator%=");
2960b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, RshEqual, "operator>>=");
2970b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LshEqual, "operator<<=");
2980b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseAndEqual,
2990b57cec5SDimitry Andric                             "operator&=");
3000b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseOrEqual,
3010b57cec5SDimitry Andric                             "operator|=");
3020b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseXorEqual,
3030b57cec5SDimitry Andric                             "operator^=");
3040b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VbaseDtor, "`vbase dtor'");
3050b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecDelDtor,
3060b57cec5SDimitry Andric                             "`vector deleting dtor'");
3070b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, DefaultCtorClosure,
3080b57cec5SDimitry Andric                             "`default ctor closure'");
3090b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ScalarDelDtor,
3100b57cec5SDimitry Andric                             "`scalar deleting dtor'");
3110b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecCtorIter,
3120b57cec5SDimitry Andric                             "`vector ctor iterator'");
3130b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecDtorIter,
3140b57cec5SDimitry Andric                             "`vector dtor iterator'");
3150b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecVbaseCtorIter,
3160b57cec5SDimitry Andric                             "`vector vbase ctor iterator'");
3170b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VdispMap,
3180b57cec5SDimitry Andric                             "`virtual displacement map'");
3190b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecCtorIter,
3200b57cec5SDimitry Andric                             "`eh vector ctor iterator'");
3210b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecDtorIter,
3220b57cec5SDimitry Andric                             "`eh vector dtor iterator'");
3230b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecVbaseCtorIter,
3240b57cec5SDimitry Andric                             "`eh vector vbase ctor iterator'");
3250b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, CopyCtorClosure,
3260b57cec5SDimitry Andric                             "`copy ctor closure'");
3270b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LocalVftableCtorClosure,
3280b57cec5SDimitry Andric                             "`local vftable ctor closure'");
3290b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArrayNew, "operator new[]");
3300b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArrayDelete,
3310b57cec5SDimitry Andric                             "operator delete[]");
3320b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorCtorIter,
3330b57cec5SDimitry Andric                             "`managed vector ctor iterator'");
3340b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorDtorIter,
3350b57cec5SDimitry Andric                             "`managed vector dtor iterator'");
3360b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVectorCopyCtorIter,
3370b57cec5SDimitry Andric                             "`EH vector copy ctor iterator'");
3380b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVectorVbaseCopyCtorIter,
3390b57cec5SDimitry Andric                             "`EH vector vbase copy ctor iterator'");
3400b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VectorCopyCtorIter,
3410b57cec5SDimitry Andric                             "`vector copy ctor iterator'");
3420b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VectorVbaseCopyCtorIter,
3430b57cec5SDimitry Andric                             "`vector vbase copy constructor iterator'");
3440b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorVbaseCopyCtorIter,
3450b57cec5SDimitry Andric                             "`managed vector vbase copy constructor iterator'");
3460b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, CoAwait,
3470b57cec5SDimitry Andric                             "operator co_await");
3480b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Spaceship, "operator<=>");
3490b57cec5SDimitry Andric   case IntrinsicFunctionKind::MaxIntrinsic:
3500b57cec5SDimitry Andric   case IntrinsicFunctionKind::None:
3510b57cec5SDimitry Andric     break;
3520b57cec5SDimitry Andric   }
3530b57cec5SDimitry Andric   outputTemplateParameters(OS, Flags);
3540b57cec5SDimitry Andric }
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric void LocalStaticGuardIdentifierNode::output(OutputStream &OS,
3570b57cec5SDimitry Andric                                             OutputFlags Flags) const {
3580b57cec5SDimitry Andric   if (IsThread)
3590b57cec5SDimitry Andric     OS << "`local static thread guard'";
3600b57cec5SDimitry Andric   else
3610b57cec5SDimitry Andric     OS << "`local static guard'";
3620b57cec5SDimitry Andric   if (ScopeIndex > 0)
3630b57cec5SDimitry Andric     OS << "{" << ScopeIndex << "}";
3640b57cec5SDimitry Andric }
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric void ConversionOperatorIdentifierNode::output(OutputStream &OS,
3670b57cec5SDimitry Andric                                               OutputFlags Flags) const {
3680b57cec5SDimitry Andric   OS << "operator";
3690b57cec5SDimitry Andric   outputTemplateParameters(OS, Flags);
3700b57cec5SDimitry Andric   OS << " ";
3710b57cec5SDimitry Andric   TargetType->output(OS, Flags);
3720b57cec5SDimitry Andric }
3730b57cec5SDimitry Andric 
3740b57cec5SDimitry Andric void StructorIdentifierNode::output(OutputStream &OS, OutputFlags Flags) const {
3750b57cec5SDimitry Andric   if (IsDestructor)
3760b57cec5SDimitry Andric     OS << "~";
3770b57cec5SDimitry Andric   Class->output(OS, Flags);
3780b57cec5SDimitry Andric   outputTemplateParameters(OS, Flags);
3790b57cec5SDimitry Andric }
3800b57cec5SDimitry Andric 
3810b57cec5SDimitry Andric void LiteralOperatorIdentifierNode::output(OutputStream &OS,
3820b57cec5SDimitry Andric                                            OutputFlags Flags) const {
3830b57cec5SDimitry Andric   OS << "operator \"\"" << Name;
3840b57cec5SDimitry Andric   outputTemplateParameters(OS, Flags);
3850b57cec5SDimitry Andric }
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric void FunctionSignatureNode::outputPre(OutputStream &OS,
3880b57cec5SDimitry Andric                                       OutputFlags Flags) const {
3898bcb0991SDimitry Andric   if (!(Flags & OF_NoAccessSpecifier)) {
3900b57cec5SDimitry Andric     if (FunctionClass & FC_Public)
3910b57cec5SDimitry Andric       OS << "public: ";
3920b57cec5SDimitry Andric     if (FunctionClass & FC_Protected)
3930b57cec5SDimitry Andric       OS << "protected: ";
3940b57cec5SDimitry Andric     if (FunctionClass & FC_Private)
3950b57cec5SDimitry Andric       OS << "private: ";
3968bcb0991SDimitry Andric   }
3970b57cec5SDimitry Andric 
3988bcb0991SDimitry Andric   if (!(Flags & OF_NoMemberType)) {
3990b57cec5SDimitry Andric     if (!(FunctionClass & FC_Global)) {
4000b57cec5SDimitry Andric       if (FunctionClass & FC_Static)
4010b57cec5SDimitry Andric         OS << "static ";
4020b57cec5SDimitry Andric     }
4030b57cec5SDimitry Andric     if (FunctionClass & FC_Virtual)
4040b57cec5SDimitry Andric       OS << "virtual ";
4050b57cec5SDimitry Andric 
4060b57cec5SDimitry Andric     if (FunctionClass & FC_ExternC)
4070b57cec5SDimitry Andric       OS << "extern \"C\" ";
4088bcb0991SDimitry Andric   }
4090b57cec5SDimitry Andric 
4108bcb0991SDimitry Andric   if (!(Flags & OF_NoReturnType) && ReturnType) {
4110b57cec5SDimitry Andric     ReturnType->outputPre(OS, Flags);
4120b57cec5SDimitry Andric     OS << " ";
4130b57cec5SDimitry Andric   }
4140b57cec5SDimitry Andric 
4150b57cec5SDimitry Andric   if (!(Flags & OF_NoCallingConvention))
4160b57cec5SDimitry Andric     outputCallingConvention(OS, CallConvention);
4170b57cec5SDimitry Andric }
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric void FunctionSignatureNode::outputPost(OutputStream &OS,
4200b57cec5SDimitry Andric                                        OutputFlags Flags) const {
4210b57cec5SDimitry Andric   if (!(FunctionClass & FC_NoParameterList)) {
4220b57cec5SDimitry Andric     OS << "(";
4230b57cec5SDimitry Andric     if (Params)
4240b57cec5SDimitry Andric       Params->output(OS, Flags);
4250b57cec5SDimitry Andric     else
4260b57cec5SDimitry Andric       OS << "void";
4270b57cec5SDimitry Andric 
4280b57cec5SDimitry Andric     if (IsVariadic) {
4290b57cec5SDimitry Andric       if (OS.back() != '(')
4300b57cec5SDimitry Andric         OS << ", ";
4310b57cec5SDimitry Andric       OS << "...";
4320b57cec5SDimitry Andric     }
4330b57cec5SDimitry Andric     OS << ")";
4340b57cec5SDimitry Andric   }
4350b57cec5SDimitry Andric 
4360b57cec5SDimitry Andric   if (Quals & Q_Const)
4370b57cec5SDimitry Andric     OS << " const";
4380b57cec5SDimitry Andric   if (Quals & Q_Volatile)
4390b57cec5SDimitry Andric     OS << " volatile";
4400b57cec5SDimitry Andric   if (Quals & Q_Restrict)
4410b57cec5SDimitry Andric     OS << " __restrict";
4420b57cec5SDimitry Andric   if (Quals & Q_Unaligned)
4430b57cec5SDimitry Andric     OS << " __unaligned";
4440b57cec5SDimitry Andric 
4450b57cec5SDimitry Andric   if (IsNoexcept)
4460b57cec5SDimitry Andric     OS << " noexcept";
4470b57cec5SDimitry Andric 
4480b57cec5SDimitry Andric   if (RefQualifier == FunctionRefQualifier::Reference)
4490b57cec5SDimitry Andric     OS << " &";
4500b57cec5SDimitry Andric   else if (RefQualifier == FunctionRefQualifier::RValueReference)
4510b57cec5SDimitry Andric     OS << " &&";
4520b57cec5SDimitry Andric 
4538bcb0991SDimitry Andric   if (!(Flags & OF_NoReturnType) && ReturnType)
4540b57cec5SDimitry Andric     ReturnType->outputPost(OS, Flags);
4550b57cec5SDimitry Andric }
4560b57cec5SDimitry Andric 
4570b57cec5SDimitry Andric void ThunkSignatureNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
4580b57cec5SDimitry Andric   OS << "[thunk]: ";
4590b57cec5SDimitry Andric 
4600b57cec5SDimitry Andric   FunctionSignatureNode::outputPre(OS, Flags);
4610b57cec5SDimitry Andric }
4620b57cec5SDimitry Andric 
4630b57cec5SDimitry Andric void ThunkSignatureNode::outputPost(OutputStream &OS, OutputFlags Flags) const {
4640b57cec5SDimitry Andric   if (FunctionClass & FC_StaticThisAdjust) {
4650b57cec5SDimitry Andric     OS << "`adjustor{" << ThisAdjust.StaticOffset << "}'";
4660b57cec5SDimitry Andric   } else if (FunctionClass & FC_VirtualThisAdjust) {
4670b57cec5SDimitry Andric     if (FunctionClass & FC_VirtualThisAdjustEx) {
4680b57cec5SDimitry Andric       OS << "`vtordispex{" << ThisAdjust.VBPtrOffset << ", "
4690b57cec5SDimitry Andric          << ThisAdjust.VBOffsetOffset << ", " << ThisAdjust.VtordispOffset
4700b57cec5SDimitry Andric          << ", " << ThisAdjust.StaticOffset << "}'";
4710b57cec5SDimitry Andric     } else {
4720b57cec5SDimitry Andric       OS << "`vtordisp{" << ThisAdjust.VtordispOffset << ", "
4730b57cec5SDimitry Andric          << ThisAdjust.StaticOffset << "}'";
4740b57cec5SDimitry Andric     }
4750b57cec5SDimitry Andric   }
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   FunctionSignatureNode::outputPost(OS, Flags);
4780b57cec5SDimitry Andric }
4790b57cec5SDimitry Andric 
4800b57cec5SDimitry Andric void PointerTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
4810b57cec5SDimitry Andric   if (Pointee->kind() == NodeKind::FunctionSignature) {
4820b57cec5SDimitry Andric     // If this is a pointer to a function, don't output the calling convention.
4830b57cec5SDimitry Andric     // It needs to go inside the parentheses.
4840b57cec5SDimitry Andric     const FunctionSignatureNode *Sig =
4850b57cec5SDimitry Andric         static_cast<const FunctionSignatureNode *>(Pointee);
4860b57cec5SDimitry Andric     Sig->outputPre(OS, OF_NoCallingConvention);
4870b57cec5SDimitry Andric   } else
4880b57cec5SDimitry Andric     Pointee->outputPre(OS, Flags);
4890b57cec5SDimitry Andric 
4900b57cec5SDimitry Andric   outputSpaceIfNecessary(OS);
4910b57cec5SDimitry Andric 
4920b57cec5SDimitry Andric   if (Quals & Q_Unaligned)
4930b57cec5SDimitry Andric     OS << "__unaligned ";
4940b57cec5SDimitry Andric 
4950b57cec5SDimitry Andric   if (Pointee->kind() == NodeKind::ArrayType) {
4960b57cec5SDimitry Andric     OS << "(";
4970b57cec5SDimitry Andric   } else if (Pointee->kind() == NodeKind::FunctionSignature) {
4980b57cec5SDimitry Andric     OS << "(";
4990b57cec5SDimitry Andric     const FunctionSignatureNode *Sig =
5000b57cec5SDimitry Andric         static_cast<const FunctionSignatureNode *>(Pointee);
5010b57cec5SDimitry Andric     outputCallingConvention(OS, Sig->CallConvention);
5020b57cec5SDimitry Andric     OS << " ";
5030b57cec5SDimitry Andric   }
5040b57cec5SDimitry Andric 
5050b57cec5SDimitry Andric   if (ClassParent) {
5060b57cec5SDimitry Andric     ClassParent->output(OS, Flags);
5070b57cec5SDimitry Andric     OS << "::";
5080b57cec5SDimitry Andric   }
5090b57cec5SDimitry Andric 
5100b57cec5SDimitry Andric   switch (Affinity) {
5110b57cec5SDimitry Andric   case PointerAffinity::Pointer:
5120b57cec5SDimitry Andric     OS << "*";
5130b57cec5SDimitry Andric     break;
5140b57cec5SDimitry Andric   case PointerAffinity::Reference:
5150b57cec5SDimitry Andric     OS << "&";
5160b57cec5SDimitry Andric     break;
5170b57cec5SDimitry Andric   case PointerAffinity::RValueReference:
5180b57cec5SDimitry Andric     OS << "&&";
5190b57cec5SDimitry Andric     break;
5200b57cec5SDimitry Andric   default:
5210b57cec5SDimitry Andric     assert(false);
5220b57cec5SDimitry Andric   }
5230b57cec5SDimitry Andric   outputQualifiers(OS, Quals, false, false);
5240b57cec5SDimitry Andric }
5250b57cec5SDimitry Andric 
5260b57cec5SDimitry Andric void PointerTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {
5270b57cec5SDimitry Andric   if (Pointee->kind() == NodeKind::ArrayType ||
5280b57cec5SDimitry Andric       Pointee->kind() == NodeKind::FunctionSignature)
5290b57cec5SDimitry Andric     OS << ")";
5300b57cec5SDimitry Andric 
5310b57cec5SDimitry Andric   Pointee->outputPost(OS, Flags);
5320b57cec5SDimitry Andric }
5330b57cec5SDimitry Andric 
5340b57cec5SDimitry Andric void TagTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
5350b57cec5SDimitry Andric   if (!(Flags & OF_NoTagSpecifier)) {
5360b57cec5SDimitry Andric     switch (Tag) {
5370b57cec5SDimitry Andric       OUTPUT_ENUM_CLASS_VALUE(TagKind, Class, "class");
5380b57cec5SDimitry Andric       OUTPUT_ENUM_CLASS_VALUE(TagKind, Struct, "struct");
5390b57cec5SDimitry Andric       OUTPUT_ENUM_CLASS_VALUE(TagKind, Union, "union");
5400b57cec5SDimitry Andric       OUTPUT_ENUM_CLASS_VALUE(TagKind, Enum, "enum");
5410b57cec5SDimitry Andric     }
5420b57cec5SDimitry Andric     OS << " ";
5430b57cec5SDimitry Andric   }
5440b57cec5SDimitry Andric   QualifiedName->output(OS, Flags);
5450b57cec5SDimitry Andric   outputQualifiers(OS, Quals, true, false);
5460b57cec5SDimitry Andric }
5470b57cec5SDimitry Andric 
5480b57cec5SDimitry Andric void TagTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {}
5490b57cec5SDimitry Andric 
5500b57cec5SDimitry Andric void ArrayTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
5510b57cec5SDimitry Andric   ElementType->outputPre(OS, Flags);
5520b57cec5SDimitry Andric   outputQualifiers(OS, Quals, true, false);
5530b57cec5SDimitry Andric }
5540b57cec5SDimitry Andric 
5550b57cec5SDimitry Andric void ArrayTypeNode::outputOneDimension(OutputStream &OS, OutputFlags Flags,
5560b57cec5SDimitry Andric                                        Node *N) const {
5570b57cec5SDimitry Andric   assert(N->kind() == NodeKind::IntegerLiteral);
5580b57cec5SDimitry Andric   IntegerLiteralNode *ILN = static_cast<IntegerLiteralNode *>(N);
5590b57cec5SDimitry Andric   if (ILN->Value != 0)
5600b57cec5SDimitry Andric     ILN->output(OS, Flags);
5610b57cec5SDimitry Andric }
5620b57cec5SDimitry Andric 
5630b57cec5SDimitry Andric void ArrayTypeNode::outputDimensionsImpl(OutputStream &OS,
5640b57cec5SDimitry Andric                                          OutputFlags Flags) const {
5650b57cec5SDimitry Andric   if (Dimensions->Count == 0)
5660b57cec5SDimitry Andric     return;
5670b57cec5SDimitry Andric 
5680b57cec5SDimitry Andric   outputOneDimension(OS, Flags, Dimensions->Nodes[0]);
5690b57cec5SDimitry Andric   for (size_t I = 1; I < Dimensions->Count; ++I) {
5700b57cec5SDimitry Andric     OS << "][";
5710b57cec5SDimitry Andric     outputOneDimension(OS, Flags, Dimensions->Nodes[I]);
5720b57cec5SDimitry Andric   }
5730b57cec5SDimitry Andric }
5740b57cec5SDimitry Andric 
5750b57cec5SDimitry Andric void ArrayTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {
5760b57cec5SDimitry Andric   OS << "[";
5770b57cec5SDimitry Andric   outputDimensionsImpl(OS, Flags);
5780b57cec5SDimitry Andric   OS << "]";
5790b57cec5SDimitry Andric 
5800b57cec5SDimitry Andric   ElementType->outputPost(OS, Flags);
5810b57cec5SDimitry Andric }
5820b57cec5SDimitry Andric 
5830b57cec5SDimitry Andric void SymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
5840b57cec5SDimitry Andric   Name->output(OS, Flags);
5850b57cec5SDimitry Andric }
5860b57cec5SDimitry Andric 
5870b57cec5SDimitry Andric void FunctionSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
5880b57cec5SDimitry Andric   Signature->outputPre(OS, Flags);
5890b57cec5SDimitry Andric   outputSpaceIfNecessary(OS);
5900b57cec5SDimitry Andric   Name->output(OS, Flags);
5910b57cec5SDimitry Andric   Signature->outputPost(OS, Flags);
5920b57cec5SDimitry Andric }
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric void VariableSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
5958bcb0991SDimitry Andric   const char *AccessSpec = nullptr;
5968bcb0991SDimitry Andric   bool IsStatic = true;
5970b57cec5SDimitry Andric   switch (SC) {
5980b57cec5SDimitry Andric   case StorageClass::PrivateStatic:
5998bcb0991SDimitry Andric     AccessSpec = "private";
6000b57cec5SDimitry Andric     break;
6010b57cec5SDimitry Andric   case StorageClass::PublicStatic:
6028bcb0991SDimitry Andric     AccessSpec = "public";
6030b57cec5SDimitry Andric     break;
6040b57cec5SDimitry Andric   case StorageClass::ProtectedStatic:
6058bcb0991SDimitry Andric     AccessSpec = "protected";
6060b57cec5SDimitry Andric     break;
6070b57cec5SDimitry Andric   default:
6088bcb0991SDimitry Andric     IsStatic = false;
6090b57cec5SDimitry Andric     break;
6100b57cec5SDimitry Andric   }
6118bcb0991SDimitry Andric   if (!(Flags & OF_NoAccessSpecifier) && AccessSpec)
6128bcb0991SDimitry Andric     OS << AccessSpec << ": ";
6138bcb0991SDimitry Andric   if (!(Flags & OF_NoMemberType) && IsStatic)
6148bcb0991SDimitry Andric     OS << "static ";
6150b57cec5SDimitry Andric 
6160b57cec5SDimitry Andric   if (Type) {
6170b57cec5SDimitry Andric     Type->outputPre(OS, Flags);
6180b57cec5SDimitry Andric     outputSpaceIfNecessary(OS);
6190b57cec5SDimitry Andric   }
6200b57cec5SDimitry Andric   Name->output(OS, Flags);
6210b57cec5SDimitry Andric   if (Type)
6220b57cec5SDimitry Andric     Type->outputPost(OS, Flags);
6230b57cec5SDimitry Andric }
6240b57cec5SDimitry Andric 
6250b57cec5SDimitry Andric void CustomTypeNode::outputPre(OutputStream &OS, OutputFlags Flags) const {
6260b57cec5SDimitry Andric   Identifier->output(OS, Flags);
6270b57cec5SDimitry Andric }
6280b57cec5SDimitry Andric void CustomTypeNode::outputPost(OutputStream &OS, OutputFlags Flags) const {}
6290b57cec5SDimitry Andric 
6300b57cec5SDimitry Andric void QualifiedNameNode::output(OutputStream &OS, OutputFlags Flags) const {
6310b57cec5SDimitry Andric   Components->output(OS, Flags, "::");
6320b57cec5SDimitry Andric }
6330b57cec5SDimitry Andric 
6340b57cec5SDimitry Andric void RttiBaseClassDescriptorNode::output(OutputStream &OS,
6350b57cec5SDimitry Andric                                          OutputFlags Flags) const {
6360b57cec5SDimitry Andric   OS << "`RTTI Base Class Descriptor at (";
6370b57cec5SDimitry Andric   OS << NVOffset << ", " << VBPtrOffset << ", " << VBTableOffset << ", "
6380b57cec5SDimitry Andric      << this->Flags;
6390b57cec5SDimitry Andric   OS << ")'";
6400b57cec5SDimitry Andric }
6410b57cec5SDimitry Andric 
6420b57cec5SDimitry Andric void LocalStaticGuardVariableNode::output(OutputStream &OS,
6430b57cec5SDimitry Andric                                           OutputFlags Flags) const {
6440b57cec5SDimitry Andric   Name->output(OS, Flags);
6450b57cec5SDimitry Andric }
6460b57cec5SDimitry Andric 
6470b57cec5SDimitry Andric void VcallThunkIdentifierNode::output(OutputStream &OS,
6480b57cec5SDimitry Andric                                       OutputFlags Flags) const {
6490b57cec5SDimitry Andric   OS << "`vcall'{" << OffsetInVTable << ", {flat}}";
6500b57cec5SDimitry Andric }
6510b57cec5SDimitry Andric 
6520b57cec5SDimitry Andric void SpecialTableSymbolNode::output(OutputStream &OS, OutputFlags Flags) const {
6530b57cec5SDimitry Andric   outputQualifiers(OS, Quals, false, true);
6540b57cec5SDimitry Andric   Name->output(OS, Flags);
6550b57cec5SDimitry Andric   if (TargetName) {
6560b57cec5SDimitry Andric     OS << "{for `";
6570b57cec5SDimitry Andric     TargetName->output(OS, Flags);
6580b57cec5SDimitry Andric     OS << "'}";
6590b57cec5SDimitry Andric   }
6600b57cec5SDimitry Andric }
661