xref: /freebsd/contrib/llvm-project/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
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/Utility.h"
150b57cec5SDimitry Andric #include <cctype>
160b57cec5SDimitry Andric #include <string>
170b57cec5SDimitry Andric 
180b57cec5SDimitry Andric using namespace llvm;
190b57cec5SDimitry Andric using namespace ms_demangle;
200b57cec5SDimitry Andric 
210b57cec5SDimitry Andric #define OUTPUT_ENUM_CLASS_VALUE(Enum, Value, Desc)                             \
220b57cec5SDimitry Andric   case Enum::Value:                                                            \
23349cc55cSDimitry Andric     OB << Desc;                                                                \
240b57cec5SDimitry Andric     break;
250b57cec5SDimitry Andric 
260b57cec5SDimitry Andric // Writes a space if the last token does not end with a punctuation.
27349cc55cSDimitry Andric static void outputSpaceIfNecessary(OutputBuffer &OB) {
28349cc55cSDimitry Andric   if (OB.empty())
290b57cec5SDimitry Andric     return;
300b57cec5SDimitry Andric 
31349cc55cSDimitry Andric   char C = OB.back();
320b57cec5SDimitry Andric   if (std::isalnum(C) || C == '>')
33349cc55cSDimitry Andric     OB << " ";
340b57cec5SDimitry Andric }
350b57cec5SDimitry Andric 
36349cc55cSDimitry Andric static void outputSingleQualifier(OutputBuffer &OB, Qualifiers Q) {
370b57cec5SDimitry Andric   switch (Q) {
380b57cec5SDimitry Andric   case Q_Const:
39349cc55cSDimitry Andric     OB << "const";
400b57cec5SDimitry Andric     break;
410b57cec5SDimitry Andric   case Q_Volatile:
42349cc55cSDimitry Andric     OB << "volatile";
430b57cec5SDimitry Andric     break;
440b57cec5SDimitry Andric   case Q_Restrict:
45349cc55cSDimitry Andric     OB << "__restrict";
460b57cec5SDimitry Andric     break;
470b57cec5SDimitry Andric   default:
480b57cec5SDimitry Andric     break;
490b57cec5SDimitry Andric   }
500b57cec5SDimitry Andric }
510b57cec5SDimitry Andric 
52349cc55cSDimitry Andric static bool outputQualifierIfPresent(OutputBuffer &OB, Qualifiers Q,
530b57cec5SDimitry Andric                                      Qualifiers Mask, bool NeedSpace) {
540b57cec5SDimitry Andric   if (!(Q & Mask))
550b57cec5SDimitry Andric     return NeedSpace;
560b57cec5SDimitry Andric 
570b57cec5SDimitry Andric   if (NeedSpace)
58349cc55cSDimitry Andric     OB << " ";
590b57cec5SDimitry Andric 
60349cc55cSDimitry Andric   outputSingleQualifier(OB, Mask);
610b57cec5SDimitry Andric   return true;
620b57cec5SDimitry Andric }
630b57cec5SDimitry Andric 
64349cc55cSDimitry Andric static void outputQualifiers(OutputBuffer &OB, Qualifiers Q, bool SpaceBefore,
650b57cec5SDimitry Andric                              bool SpaceAfter) {
660b57cec5SDimitry Andric   if (Q == Q_None)
670b57cec5SDimitry Andric     return;
680b57cec5SDimitry Andric 
69349cc55cSDimitry Andric   size_t Pos1 = OB.getCurrentPosition();
70349cc55cSDimitry Andric   SpaceBefore = outputQualifierIfPresent(OB, Q, Q_Const, SpaceBefore);
71349cc55cSDimitry Andric   SpaceBefore = outputQualifierIfPresent(OB, Q, Q_Volatile, SpaceBefore);
72349cc55cSDimitry Andric   SpaceBefore = outputQualifierIfPresent(OB, Q, Q_Restrict, SpaceBefore);
73349cc55cSDimitry Andric   size_t Pos2 = OB.getCurrentPosition();
740b57cec5SDimitry Andric   if (SpaceAfter && Pos2 > Pos1)
75349cc55cSDimitry Andric     OB << " ";
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric 
78349cc55cSDimitry Andric static void outputCallingConvention(OutputBuffer &OB, CallingConv CC) {
79349cc55cSDimitry Andric   outputSpaceIfNecessary(OB);
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric   switch (CC) {
820b57cec5SDimitry Andric   case CallingConv::Cdecl:
83349cc55cSDimitry Andric     OB << "__cdecl";
840b57cec5SDimitry Andric     break;
850b57cec5SDimitry Andric   case CallingConv::Fastcall:
86349cc55cSDimitry Andric     OB << "__fastcall";
870b57cec5SDimitry Andric     break;
880b57cec5SDimitry Andric   case CallingConv::Pascal:
89349cc55cSDimitry Andric     OB << "__pascal";
900b57cec5SDimitry Andric     break;
910b57cec5SDimitry Andric   case CallingConv::Regcall:
92349cc55cSDimitry Andric     OB << "__regcall";
930b57cec5SDimitry Andric     break;
940b57cec5SDimitry Andric   case CallingConv::Stdcall:
95349cc55cSDimitry Andric     OB << "__stdcall";
960b57cec5SDimitry Andric     break;
970b57cec5SDimitry Andric   case CallingConv::Thiscall:
98349cc55cSDimitry Andric     OB << "__thiscall";
990b57cec5SDimitry Andric     break;
1000b57cec5SDimitry Andric   case CallingConv::Eabi:
101349cc55cSDimitry Andric     OB << "__eabi";
1020b57cec5SDimitry Andric     break;
1030b57cec5SDimitry Andric   case CallingConv::Vectorcall:
104349cc55cSDimitry Andric     OB << "__vectorcall";
1050b57cec5SDimitry Andric     break;
1060b57cec5SDimitry Andric   case CallingConv::Clrcall:
107349cc55cSDimitry Andric     OB << "__clrcall";
1080b57cec5SDimitry Andric     break;
109fe6060f1SDimitry Andric   case CallingConv::Swift:
110349cc55cSDimitry Andric     OB << "__attribute__((__swiftcall__)) ";
111fe6060f1SDimitry Andric     break;
112fe6060f1SDimitry Andric   case CallingConv::SwiftAsync:
113349cc55cSDimitry Andric     OB << "__attribute__((__swiftasynccall__)) ";
114fe6060f1SDimitry Andric     break;
1150b57cec5SDimitry Andric   default:
1160b57cec5SDimitry Andric     break;
1170b57cec5SDimitry Andric   }
1180b57cec5SDimitry Andric }
1190b57cec5SDimitry Andric 
1200b57cec5SDimitry Andric std::string Node::toString(OutputFlags Flags) const {
121349cc55cSDimitry Andric   OutputBuffer OB;
122349cc55cSDimitry Andric   initializeOutputBuffer(nullptr, nullptr, OB, 1024);
123349cc55cSDimitry Andric   this->output(OB, Flags);
124*81ad6265SDimitry Andric   StringView SV = OB;
125*81ad6265SDimitry Andric   std::string Owned(SV.begin(), SV.end());
126349cc55cSDimitry Andric   std::free(OB.getBuffer());
127fe6060f1SDimitry Andric   return Owned;
1280b57cec5SDimitry Andric }
1290b57cec5SDimitry Andric 
130349cc55cSDimitry Andric void PrimitiveTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
1310b57cec5SDimitry Andric   switch (PrimKind) {
1320b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Void, "void");
1330b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Bool, "bool");
1340b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char, "char");
1350b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Schar, "signed char");
1360b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uchar, "unsigned char");
1370b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char8, "char8_t");
1380b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char16, "char16_t");
1390b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char32, "char32_t");
1400b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Short, "short");
1410b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ushort, "unsigned short");
1420b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Int, "int");
1430b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uint, "unsigned int");
1440b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Long, "long");
1450b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ulong, "unsigned long");
1460b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Int64, "__int64");
1470b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uint64, "unsigned __int64");
1480b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Wchar, "wchar_t");
1490b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Float, "float");
1500b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Double, "double");
1510b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ldouble, "long double");
1520b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Nullptr, "std::nullptr_t");
1530b57cec5SDimitry Andric   }
154349cc55cSDimitry Andric   outputQualifiers(OB, Quals, true, false);
1550b57cec5SDimitry Andric }
1560b57cec5SDimitry Andric 
157349cc55cSDimitry Andric void NodeArrayNode::output(OutputBuffer &OB, OutputFlags Flags) const {
158349cc55cSDimitry Andric   output(OB, Flags, ", ");
1590b57cec5SDimitry Andric }
1600b57cec5SDimitry Andric 
161349cc55cSDimitry Andric void NodeArrayNode::output(OutputBuffer &OB, OutputFlags Flags,
1620b57cec5SDimitry Andric                            StringView Separator) const {
1630b57cec5SDimitry Andric   if (Count == 0)
1640b57cec5SDimitry Andric     return;
1650b57cec5SDimitry Andric   if (Nodes[0])
166349cc55cSDimitry Andric     Nodes[0]->output(OB, Flags);
1670b57cec5SDimitry Andric   for (size_t I = 1; I < Count; ++I) {
168349cc55cSDimitry Andric     OB << Separator;
169349cc55cSDimitry Andric     Nodes[I]->output(OB, Flags);
1700b57cec5SDimitry Andric   }
1710b57cec5SDimitry Andric }
1720b57cec5SDimitry Andric 
173349cc55cSDimitry Andric void EncodedStringLiteralNode::output(OutputBuffer &OB,
1740b57cec5SDimitry Andric                                       OutputFlags Flags) const {
1750b57cec5SDimitry Andric   switch (Char) {
1760b57cec5SDimitry Andric   case CharKind::Wchar:
177349cc55cSDimitry Andric     OB << "L\"";
1780b57cec5SDimitry Andric     break;
1790b57cec5SDimitry Andric   case CharKind::Char:
180349cc55cSDimitry Andric     OB << "\"";
1810b57cec5SDimitry Andric     break;
1820b57cec5SDimitry Andric   case CharKind::Char16:
183349cc55cSDimitry Andric     OB << "u\"";
1840b57cec5SDimitry Andric     break;
1850b57cec5SDimitry Andric   case CharKind::Char32:
186349cc55cSDimitry Andric     OB << "U\"";
1870b57cec5SDimitry Andric     break;
1880b57cec5SDimitry Andric   }
189349cc55cSDimitry Andric   OB << DecodedString << "\"";
1900b57cec5SDimitry Andric   if (IsTruncated)
191349cc55cSDimitry Andric     OB << "...";
1920b57cec5SDimitry Andric }
1930b57cec5SDimitry Andric 
194349cc55cSDimitry Andric void IntegerLiteralNode::output(OutputBuffer &OB, OutputFlags Flags) const {
1950b57cec5SDimitry Andric   if (IsNegative)
196349cc55cSDimitry Andric     OB << '-';
197349cc55cSDimitry Andric   OB << Value;
1980b57cec5SDimitry Andric }
1990b57cec5SDimitry Andric 
200349cc55cSDimitry Andric void TemplateParameterReferenceNode::output(OutputBuffer &OB,
2010b57cec5SDimitry Andric                                             OutputFlags Flags) const {
2020b57cec5SDimitry Andric   if (ThunkOffsetCount > 0)
203349cc55cSDimitry Andric     OB << "{";
2040b57cec5SDimitry Andric   else if (Affinity == PointerAffinity::Pointer)
205349cc55cSDimitry Andric     OB << "&";
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric   if (Symbol) {
208349cc55cSDimitry Andric     Symbol->output(OB, Flags);
2090b57cec5SDimitry Andric     if (ThunkOffsetCount > 0)
210349cc55cSDimitry Andric       OB << ", ";
2110b57cec5SDimitry Andric   }
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric   if (ThunkOffsetCount > 0)
214349cc55cSDimitry Andric     OB << ThunkOffsets[0];
2150b57cec5SDimitry Andric   for (int I = 1; I < ThunkOffsetCount; ++I) {
216349cc55cSDimitry Andric     OB << ", " << ThunkOffsets[I];
2170b57cec5SDimitry Andric   }
2180b57cec5SDimitry Andric   if (ThunkOffsetCount > 0)
219349cc55cSDimitry Andric     OB << "}";
2200b57cec5SDimitry Andric }
2210b57cec5SDimitry Andric 
222349cc55cSDimitry Andric void IdentifierNode::outputTemplateParameters(OutputBuffer &OB,
2230b57cec5SDimitry Andric                                               OutputFlags Flags) const {
2240b57cec5SDimitry Andric   if (!TemplateParams)
2250b57cec5SDimitry Andric     return;
226349cc55cSDimitry Andric   OB << "<";
227349cc55cSDimitry Andric   TemplateParams->output(OB, Flags);
228349cc55cSDimitry Andric   OB << ">";
2290b57cec5SDimitry Andric }
2300b57cec5SDimitry Andric 
231349cc55cSDimitry Andric void DynamicStructorIdentifierNode::output(OutputBuffer &OB,
2320b57cec5SDimitry Andric                                            OutputFlags Flags) const {
2330b57cec5SDimitry Andric   if (IsDestructor)
234349cc55cSDimitry Andric     OB << "`dynamic atexit destructor for ";
2350b57cec5SDimitry Andric   else
236349cc55cSDimitry Andric     OB << "`dynamic initializer for ";
2370b57cec5SDimitry Andric 
2380b57cec5SDimitry Andric   if (Variable) {
239349cc55cSDimitry Andric     OB << "`";
240349cc55cSDimitry Andric     Variable->output(OB, Flags);
241349cc55cSDimitry Andric     OB << "''";
2420b57cec5SDimitry Andric   } else {
243349cc55cSDimitry Andric     OB << "'";
244349cc55cSDimitry Andric     Name->output(OB, Flags);
245349cc55cSDimitry Andric     OB << "''";
2460b57cec5SDimitry Andric   }
2470b57cec5SDimitry Andric }
2480b57cec5SDimitry Andric 
249349cc55cSDimitry Andric void NamedIdentifierNode::output(OutputBuffer &OB, OutputFlags Flags) const {
250349cc55cSDimitry Andric   OB << Name;
251349cc55cSDimitry Andric   outputTemplateParameters(OB, Flags);
2520b57cec5SDimitry Andric }
2530b57cec5SDimitry Andric 
254349cc55cSDimitry Andric void IntrinsicFunctionIdentifierNode::output(OutputBuffer &OB,
2550b57cec5SDimitry Andric                                              OutputFlags Flags) const {
2560b57cec5SDimitry Andric   switch (Operator) {
2570b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, New, "operator new");
2580b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Delete, "operator delete");
2590b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Assign, "operator=");
2600b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, RightShift, "operator>>");
2610b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LeftShift, "operator<<");
2620b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalNot, "operator!");
2630b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Equals, "operator==");
2640b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, NotEquals, "operator!=");
2650b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArraySubscript,
2660b57cec5SDimitry Andric                             "operator[]");
2670b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Pointer, "operator->");
2680b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Increment, "operator++");
2690b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Decrement, "operator--");
2700b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Minus, "operator-");
2710b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Plus, "operator+");
2720b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Dereference, "operator*");
2730b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseAnd, "operator&");
2740b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, MemberPointer,
2750b57cec5SDimitry Andric                             "operator->*");
2760b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Divide, "operator/");
2770b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Modulus, "operator%");
2780b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LessThan, "operator<");
2790b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LessThanEqual, "operator<=");
2800b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, GreaterThan, "operator>");
2810b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, GreaterThanEqual,
2820b57cec5SDimitry Andric                             "operator>=");
2830b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Comma, "operator,");
2840b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Parens, "operator()");
2850b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseNot, "operator~");
2860b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseXor, "operator^");
2870b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseOr, "operator|");
2880b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalAnd, "operator&&");
2890b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalOr, "operator||");
2900b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, TimesEqual, "operator*=");
2910b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, PlusEqual, "operator+=");
2920b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, MinusEqual, "operator-=");
2930b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, DivEqual, "operator/=");
2940b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ModEqual, "operator%=");
2950b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, RshEqual, "operator>>=");
2960b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LshEqual, "operator<<=");
2970b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseAndEqual,
2980b57cec5SDimitry Andric                             "operator&=");
2990b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseOrEqual,
3000b57cec5SDimitry Andric                             "operator|=");
3010b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseXorEqual,
3020b57cec5SDimitry Andric                             "operator^=");
3030b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VbaseDtor, "`vbase dtor'");
3040b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecDelDtor,
3050b57cec5SDimitry Andric                             "`vector deleting dtor'");
3060b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, DefaultCtorClosure,
3070b57cec5SDimitry Andric                             "`default ctor closure'");
3080b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ScalarDelDtor,
3090b57cec5SDimitry Andric                             "`scalar deleting dtor'");
3100b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecCtorIter,
3110b57cec5SDimitry Andric                             "`vector ctor iterator'");
3120b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecDtorIter,
3130b57cec5SDimitry Andric                             "`vector dtor iterator'");
3140b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecVbaseCtorIter,
3150b57cec5SDimitry Andric                             "`vector vbase ctor iterator'");
3160b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VdispMap,
3170b57cec5SDimitry Andric                             "`virtual displacement map'");
3180b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecCtorIter,
3190b57cec5SDimitry Andric                             "`eh vector ctor iterator'");
3200b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecDtorIter,
3210b57cec5SDimitry Andric                             "`eh vector dtor iterator'");
3220b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecVbaseCtorIter,
3230b57cec5SDimitry Andric                             "`eh vector vbase ctor iterator'");
3240b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, CopyCtorClosure,
3250b57cec5SDimitry Andric                             "`copy ctor closure'");
3260b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LocalVftableCtorClosure,
3270b57cec5SDimitry Andric                             "`local vftable ctor closure'");
3280b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArrayNew, "operator new[]");
3290b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArrayDelete,
3300b57cec5SDimitry Andric                             "operator delete[]");
3310b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorCtorIter,
3320b57cec5SDimitry Andric                             "`managed vector ctor iterator'");
3330b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorDtorIter,
3340b57cec5SDimitry Andric                             "`managed vector dtor iterator'");
3350b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVectorCopyCtorIter,
3360b57cec5SDimitry Andric                             "`EH vector copy ctor iterator'");
3370b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVectorVbaseCopyCtorIter,
3380b57cec5SDimitry Andric                             "`EH vector vbase copy ctor iterator'");
3390b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VectorCopyCtorIter,
3400b57cec5SDimitry Andric                             "`vector copy ctor iterator'");
3410b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VectorVbaseCopyCtorIter,
3420b57cec5SDimitry Andric                             "`vector vbase copy constructor iterator'");
3430b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorVbaseCopyCtorIter,
3440b57cec5SDimitry Andric                             "`managed vector vbase copy constructor iterator'");
3450b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, CoAwait,
3460b57cec5SDimitry Andric                             "operator co_await");
3470b57cec5SDimitry Andric     OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Spaceship, "operator<=>");
3480b57cec5SDimitry Andric   case IntrinsicFunctionKind::MaxIntrinsic:
3490b57cec5SDimitry Andric   case IntrinsicFunctionKind::None:
3500b57cec5SDimitry Andric     break;
3510b57cec5SDimitry Andric   }
352349cc55cSDimitry Andric   outputTemplateParameters(OB, Flags);
3530b57cec5SDimitry Andric }
3540b57cec5SDimitry Andric 
355349cc55cSDimitry Andric void LocalStaticGuardIdentifierNode::output(OutputBuffer &OB,
3560b57cec5SDimitry Andric                                             OutputFlags Flags) const {
3570b57cec5SDimitry Andric   if (IsThread)
358349cc55cSDimitry Andric     OB << "`local static thread guard'";
3590b57cec5SDimitry Andric   else
360349cc55cSDimitry Andric     OB << "`local static guard'";
3610b57cec5SDimitry Andric   if (ScopeIndex > 0)
362349cc55cSDimitry Andric     OB << "{" << ScopeIndex << "}";
3630b57cec5SDimitry Andric }
3640b57cec5SDimitry Andric 
365349cc55cSDimitry Andric void ConversionOperatorIdentifierNode::output(OutputBuffer &OB,
3660b57cec5SDimitry Andric                                               OutputFlags Flags) const {
367349cc55cSDimitry Andric   OB << "operator";
368349cc55cSDimitry Andric   outputTemplateParameters(OB, Flags);
369349cc55cSDimitry Andric   OB << " ";
370349cc55cSDimitry Andric   TargetType->output(OB, Flags);
3710b57cec5SDimitry Andric }
3720b57cec5SDimitry Andric 
373349cc55cSDimitry Andric void StructorIdentifierNode::output(OutputBuffer &OB, OutputFlags Flags) const {
3740b57cec5SDimitry Andric   if (IsDestructor)
375349cc55cSDimitry Andric     OB << "~";
376349cc55cSDimitry Andric   Class->output(OB, Flags);
377349cc55cSDimitry Andric   outputTemplateParameters(OB, Flags);
3780b57cec5SDimitry Andric }
3790b57cec5SDimitry Andric 
380349cc55cSDimitry Andric void LiteralOperatorIdentifierNode::output(OutputBuffer &OB,
3810b57cec5SDimitry Andric                                            OutputFlags Flags) const {
382349cc55cSDimitry Andric   OB << "operator \"\"" << Name;
383349cc55cSDimitry Andric   outputTemplateParameters(OB, Flags);
3840b57cec5SDimitry Andric }
3850b57cec5SDimitry Andric 
386349cc55cSDimitry Andric void FunctionSignatureNode::outputPre(OutputBuffer &OB,
3870b57cec5SDimitry Andric                                       OutputFlags Flags) const {
3888bcb0991SDimitry Andric   if (!(Flags & OF_NoAccessSpecifier)) {
3890b57cec5SDimitry Andric     if (FunctionClass & FC_Public)
390349cc55cSDimitry Andric       OB << "public: ";
3910b57cec5SDimitry Andric     if (FunctionClass & FC_Protected)
392349cc55cSDimitry Andric       OB << "protected: ";
3930b57cec5SDimitry Andric     if (FunctionClass & FC_Private)
394349cc55cSDimitry Andric       OB << "private: ";
3958bcb0991SDimitry Andric   }
3960b57cec5SDimitry Andric 
3978bcb0991SDimitry Andric   if (!(Flags & OF_NoMemberType)) {
3980b57cec5SDimitry Andric     if (!(FunctionClass & FC_Global)) {
3990b57cec5SDimitry Andric       if (FunctionClass & FC_Static)
400349cc55cSDimitry Andric         OB << "static ";
4010b57cec5SDimitry Andric     }
4020b57cec5SDimitry Andric     if (FunctionClass & FC_Virtual)
403349cc55cSDimitry Andric       OB << "virtual ";
4040b57cec5SDimitry Andric 
4050b57cec5SDimitry Andric     if (FunctionClass & FC_ExternC)
406349cc55cSDimitry Andric       OB << "extern \"C\" ";
4078bcb0991SDimitry Andric   }
4080b57cec5SDimitry Andric 
4098bcb0991SDimitry Andric   if (!(Flags & OF_NoReturnType) && ReturnType) {
410349cc55cSDimitry Andric     ReturnType->outputPre(OB, Flags);
411349cc55cSDimitry Andric     OB << " ";
4120b57cec5SDimitry Andric   }
4130b57cec5SDimitry Andric 
4140b57cec5SDimitry Andric   if (!(Flags & OF_NoCallingConvention))
415349cc55cSDimitry Andric     outputCallingConvention(OB, CallConvention);
4160b57cec5SDimitry Andric }
4170b57cec5SDimitry Andric 
418349cc55cSDimitry Andric void FunctionSignatureNode::outputPost(OutputBuffer &OB,
4190b57cec5SDimitry Andric                                        OutputFlags Flags) const {
4200b57cec5SDimitry Andric   if (!(FunctionClass & FC_NoParameterList)) {
421349cc55cSDimitry Andric     OB << "(";
4220b57cec5SDimitry Andric     if (Params)
423349cc55cSDimitry Andric       Params->output(OB, Flags);
4240b57cec5SDimitry Andric     else
425349cc55cSDimitry Andric       OB << "void";
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric     if (IsVariadic) {
428349cc55cSDimitry Andric       if (OB.back() != '(')
429349cc55cSDimitry Andric         OB << ", ";
430349cc55cSDimitry Andric       OB << "...";
4310b57cec5SDimitry Andric     }
432349cc55cSDimitry Andric     OB << ")";
4330b57cec5SDimitry Andric   }
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   if (Quals & Q_Const)
436349cc55cSDimitry Andric     OB << " const";
4370b57cec5SDimitry Andric   if (Quals & Q_Volatile)
438349cc55cSDimitry Andric     OB << " volatile";
4390b57cec5SDimitry Andric   if (Quals & Q_Restrict)
440349cc55cSDimitry Andric     OB << " __restrict";
4410b57cec5SDimitry Andric   if (Quals & Q_Unaligned)
442349cc55cSDimitry Andric     OB << " __unaligned";
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric   if (IsNoexcept)
445349cc55cSDimitry Andric     OB << " noexcept";
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric   if (RefQualifier == FunctionRefQualifier::Reference)
448349cc55cSDimitry Andric     OB << " &";
4490b57cec5SDimitry Andric   else if (RefQualifier == FunctionRefQualifier::RValueReference)
450349cc55cSDimitry Andric     OB << " &&";
4510b57cec5SDimitry Andric 
4528bcb0991SDimitry Andric   if (!(Flags & OF_NoReturnType) && ReturnType)
453349cc55cSDimitry Andric     ReturnType->outputPost(OB, Flags);
4540b57cec5SDimitry Andric }
4550b57cec5SDimitry Andric 
456349cc55cSDimitry Andric void ThunkSignatureNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
457349cc55cSDimitry Andric   OB << "[thunk]: ";
4580b57cec5SDimitry Andric 
459349cc55cSDimitry Andric   FunctionSignatureNode::outputPre(OB, Flags);
4600b57cec5SDimitry Andric }
4610b57cec5SDimitry Andric 
462349cc55cSDimitry Andric void ThunkSignatureNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {
4630b57cec5SDimitry Andric   if (FunctionClass & FC_StaticThisAdjust) {
464349cc55cSDimitry Andric     OB << "`adjustor{" << ThisAdjust.StaticOffset << "}'";
4650b57cec5SDimitry Andric   } else if (FunctionClass & FC_VirtualThisAdjust) {
4660b57cec5SDimitry Andric     if (FunctionClass & FC_VirtualThisAdjustEx) {
467349cc55cSDimitry Andric       OB << "`vtordispex{" << ThisAdjust.VBPtrOffset << ", "
4680b57cec5SDimitry Andric          << ThisAdjust.VBOffsetOffset << ", " << ThisAdjust.VtordispOffset
4690b57cec5SDimitry Andric          << ", " << ThisAdjust.StaticOffset << "}'";
4700b57cec5SDimitry Andric     } else {
471349cc55cSDimitry Andric       OB << "`vtordisp{" << ThisAdjust.VtordispOffset << ", "
4720b57cec5SDimitry Andric          << ThisAdjust.StaticOffset << "}'";
4730b57cec5SDimitry Andric     }
4740b57cec5SDimitry Andric   }
4750b57cec5SDimitry Andric 
476349cc55cSDimitry Andric   FunctionSignatureNode::outputPost(OB, Flags);
4770b57cec5SDimitry Andric }
4780b57cec5SDimitry Andric 
479349cc55cSDimitry Andric void PointerTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
4800b57cec5SDimitry Andric   if (Pointee->kind() == NodeKind::FunctionSignature) {
4810b57cec5SDimitry Andric     // If this is a pointer to a function, don't output the calling convention.
4820b57cec5SDimitry Andric     // It needs to go inside the parentheses.
4830b57cec5SDimitry Andric     const FunctionSignatureNode *Sig =
4840b57cec5SDimitry Andric         static_cast<const FunctionSignatureNode *>(Pointee);
485349cc55cSDimitry Andric     Sig->outputPre(OB, OF_NoCallingConvention);
4860b57cec5SDimitry Andric   } else
487349cc55cSDimitry Andric     Pointee->outputPre(OB, Flags);
4880b57cec5SDimitry Andric 
489349cc55cSDimitry Andric   outputSpaceIfNecessary(OB);
4900b57cec5SDimitry Andric 
4910b57cec5SDimitry Andric   if (Quals & Q_Unaligned)
492349cc55cSDimitry Andric     OB << "__unaligned ";
4930b57cec5SDimitry Andric 
4940b57cec5SDimitry Andric   if (Pointee->kind() == NodeKind::ArrayType) {
495349cc55cSDimitry Andric     OB << "(";
4960b57cec5SDimitry Andric   } else if (Pointee->kind() == NodeKind::FunctionSignature) {
497349cc55cSDimitry Andric     OB << "(";
4980b57cec5SDimitry Andric     const FunctionSignatureNode *Sig =
4990b57cec5SDimitry Andric         static_cast<const FunctionSignatureNode *>(Pointee);
500349cc55cSDimitry Andric     outputCallingConvention(OB, Sig->CallConvention);
501349cc55cSDimitry Andric     OB << " ";
5020b57cec5SDimitry Andric   }
5030b57cec5SDimitry Andric 
5040b57cec5SDimitry Andric   if (ClassParent) {
505349cc55cSDimitry Andric     ClassParent->output(OB, Flags);
506349cc55cSDimitry Andric     OB << "::";
5070b57cec5SDimitry Andric   }
5080b57cec5SDimitry Andric 
5090b57cec5SDimitry Andric   switch (Affinity) {
5100b57cec5SDimitry Andric   case PointerAffinity::Pointer:
511349cc55cSDimitry Andric     OB << "*";
5120b57cec5SDimitry Andric     break;
5130b57cec5SDimitry Andric   case PointerAffinity::Reference:
514349cc55cSDimitry Andric     OB << "&";
5150b57cec5SDimitry Andric     break;
5160b57cec5SDimitry Andric   case PointerAffinity::RValueReference:
517349cc55cSDimitry Andric     OB << "&&";
5180b57cec5SDimitry Andric     break;
5190b57cec5SDimitry Andric   default:
5200b57cec5SDimitry Andric     assert(false);
5210b57cec5SDimitry Andric   }
522349cc55cSDimitry Andric   outputQualifiers(OB, Quals, false, false);
5230b57cec5SDimitry Andric }
5240b57cec5SDimitry Andric 
525349cc55cSDimitry Andric void PointerTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {
5260b57cec5SDimitry Andric   if (Pointee->kind() == NodeKind::ArrayType ||
5270b57cec5SDimitry Andric       Pointee->kind() == NodeKind::FunctionSignature)
528349cc55cSDimitry Andric     OB << ")";
5290b57cec5SDimitry Andric 
530349cc55cSDimitry Andric   Pointee->outputPost(OB, Flags);
5310b57cec5SDimitry Andric }
5320b57cec5SDimitry Andric 
533349cc55cSDimitry Andric void TagTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
5340b57cec5SDimitry Andric   if (!(Flags & OF_NoTagSpecifier)) {
5350b57cec5SDimitry Andric     switch (Tag) {
5360b57cec5SDimitry Andric       OUTPUT_ENUM_CLASS_VALUE(TagKind, Class, "class");
5370b57cec5SDimitry Andric       OUTPUT_ENUM_CLASS_VALUE(TagKind, Struct, "struct");
5380b57cec5SDimitry Andric       OUTPUT_ENUM_CLASS_VALUE(TagKind, Union, "union");
5390b57cec5SDimitry Andric       OUTPUT_ENUM_CLASS_VALUE(TagKind, Enum, "enum");
5400b57cec5SDimitry Andric     }
541349cc55cSDimitry Andric     OB << " ";
5420b57cec5SDimitry Andric   }
543349cc55cSDimitry Andric   QualifiedName->output(OB, Flags);
544349cc55cSDimitry Andric   outputQualifiers(OB, Quals, true, false);
5450b57cec5SDimitry Andric }
5460b57cec5SDimitry Andric 
547349cc55cSDimitry Andric void TagTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {}
5480b57cec5SDimitry Andric 
549349cc55cSDimitry Andric void ArrayTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
550349cc55cSDimitry Andric   ElementType->outputPre(OB, Flags);
551349cc55cSDimitry Andric   outputQualifiers(OB, Quals, true, false);
5520b57cec5SDimitry Andric }
5530b57cec5SDimitry Andric 
554349cc55cSDimitry Andric void ArrayTypeNode::outputOneDimension(OutputBuffer &OB, OutputFlags Flags,
5550b57cec5SDimitry Andric                                        Node *N) const {
5560b57cec5SDimitry Andric   assert(N->kind() == NodeKind::IntegerLiteral);
5570b57cec5SDimitry Andric   IntegerLiteralNode *ILN = static_cast<IntegerLiteralNode *>(N);
5580b57cec5SDimitry Andric   if (ILN->Value != 0)
559349cc55cSDimitry Andric     ILN->output(OB, Flags);
5600b57cec5SDimitry Andric }
5610b57cec5SDimitry Andric 
562349cc55cSDimitry Andric void ArrayTypeNode::outputDimensionsImpl(OutputBuffer &OB,
5630b57cec5SDimitry Andric                                          OutputFlags Flags) const {
5640b57cec5SDimitry Andric   if (Dimensions->Count == 0)
5650b57cec5SDimitry Andric     return;
5660b57cec5SDimitry Andric 
567349cc55cSDimitry Andric   outputOneDimension(OB, Flags, Dimensions->Nodes[0]);
5680b57cec5SDimitry Andric   for (size_t I = 1; I < Dimensions->Count; ++I) {
569349cc55cSDimitry Andric     OB << "][";
570349cc55cSDimitry Andric     outputOneDimension(OB, Flags, Dimensions->Nodes[I]);
5710b57cec5SDimitry Andric   }
5720b57cec5SDimitry Andric }
5730b57cec5SDimitry Andric 
574349cc55cSDimitry Andric void ArrayTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {
575349cc55cSDimitry Andric   OB << "[";
576349cc55cSDimitry Andric   outputDimensionsImpl(OB, Flags);
577349cc55cSDimitry Andric   OB << "]";
5780b57cec5SDimitry Andric 
579349cc55cSDimitry Andric   ElementType->outputPost(OB, Flags);
5800b57cec5SDimitry Andric }
5810b57cec5SDimitry Andric 
582349cc55cSDimitry Andric void SymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const {
583349cc55cSDimitry Andric   Name->output(OB, Flags);
5840b57cec5SDimitry Andric }
5850b57cec5SDimitry Andric 
586349cc55cSDimitry Andric void FunctionSymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const {
587349cc55cSDimitry Andric   Signature->outputPre(OB, Flags);
588349cc55cSDimitry Andric   outputSpaceIfNecessary(OB);
589349cc55cSDimitry Andric   Name->output(OB, Flags);
590349cc55cSDimitry Andric   Signature->outputPost(OB, Flags);
5910b57cec5SDimitry Andric }
5920b57cec5SDimitry Andric 
593349cc55cSDimitry Andric void VariableSymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const {
5948bcb0991SDimitry Andric   const char *AccessSpec = nullptr;
5958bcb0991SDimitry Andric   bool IsStatic = true;
5960b57cec5SDimitry Andric   switch (SC) {
5970b57cec5SDimitry Andric   case StorageClass::PrivateStatic:
5988bcb0991SDimitry Andric     AccessSpec = "private";
5990b57cec5SDimitry Andric     break;
6000b57cec5SDimitry Andric   case StorageClass::PublicStatic:
6018bcb0991SDimitry Andric     AccessSpec = "public";
6020b57cec5SDimitry Andric     break;
6030b57cec5SDimitry Andric   case StorageClass::ProtectedStatic:
6048bcb0991SDimitry Andric     AccessSpec = "protected";
6050b57cec5SDimitry Andric     break;
6060b57cec5SDimitry Andric   default:
6078bcb0991SDimitry Andric     IsStatic = false;
6080b57cec5SDimitry Andric     break;
6090b57cec5SDimitry Andric   }
6108bcb0991SDimitry Andric   if (!(Flags & OF_NoAccessSpecifier) && AccessSpec)
611349cc55cSDimitry Andric     OB << AccessSpec << ": ";
6128bcb0991SDimitry Andric   if (!(Flags & OF_NoMemberType) && IsStatic)
613349cc55cSDimitry Andric     OB << "static ";
6140b57cec5SDimitry Andric 
615349cc55cSDimitry Andric   if (!(Flags & OF_NoVariableType) && Type) {
616349cc55cSDimitry Andric     Type->outputPre(OB, Flags);
617349cc55cSDimitry Andric     outputSpaceIfNecessary(OB);
6180b57cec5SDimitry Andric   }
619349cc55cSDimitry Andric   Name->output(OB, Flags);
620349cc55cSDimitry Andric   if (!(Flags & OF_NoVariableType) && Type)
621349cc55cSDimitry Andric     Type->outputPost(OB, Flags);
6220b57cec5SDimitry Andric }
6230b57cec5SDimitry Andric 
624349cc55cSDimitry Andric void CustomTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
625349cc55cSDimitry Andric   Identifier->output(OB, Flags);
6260b57cec5SDimitry Andric }
627349cc55cSDimitry Andric void CustomTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {}
6280b57cec5SDimitry Andric 
629349cc55cSDimitry Andric void QualifiedNameNode::output(OutputBuffer &OB, OutputFlags Flags) const {
630349cc55cSDimitry Andric   Components->output(OB, Flags, "::");
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric 
633349cc55cSDimitry Andric void RttiBaseClassDescriptorNode::output(OutputBuffer &OB,
6340b57cec5SDimitry Andric                                          OutputFlags Flags) const {
635349cc55cSDimitry Andric   OB << "`RTTI Base Class Descriptor at (";
636349cc55cSDimitry Andric   OB << NVOffset << ", " << VBPtrOffset << ", " << VBTableOffset << ", "
6370b57cec5SDimitry Andric      << this->Flags;
638349cc55cSDimitry Andric   OB << ")'";
6390b57cec5SDimitry Andric }
6400b57cec5SDimitry Andric 
641349cc55cSDimitry Andric void LocalStaticGuardVariableNode::output(OutputBuffer &OB,
6420b57cec5SDimitry Andric                                           OutputFlags Flags) const {
643349cc55cSDimitry Andric   Name->output(OB, Flags);
6440b57cec5SDimitry Andric }
6450b57cec5SDimitry Andric 
646349cc55cSDimitry Andric void VcallThunkIdentifierNode::output(OutputBuffer &OB,
6470b57cec5SDimitry Andric                                       OutputFlags Flags) const {
648349cc55cSDimitry Andric   OB << "`vcall'{" << OffsetInVTable << ", {flat}}";
6490b57cec5SDimitry Andric }
6500b57cec5SDimitry Andric 
651349cc55cSDimitry Andric void SpecialTableSymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const {
652349cc55cSDimitry Andric   outputQualifiers(OB, Quals, false, true);
653349cc55cSDimitry Andric   Name->output(OB, Flags);
6540b57cec5SDimitry Andric   if (TargetName) {
655349cc55cSDimitry Andric     OB << "{for `";
656349cc55cSDimitry Andric     TargetName->output(OB, Flags);
657349cc55cSDimitry Andric     OB << "'}";
6580b57cec5SDimitry Andric   }
6590b57cec5SDimitry Andric }
660