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.
outputSpaceIfNecessary(OutputBuffer & OB)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
outputSingleQualifier(OutputBuffer & OB,Qualifiers Q)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
outputQualifierIfPresent(OutputBuffer & OB,Qualifiers Q,Qualifiers Mask,bool NeedSpace)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
outputQualifiers(OutputBuffer & OB,Qualifiers Q,bool SpaceBefore,bool SpaceAfter)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
outputCallingConvention(OutputBuffer & OB,CallingConv CC)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
toString(OutputFlags Flags) const1200b57cec5SDimitry Andric std::string Node::toString(OutputFlags Flags) const {
121349cc55cSDimitry Andric OutputBuffer OB;
122349cc55cSDimitry Andric this->output(OB, Flags);
12306c3fb27SDimitry Andric std::string_view SV = OB;
12481ad6265SDimitry Andric std::string Owned(SV.begin(), SV.end());
125349cc55cSDimitry Andric std::free(OB.getBuffer());
126fe6060f1SDimitry Andric return Owned;
1270b57cec5SDimitry Andric }
1280b57cec5SDimitry Andric
outputPre(OutputBuffer & OB,OutputFlags Flags) const129349cc55cSDimitry Andric void PrimitiveTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
1300b57cec5SDimitry Andric switch (PrimKind) {
1310b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Void, "void");
1320b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Bool, "bool");
1330b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char, "char");
1340b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Schar, "signed char");
1350b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uchar, "unsigned char");
1360b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char8, "char8_t");
1370b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char16, "char16_t");
1380b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char32, "char32_t");
1390b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Short, "short");
1400b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ushort, "unsigned short");
1410b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Int, "int");
1420b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uint, "unsigned int");
1430b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Long, "long");
1440b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ulong, "unsigned long");
1450b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Int64, "__int64");
1460b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uint64, "unsigned __int64");
1470b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Wchar, "wchar_t");
1480b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Float, "float");
1490b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Double, "double");
1500b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ldouble, "long double");
1510b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Nullptr, "std::nullptr_t");
1520b57cec5SDimitry Andric }
153349cc55cSDimitry Andric outputQualifiers(OB, Quals, true, false);
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const156349cc55cSDimitry Andric void NodeArrayNode::output(OutputBuffer &OB, OutputFlags Flags) const {
157349cc55cSDimitry Andric output(OB, Flags, ", ");
1580b57cec5SDimitry Andric }
1590b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags,std::string_view Separator) const160349cc55cSDimitry Andric void NodeArrayNode::output(OutputBuffer &OB, OutputFlags Flags,
16106c3fb27SDimitry Andric std::string_view Separator) const {
1620b57cec5SDimitry Andric if (Count == 0)
1630b57cec5SDimitry Andric return;
1640b57cec5SDimitry Andric if (Nodes[0])
165349cc55cSDimitry Andric Nodes[0]->output(OB, Flags);
1660b57cec5SDimitry Andric for (size_t I = 1; I < Count; ++I) {
167349cc55cSDimitry Andric OB << Separator;
168349cc55cSDimitry Andric Nodes[I]->output(OB, Flags);
1690b57cec5SDimitry Andric }
1700b57cec5SDimitry Andric }
1710b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const172349cc55cSDimitry Andric void EncodedStringLiteralNode::output(OutputBuffer &OB,
1730b57cec5SDimitry Andric OutputFlags Flags) const {
1740b57cec5SDimitry Andric switch (Char) {
1750b57cec5SDimitry Andric case CharKind::Wchar:
176349cc55cSDimitry Andric OB << "L\"";
1770b57cec5SDimitry Andric break;
1780b57cec5SDimitry Andric case CharKind::Char:
179349cc55cSDimitry Andric OB << "\"";
1800b57cec5SDimitry Andric break;
1810b57cec5SDimitry Andric case CharKind::Char16:
182349cc55cSDimitry Andric OB << "u\"";
1830b57cec5SDimitry Andric break;
1840b57cec5SDimitry Andric case CharKind::Char32:
185349cc55cSDimitry Andric OB << "U\"";
1860b57cec5SDimitry Andric break;
1870b57cec5SDimitry Andric }
188349cc55cSDimitry Andric OB << DecodedString << "\"";
1890b57cec5SDimitry Andric if (IsTruncated)
190349cc55cSDimitry Andric OB << "...";
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const193349cc55cSDimitry Andric void IntegerLiteralNode::output(OutputBuffer &OB, OutputFlags Flags) const {
1940b57cec5SDimitry Andric if (IsNegative)
195349cc55cSDimitry Andric OB << '-';
196349cc55cSDimitry Andric OB << Value;
1970b57cec5SDimitry Andric }
1980b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const199349cc55cSDimitry Andric void TemplateParameterReferenceNode::output(OutputBuffer &OB,
2000b57cec5SDimitry Andric OutputFlags Flags) const {
2010b57cec5SDimitry Andric if (ThunkOffsetCount > 0)
202349cc55cSDimitry Andric OB << "{";
2030b57cec5SDimitry Andric else if (Affinity == PointerAffinity::Pointer)
204349cc55cSDimitry Andric OB << "&";
2050b57cec5SDimitry Andric
2060b57cec5SDimitry Andric if (Symbol) {
207349cc55cSDimitry Andric Symbol->output(OB, Flags);
2080b57cec5SDimitry Andric if (ThunkOffsetCount > 0)
209349cc55cSDimitry Andric OB << ", ";
2100b57cec5SDimitry Andric }
2110b57cec5SDimitry Andric
2120b57cec5SDimitry Andric if (ThunkOffsetCount > 0)
213349cc55cSDimitry Andric OB << ThunkOffsets[0];
2140b57cec5SDimitry Andric for (int I = 1; I < ThunkOffsetCount; ++I) {
215349cc55cSDimitry Andric OB << ", " << ThunkOffsets[I];
2160b57cec5SDimitry Andric }
2170b57cec5SDimitry Andric if (ThunkOffsetCount > 0)
218349cc55cSDimitry Andric OB << "}";
2190b57cec5SDimitry Andric }
2200b57cec5SDimitry Andric
outputTemplateParameters(OutputBuffer & OB,OutputFlags Flags) const221349cc55cSDimitry Andric void IdentifierNode::outputTemplateParameters(OutputBuffer &OB,
2220b57cec5SDimitry Andric OutputFlags Flags) const {
2230b57cec5SDimitry Andric if (!TemplateParams)
2240b57cec5SDimitry Andric return;
225349cc55cSDimitry Andric OB << "<";
226349cc55cSDimitry Andric TemplateParams->output(OB, Flags);
227349cc55cSDimitry Andric OB << ">";
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const230349cc55cSDimitry Andric void DynamicStructorIdentifierNode::output(OutputBuffer &OB,
2310b57cec5SDimitry Andric OutputFlags Flags) const {
2320b57cec5SDimitry Andric if (IsDestructor)
233349cc55cSDimitry Andric OB << "`dynamic atexit destructor for ";
2340b57cec5SDimitry Andric else
235349cc55cSDimitry Andric OB << "`dynamic initializer for ";
2360b57cec5SDimitry Andric
2370b57cec5SDimitry Andric if (Variable) {
238349cc55cSDimitry Andric OB << "`";
239349cc55cSDimitry Andric Variable->output(OB, Flags);
240349cc55cSDimitry Andric OB << "''";
2410b57cec5SDimitry Andric } else {
242349cc55cSDimitry Andric OB << "'";
243349cc55cSDimitry Andric Name->output(OB, Flags);
244349cc55cSDimitry Andric OB << "''";
2450b57cec5SDimitry Andric }
2460b57cec5SDimitry Andric }
2470b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const248349cc55cSDimitry Andric void NamedIdentifierNode::output(OutputBuffer &OB, OutputFlags Flags) const {
249349cc55cSDimitry Andric OB << Name;
250349cc55cSDimitry Andric outputTemplateParameters(OB, Flags);
2510b57cec5SDimitry Andric }
2520b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const253349cc55cSDimitry Andric void IntrinsicFunctionIdentifierNode::output(OutputBuffer &OB,
2540b57cec5SDimitry Andric OutputFlags Flags) const {
2550b57cec5SDimitry Andric switch (Operator) {
2560b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, New, "operator new");
2570b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Delete, "operator delete");
2580b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Assign, "operator=");
2590b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, RightShift, "operator>>");
2600b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LeftShift, "operator<<");
2610b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalNot, "operator!");
2620b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Equals, "operator==");
2630b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, NotEquals, "operator!=");
2640b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArraySubscript,
2650b57cec5SDimitry Andric "operator[]");
2660b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Pointer, "operator->");
2670b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Increment, "operator++");
2680b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Decrement, "operator--");
2690b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Minus, "operator-");
2700b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Plus, "operator+");
2710b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Dereference, "operator*");
2720b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseAnd, "operator&");
2730b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, MemberPointer,
2740b57cec5SDimitry Andric "operator->*");
2750b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Divide, "operator/");
2760b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Modulus, "operator%");
2770b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LessThan, "operator<");
2780b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LessThanEqual, "operator<=");
2790b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, GreaterThan, "operator>");
2800b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, GreaterThanEqual,
2810b57cec5SDimitry Andric "operator>=");
2820b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Comma, "operator,");
2830b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Parens, "operator()");
2840b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseNot, "operator~");
2850b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseXor, "operator^");
2860b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseOr, "operator|");
2870b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalAnd, "operator&&");
2880b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalOr, "operator||");
2890b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, TimesEqual, "operator*=");
2900b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, PlusEqual, "operator+=");
2910b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, MinusEqual, "operator-=");
2920b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, DivEqual, "operator/=");
2930b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ModEqual, "operator%=");
2940b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, RshEqual, "operator>>=");
2950b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LshEqual, "operator<<=");
2960b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseAndEqual,
2970b57cec5SDimitry Andric "operator&=");
2980b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseOrEqual,
2990b57cec5SDimitry Andric "operator|=");
3000b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseXorEqual,
3010b57cec5SDimitry Andric "operator^=");
3020b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VbaseDtor, "`vbase dtor'");
3030b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecDelDtor,
3040b57cec5SDimitry Andric "`vector deleting dtor'");
3050b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, DefaultCtorClosure,
3060b57cec5SDimitry Andric "`default ctor closure'");
3070b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ScalarDelDtor,
3080b57cec5SDimitry Andric "`scalar deleting dtor'");
3090b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecCtorIter,
3100b57cec5SDimitry Andric "`vector ctor iterator'");
3110b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecDtorIter,
3120b57cec5SDimitry Andric "`vector dtor iterator'");
3130b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecVbaseCtorIter,
3140b57cec5SDimitry Andric "`vector vbase ctor iterator'");
3150b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VdispMap,
3160b57cec5SDimitry Andric "`virtual displacement map'");
3170b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecCtorIter,
3180b57cec5SDimitry Andric "`eh vector ctor iterator'");
3190b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecDtorIter,
3200b57cec5SDimitry Andric "`eh vector dtor iterator'");
3210b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecVbaseCtorIter,
3220b57cec5SDimitry Andric "`eh vector vbase ctor iterator'");
3230b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, CopyCtorClosure,
3240b57cec5SDimitry Andric "`copy ctor closure'");
3250b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LocalVftableCtorClosure,
3260b57cec5SDimitry Andric "`local vftable ctor closure'");
3270b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArrayNew, "operator new[]");
3280b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArrayDelete,
3290b57cec5SDimitry Andric "operator delete[]");
3300b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorCtorIter,
3310b57cec5SDimitry Andric "`managed vector ctor iterator'");
3320b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorDtorIter,
3330b57cec5SDimitry Andric "`managed vector dtor iterator'");
3340b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVectorCopyCtorIter,
3350b57cec5SDimitry Andric "`EH vector copy ctor iterator'");
3360b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVectorVbaseCopyCtorIter,
3370b57cec5SDimitry Andric "`EH vector vbase copy ctor iterator'");
3380b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VectorCopyCtorIter,
3390b57cec5SDimitry Andric "`vector copy ctor iterator'");
3400b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VectorVbaseCopyCtorIter,
3410b57cec5SDimitry Andric "`vector vbase copy constructor iterator'");
3420b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorVbaseCopyCtorIter,
3430b57cec5SDimitry Andric "`managed vector vbase copy constructor iterator'");
3440b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, CoAwait,
3450b57cec5SDimitry Andric "operator co_await");
3460b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Spaceship, "operator<=>");
3470b57cec5SDimitry Andric case IntrinsicFunctionKind::MaxIntrinsic:
3480b57cec5SDimitry Andric case IntrinsicFunctionKind::None:
3490b57cec5SDimitry Andric break;
3500b57cec5SDimitry Andric }
351349cc55cSDimitry Andric outputTemplateParameters(OB, Flags);
3520b57cec5SDimitry Andric }
3530b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const354349cc55cSDimitry Andric void LocalStaticGuardIdentifierNode::output(OutputBuffer &OB,
3550b57cec5SDimitry Andric OutputFlags Flags) const {
3560b57cec5SDimitry Andric if (IsThread)
357349cc55cSDimitry Andric OB << "`local static thread guard'";
3580b57cec5SDimitry Andric else
359349cc55cSDimitry Andric OB << "`local static guard'";
3600b57cec5SDimitry Andric if (ScopeIndex > 0)
361349cc55cSDimitry Andric OB << "{" << ScopeIndex << "}";
3620b57cec5SDimitry Andric }
3630b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const364349cc55cSDimitry Andric void ConversionOperatorIdentifierNode::output(OutputBuffer &OB,
3650b57cec5SDimitry Andric OutputFlags Flags) const {
366349cc55cSDimitry Andric OB << "operator";
367349cc55cSDimitry Andric outputTemplateParameters(OB, Flags);
368349cc55cSDimitry Andric OB << " ";
369349cc55cSDimitry Andric TargetType->output(OB, Flags);
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const372349cc55cSDimitry Andric void StructorIdentifierNode::output(OutputBuffer &OB, OutputFlags Flags) const {
3730b57cec5SDimitry Andric if (IsDestructor)
374349cc55cSDimitry Andric OB << "~";
375349cc55cSDimitry Andric Class->output(OB, Flags);
376349cc55cSDimitry Andric outputTemplateParameters(OB, Flags);
3770b57cec5SDimitry Andric }
3780b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const379349cc55cSDimitry Andric void LiteralOperatorIdentifierNode::output(OutputBuffer &OB,
3800b57cec5SDimitry Andric OutputFlags Flags) const {
381349cc55cSDimitry Andric OB << "operator \"\"" << Name;
382349cc55cSDimitry Andric outputTemplateParameters(OB, Flags);
3830b57cec5SDimitry Andric }
3840b57cec5SDimitry Andric
outputPre(OutputBuffer & OB,OutputFlags Flags) const385349cc55cSDimitry Andric void FunctionSignatureNode::outputPre(OutputBuffer &OB,
3860b57cec5SDimitry Andric OutputFlags Flags) const {
3878bcb0991SDimitry Andric if (!(Flags & OF_NoAccessSpecifier)) {
3880b57cec5SDimitry Andric if (FunctionClass & FC_Public)
389349cc55cSDimitry Andric OB << "public: ";
3900b57cec5SDimitry Andric if (FunctionClass & FC_Protected)
391349cc55cSDimitry Andric OB << "protected: ";
3920b57cec5SDimitry Andric if (FunctionClass & FC_Private)
393349cc55cSDimitry Andric OB << "private: ";
3948bcb0991SDimitry Andric }
3950b57cec5SDimitry Andric
3968bcb0991SDimitry Andric if (!(Flags & OF_NoMemberType)) {
3970b57cec5SDimitry Andric if (!(FunctionClass & FC_Global)) {
3980b57cec5SDimitry Andric if (FunctionClass & FC_Static)
399349cc55cSDimitry Andric OB << "static ";
4000b57cec5SDimitry Andric }
4010b57cec5SDimitry Andric if (FunctionClass & FC_Virtual)
402349cc55cSDimitry Andric OB << "virtual ";
4030b57cec5SDimitry Andric
4040b57cec5SDimitry Andric if (FunctionClass & FC_ExternC)
405349cc55cSDimitry Andric OB << "extern \"C\" ";
4068bcb0991SDimitry Andric }
4070b57cec5SDimitry Andric
4088bcb0991SDimitry Andric if (!(Flags & OF_NoReturnType) && ReturnType) {
409349cc55cSDimitry Andric ReturnType->outputPre(OB, Flags);
410349cc55cSDimitry Andric OB << " ";
4110b57cec5SDimitry Andric }
4120b57cec5SDimitry Andric
4130b57cec5SDimitry Andric if (!(Flags & OF_NoCallingConvention))
414349cc55cSDimitry Andric outputCallingConvention(OB, CallConvention);
4150b57cec5SDimitry Andric }
4160b57cec5SDimitry Andric
outputPost(OutputBuffer & OB,OutputFlags Flags) const417349cc55cSDimitry Andric void FunctionSignatureNode::outputPost(OutputBuffer &OB,
4180b57cec5SDimitry Andric OutputFlags Flags) const {
4190b57cec5SDimitry Andric if (!(FunctionClass & FC_NoParameterList)) {
420349cc55cSDimitry Andric OB << "(";
4210b57cec5SDimitry Andric if (Params)
422349cc55cSDimitry Andric Params->output(OB, Flags);
4230b57cec5SDimitry Andric else
424349cc55cSDimitry Andric OB << "void";
4250b57cec5SDimitry Andric
4260b57cec5SDimitry Andric if (IsVariadic) {
427349cc55cSDimitry Andric if (OB.back() != '(')
428349cc55cSDimitry Andric OB << ", ";
429349cc55cSDimitry Andric OB << "...";
4300b57cec5SDimitry Andric }
431349cc55cSDimitry Andric OB << ")";
4320b57cec5SDimitry Andric }
4330b57cec5SDimitry Andric
4340b57cec5SDimitry Andric if (Quals & Q_Const)
435349cc55cSDimitry Andric OB << " const";
4360b57cec5SDimitry Andric if (Quals & Q_Volatile)
437349cc55cSDimitry Andric OB << " volatile";
4380b57cec5SDimitry Andric if (Quals & Q_Restrict)
439349cc55cSDimitry Andric OB << " __restrict";
4400b57cec5SDimitry Andric if (Quals & Q_Unaligned)
441349cc55cSDimitry Andric OB << " __unaligned";
4420b57cec5SDimitry Andric
4430b57cec5SDimitry Andric if (IsNoexcept)
444349cc55cSDimitry Andric OB << " noexcept";
4450b57cec5SDimitry Andric
4460b57cec5SDimitry Andric if (RefQualifier == FunctionRefQualifier::Reference)
447349cc55cSDimitry Andric OB << " &";
4480b57cec5SDimitry Andric else if (RefQualifier == FunctionRefQualifier::RValueReference)
449349cc55cSDimitry Andric OB << " &&";
4500b57cec5SDimitry Andric
4518bcb0991SDimitry Andric if (!(Flags & OF_NoReturnType) && ReturnType)
452349cc55cSDimitry Andric ReturnType->outputPost(OB, Flags);
4530b57cec5SDimitry Andric }
4540b57cec5SDimitry Andric
outputPre(OutputBuffer & OB,OutputFlags Flags) const455349cc55cSDimitry Andric void ThunkSignatureNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
456349cc55cSDimitry Andric OB << "[thunk]: ";
4570b57cec5SDimitry Andric
458349cc55cSDimitry Andric FunctionSignatureNode::outputPre(OB, Flags);
4590b57cec5SDimitry Andric }
4600b57cec5SDimitry Andric
outputPost(OutputBuffer & OB,OutputFlags Flags) const461349cc55cSDimitry Andric void ThunkSignatureNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {
4620b57cec5SDimitry Andric if (FunctionClass & FC_StaticThisAdjust) {
463349cc55cSDimitry Andric OB << "`adjustor{" << ThisAdjust.StaticOffset << "}'";
4640b57cec5SDimitry Andric } else if (FunctionClass & FC_VirtualThisAdjust) {
4650b57cec5SDimitry Andric if (FunctionClass & FC_VirtualThisAdjustEx) {
466349cc55cSDimitry Andric OB << "`vtordispex{" << ThisAdjust.VBPtrOffset << ", "
4670b57cec5SDimitry Andric << ThisAdjust.VBOffsetOffset << ", " << ThisAdjust.VtordispOffset
4680b57cec5SDimitry Andric << ", " << ThisAdjust.StaticOffset << "}'";
4690b57cec5SDimitry Andric } else {
470349cc55cSDimitry Andric OB << "`vtordisp{" << ThisAdjust.VtordispOffset << ", "
4710b57cec5SDimitry Andric << ThisAdjust.StaticOffset << "}'";
4720b57cec5SDimitry Andric }
4730b57cec5SDimitry Andric }
4740b57cec5SDimitry Andric
475349cc55cSDimitry Andric FunctionSignatureNode::outputPost(OB, Flags);
4760b57cec5SDimitry Andric }
4770b57cec5SDimitry Andric
outputPre(OutputBuffer & OB,OutputFlags Flags) const478349cc55cSDimitry Andric void PointerTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
4790b57cec5SDimitry Andric if (Pointee->kind() == NodeKind::FunctionSignature) {
4800b57cec5SDimitry Andric // If this is a pointer to a function, don't output the calling convention.
4810b57cec5SDimitry Andric // It needs to go inside the parentheses.
4820b57cec5SDimitry Andric const FunctionSignatureNode *Sig =
4830b57cec5SDimitry Andric static_cast<const FunctionSignatureNode *>(Pointee);
484349cc55cSDimitry Andric Sig->outputPre(OB, OF_NoCallingConvention);
4850b57cec5SDimitry Andric } else
486349cc55cSDimitry Andric Pointee->outputPre(OB, Flags);
4870b57cec5SDimitry Andric
488349cc55cSDimitry Andric outputSpaceIfNecessary(OB);
4890b57cec5SDimitry Andric
4900b57cec5SDimitry Andric if (Quals & Q_Unaligned)
491349cc55cSDimitry Andric OB << "__unaligned ";
4920b57cec5SDimitry Andric
4930b57cec5SDimitry Andric if (Pointee->kind() == NodeKind::ArrayType) {
494349cc55cSDimitry Andric OB << "(";
4950b57cec5SDimitry Andric } else if (Pointee->kind() == NodeKind::FunctionSignature) {
496349cc55cSDimitry Andric OB << "(";
4970b57cec5SDimitry Andric const FunctionSignatureNode *Sig =
4980b57cec5SDimitry Andric static_cast<const FunctionSignatureNode *>(Pointee);
499349cc55cSDimitry Andric outputCallingConvention(OB, Sig->CallConvention);
500349cc55cSDimitry Andric OB << " ";
5010b57cec5SDimitry Andric }
5020b57cec5SDimitry Andric
5030b57cec5SDimitry Andric if (ClassParent) {
504349cc55cSDimitry Andric ClassParent->output(OB, Flags);
505349cc55cSDimitry Andric OB << "::";
5060b57cec5SDimitry Andric }
5070b57cec5SDimitry Andric
5080b57cec5SDimitry Andric switch (Affinity) {
5090b57cec5SDimitry Andric case PointerAffinity::Pointer:
510349cc55cSDimitry Andric OB << "*";
5110b57cec5SDimitry Andric break;
5120b57cec5SDimitry Andric case PointerAffinity::Reference:
513349cc55cSDimitry Andric OB << "&";
5140b57cec5SDimitry Andric break;
5150b57cec5SDimitry Andric case PointerAffinity::RValueReference:
516349cc55cSDimitry Andric OB << "&&";
5170b57cec5SDimitry Andric break;
5180b57cec5SDimitry Andric default:
5190b57cec5SDimitry Andric assert(false);
5200b57cec5SDimitry Andric }
521349cc55cSDimitry Andric outputQualifiers(OB, Quals, false, false);
5220b57cec5SDimitry Andric }
5230b57cec5SDimitry Andric
outputPost(OutputBuffer & OB,OutputFlags Flags) const524349cc55cSDimitry Andric void PointerTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {
5250b57cec5SDimitry Andric if (Pointee->kind() == NodeKind::ArrayType ||
5260b57cec5SDimitry Andric Pointee->kind() == NodeKind::FunctionSignature)
527349cc55cSDimitry Andric OB << ")";
5280b57cec5SDimitry Andric
529349cc55cSDimitry Andric Pointee->outputPost(OB, Flags);
5300b57cec5SDimitry Andric }
5310b57cec5SDimitry Andric
outputPre(OutputBuffer & OB,OutputFlags Flags) const532349cc55cSDimitry Andric void TagTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
5330b57cec5SDimitry Andric if (!(Flags & OF_NoTagSpecifier)) {
5340b57cec5SDimitry Andric switch (Tag) {
5350b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(TagKind, Class, "class");
5360b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(TagKind, Struct, "struct");
5370b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(TagKind, Union, "union");
5380b57cec5SDimitry Andric OUTPUT_ENUM_CLASS_VALUE(TagKind, Enum, "enum");
5390b57cec5SDimitry Andric }
540349cc55cSDimitry Andric OB << " ";
5410b57cec5SDimitry Andric }
542349cc55cSDimitry Andric QualifiedName->output(OB, Flags);
543349cc55cSDimitry Andric outputQualifiers(OB, Quals, true, false);
5440b57cec5SDimitry Andric }
5450b57cec5SDimitry Andric
outputPost(OutputBuffer & OB,OutputFlags Flags) const546349cc55cSDimitry Andric void TagTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {}
5470b57cec5SDimitry Andric
outputPre(OutputBuffer & OB,OutputFlags Flags) const548349cc55cSDimitry Andric void ArrayTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
549349cc55cSDimitry Andric ElementType->outputPre(OB, Flags);
550349cc55cSDimitry Andric outputQualifiers(OB, Quals, true, false);
5510b57cec5SDimitry Andric }
5520b57cec5SDimitry Andric
outputOneDimension(OutputBuffer & OB,OutputFlags Flags,Node * N) const553349cc55cSDimitry Andric void ArrayTypeNode::outputOneDimension(OutputBuffer &OB, OutputFlags Flags,
5540b57cec5SDimitry Andric Node *N) const {
5550b57cec5SDimitry Andric assert(N->kind() == NodeKind::IntegerLiteral);
5560b57cec5SDimitry Andric IntegerLiteralNode *ILN = static_cast<IntegerLiteralNode *>(N);
5570b57cec5SDimitry Andric if (ILN->Value != 0)
558349cc55cSDimitry Andric ILN->output(OB, Flags);
5590b57cec5SDimitry Andric }
5600b57cec5SDimitry Andric
outputDimensionsImpl(OutputBuffer & OB,OutputFlags Flags) const561349cc55cSDimitry Andric void ArrayTypeNode::outputDimensionsImpl(OutputBuffer &OB,
5620b57cec5SDimitry Andric OutputFlags Flags) const {
5630b57cec5SDimitry Andric if (Dimensions->Count == 0)
5640b57cec5SDimitry Andric return;
5650b57cec5SDimitry Andric
566349cc55cSDimitry Andric outputOneDimension(OB, Flags, Dimensions->Nodes[0]);
5670b57cec5SDimitry Andric for (size_t I = 1; I < Dimensions->Count; ++I) {
568349cc55cSDimitry Andric OB << "][";
569349cc55cSDimitry Andric outputOneDimension(OB, Flags, Dimensions->Nodes[I]);
5700b57cec5SDimitry Andric }
5710b57cec5SDimitry Andric }
5720b57cec5SDimitry Andric
outputPost(OutputBuffer & OB,OutputFlags Flags) const573349cc55cSDimitry Andric void ArrayTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {
574349cc55cSDimitry Andric OB << "[";
575349cc55cSDimitry Andric outputDimensionsImpl(OB, Flags);
576349cc55cSDimitry Andric OB << "]";
5770b57cec5SDimitry Andric
578349cc55cSDimitry Andric ElementType->outputPost(OB, Flags);
5790b57cec5SDimitry Andric }
5800b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const581349cc55cSDimitry Andric void SymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const {
582349cc55cSDimitry Andric Name->output(OB, Flags);
5830b57cec5SDimitry Andric }
5840b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const585349cc55cSDimitry Andric void FunctionSymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const {
586349cc55cSDimitry Andric Signature->outputPre(OB, Flags);
587349cc55cSDimitry Andric outputSpaceIfNecessary(OB);
588349cc55cSDimitry Andric Name->output(OB, Flags);
589349cc55cSDimitry Andric Signature->outputPost(OB, Flags);
5900b57cec5SDimitry Andric }
5910b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const592349cc55cSDimitry Andric void VariableSymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const {
5938bcb0991SDimitry Andric const char *AccessSpec = nullptr;
5948bcb0991SDimitry Andric bool IsStatic = true;
5950b57cec5SDimitry Andric switch (SC) {
5960b57cec5SDimitry Andric case StorageClass::PrivateStatic:
5978bcb0991SDimitry Andric AccessSpec = "private";
5980b57cec5SDimitry Andric break;
5990b57cec5SDimitry Andric case StorageClass::PublicStatic:
6008bcb0991SDimitry Andric AccessSpec = "public";
6010b57cec5SDimitry Andric break;
6020b57cec5SDimitry Andric case StorageClass::ProtectedStatic:
6038bcb0991SDimitry Andric AccessSpec = "protected";
6040b57cec5SDimitry Andric break;
6050b57cec5SDimitry Andric default:
6068bcb0991SDimitry Andric IsStatic = false;
6070b57cec5SDimitry Andric break;
6080b57cec5SDimitry Andric }
6098bcb0991SDimitry Andric if (!(Flags & OF_NoAccessSpecifier) && AccessSpec)
610349cc55cSDimitry Andric OB << AccessSpec << ": ";
6118bcb0991SDimitry Andric if (!(Flags & OF_NoMemberType) && IsStatic)
612349cc55cSDimitry Andric OB << "static ";
6130b57cec5SDimitry Andric
614349cc55cSDimitry Andric if (!(Flags & OF_NoVariableType) && Type) {
615349cc55cSDimitry Andric Type->outputPre(OB, Flags);
616349cc55cSDimitry Andric outputSpaceIfNecessary(OB);
6170b57cec5SDimitry Andric }
618349cc55cSDimitry Andric Name->output(OB, Flags);
619349cc55cSDimitry Andric if (!(Flags & OF_NoVariableType) && Type)
620349cc55cSDimitry Andric Type->outputPost(OB, Flags);
6210b57cec5SDimitry Andric }
6220b57cec5SDimitry Andric
outputPre(OutputBuffer & OB,OutputFlags Flags) const623349cc55cSDimitry Andric void CustomTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const {
624349cc55cSDimitry Andric Identifier->output(OB, Flags);
6250b57cec5SDimitry Andric }
outputPost(OutputBuffer & OB,OutputFlags Flags) const626349cc55cSDimitry Andric void CustomTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {}
6270b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const628349cc55cSDimitry Andric void QualifiedNameNode::output(OutputBuffer &OB, OutputFlags Flags) const {
629349cc55cSDimitry Andric Components->output(OB, Flags, "::");
6300b57cec5SDimitry Andric }
6310b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const632349cc55cSDimitry Andric void RttiBaseClassDescriptorNode::output(OutputBuffer &OB,
6330b57cec5SDimitry Andric OutputFlags Flags) const {
634349cc55cSDimitry Andric OB << "`RTTI Base Class Descriptor at (";
635349cc55cSDimitry Andric OB << NVOffset << ", " << VBPtrOffset << ", " << VBTableOffset << ", "
6360b57cec5SDimitry Andric << this->Flags;
637349cc55cSDimitry Andric OB << ")'";
6380b57cec5SDimitry Andric }
6390b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const640349cc55cSDimitry Andric void LocalStaticGuardVariableNode::output(OutputBuffer &OB,
6410b57cec5SDimitry Andric OutputFlags Flags) const {
642349cc55cSDimitry Andric Name->output(OB, Flags);
6430b57cec5SDimitry Andric }
6440b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const645349cc55cSDimitry Andric void VcallThunkIdentifierNode::output(OutputBuffer &OB,
6460b57cec5SDimitry Andric OutputFlags Flags) const {
647349cc55cSDimitry Andric OB << "`vcall'{" << OffsetInVTable << ", {flat}}";
6480b57cec5SDimitry Andric }
6490b57cec5SDimitry Andric
output(OutputBuffer & OB,OutputFlags Flags) const650349cc55cSDimitry Andric void SpecialTableSymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const {
651349cc55cSDimitry Andric outputQualifiers(OB, Quals, false, true);
652349cc55cSDimitry Andric Name->output(OB, Flags);
6530b57cec5SDimitry Andric if (TargetName) {
654349cc55cSDimitry Andric OB << "{for `";
655349cc55cSDimitry Andric TargetName->output(OB, Flags);
656349cc55cSDimitry Andric OB << "'}";
6570b57cec5SDimitry Andric }
6580b57cec5SDimitry Andric }
659