File: | build/llvm-toolchain-snapshot-15~++20220420111733+e13d2efed663/llvm/lib/Demangle/MicrosoftDemangleNodes.cpp |
Warning: | line 72, column 3 Value stored to 'SpaceBefore' is never read |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | //===- MicrosoftDemangle.cpp ----------------------------------------------===// |
2 | // |
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
4 | // See https://llvm.org/LICENSE.txt for license information. |
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | // This file defines a demangler for MSVC-style mangled symbols. |
10 | // |
11 | //===----------------------------------------------------------------------===// |
12 | |
13 | #include "llvm/Demangle/MicrosoftDemangleNodes.h" |
14 | #include "llvm/Demangle/Utility.h" |
15 | #include <cctype> |
16 | #include <string> |
17 | |
18 | using namespace llvm; |
19 | using namespace ms_demangle; |
20 | |
21 | #define OUTPUT_ENUM_CLASS_VALUE(Enum, Value, Desc)case Enum::Value: OB << Desc; break; \ |
22 | case Enum::Value: \ |
23 | OB << Desc; \ |
24 | break; |
25 | |
26 | // Writes a space if the last token does not end with a punctuation. |
27 | static void outputSpaceIfNecessary(OutputBuffer &OB) { |
28 | if (OB.empty()) |
29 | return; |
30 | |
31 | char C = OB.back(); |
32 | if (std::isalnum(C) || C == '>') |
33 | OB << " "; |
34 | } |
35 | |
36 | static void outputSingleQualifier(OutputBuffer &OB, Qualifiers Q) { |
37 | switch (Q) { |
38 | case Q_Const: |
39 | OB << "const"; |
40 | break; |
41 | case Q_Volatile: |
42 | OB << "volatile"; |
43 | break; |
44 | case Q_Restrict: |
45 | OB << "__restrict"; |
46 | break; |
47 | default: |
48 | break; |
49 | } |
50 | } |
51 | |
52 | static bool outputQualifierIfPresent(OutputBuffer &OB, Qualifiers Q, |
53 | Qualifiers Mask, bool NeedSpace) { |
54 | if (!(Q & Mask)) |
55 | return NeedSpace; |
56 | |
57 | if (NeedSpace) |
58 | OB << " "; |
59 | |
60 | outputSingleQualifier(OB, Mask); |
61 | return true; |
62 | } |
63 | |
64 | static void outputQualifiers(OutputBuffer &OB, Qualifiers Q, bool SpaceBefore, |
65 | bool SpaceAfter) { |
66 | if (Q == Q_None) |
67 | return; |
68 | |
69 | size_t Pos1 = OB.getCurrentPosition(); |
70 | SpaceBefore = outputQualifierIfPresent(OB, Q, Q_Const, SpaceBefore); |
71 | SpaceBefore = outputQualifierIfPresent(OB, Q, Q_Volatile, SpaceBefore); |
72 | SpaceBefore = outputQualifierIfPresent(OB, Q, Q_Restrict, SpaceBefore); |
Value stored to 'SpaceBefore' is never read | |
73 | size_t Pos2 = OB.getCurrentPosition(); |
74 | if (SpaceAfter && Pos2 > Pos1) |
75 | OB << " "; |
76 | } |
77 | |
78 | static void outputCallingConvention(OutputBuffer &OB, CallingConv CC) { |
79 | outputSpaceIfNecessary(OB); |
80 | |
81 | switch (CC) { |
82 | case CallingConv::Cdecl: |
83 | OB << "__cdecl"; |
84 | break; |
85 | case CallingConv::Fastcall: |
86 | OB << "__fastcall"; |
87 | break; |
88 | case CallingConv::Pascal: |
89 | OB << "__pascal"; |
90 | break; |
91 | case CallingConv::Regcall: |
92 | OB << "__regcall"; |
93 | break; |
94 | case CallingConv::Stdcall: |
95 | OB << "__stdcall"; |
96 | break; |
97 | case CallingConv::Thiscall: |
98 | OB << "__thiscall"; |
99 | break; |
100 | case CallingConv::Eabi: |
101 | OB << "__eabi"; |
102 | break; |
103 | case CallingConv::Vectorcall: |
104 | OB << "__vectorcall"; |
105 | break; |
106 | case CallingConv::Clrcall: |
107 | OB << "__clrcall"; |
108 | break; |
109 | case CallingConv::Swift: |
110 | OB << "__attribute__((__swiftcall__)) "; |
111 | break; |
112 | case CallingConv::SwiftAsync: |
113 | OB << "__attribute__((__swiftasynccall__)) "; |
114 | break; |
115 | default: |
116 | break; |
117 | } |
118 | } |
119 | |
120 | std::string Node::toString(OutputFlags Flags) const { |
121 | OutputBuffer OB; |
122 | initializeOutputBuffer(nullptr, nullptr, OB, 1024); |
123 | this->output(OB, Flags); |
124 | StringView SV = OB; |
125 | std::string Owned(SV.begin(), SV.end()); |
126 | std::free(OB.getBuffer()); |
127 | return Owned; |
128 | } |
129 | |
130 | void PrimitiveTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const { |
131 | switch (PrimKind) { |
132 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Void, "void")case PrimitiveKind::Void: OB << "void"; break;; |
133 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Bool, "bool")case PrimitiveKind::Bool: OB << "bool"; break;; |
134 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char, "char")case PrimitiveKind::Char: OB << "char"; break;; |
135 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Schar, "signed char")case PrimitiveKind::Schar: OB << "signed char"; break;; |
136 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uchar, "unsigned char")case PrimitiveKind::Uchar: OB << "unsigned char"; break ;; |
137 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char8, "char8_t")case PrimitiveKind::Char8: OB << "char8_t"; break;; |
138 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char16, "char16_t")case PrimitiveKind::Char16: OB << "char16_t"; break;; |
139 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Char32, "char32_t")case PrimitiveKind::Char32: OB << "char32_t"; break;; |
140 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Short, "short")case PrimitiveKind::Short: OB << "short"; break;; |
141 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ushort, "unsigned short")case PrimitiveKind::Ushort: OB << "unsigned short"; break ;; |
142 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Int, "int")case PrimitiveKind::Int: OB << "int"; break;; |
143 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uint, "unsigned int")case PrimitiveKind::Uint: OB << "unsigned int"; break;; |
144 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Long, "long")case PrimitiveKind::Long: OB << "long"; break;; |
145 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ulong, "unsigned long")case PrimitiveKind::Ulong: OB << "unsigned long"; break ;; |
146 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Int64, "__int64")case PrimitiveKind::Int64: OB << "__int64"; break;; |
147 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Uint64, "unsigned __int64")case PrimitiveKind::Uint64: OB << "unsigned __int64"; break ;; |
148 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Wchar, "wchar_t")case PrimitiveKind::Wchar: OB << "wchar_t"; break;; |
149 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Float, "float")case PrimitiveKind::Float: OB << "float"; break;; |
150 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Double, "double")case PrimitiveKind::Double: OB << "double"; break;; |
151 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Ldouble, "long double")case PrimitiveKind::Ldouble: OB << "long double"; break ;; |
152 | OUTPUT_ENUM_CLASS_VALUE(PrimitiveKind, Nullptr, "std::nullptr_t")case PrimitiveKind::Nullptr: OB << "std::nullptr_t"; break ;; |
153 | } |
154 | outputQualifiers(OB, Quals, true, false); |
155 | } |
156 | |
157 | void NodeArrayNode::output(OutputBuffer &OB, OutputFlags Flags) const { |
158 | output(OB, Flags, ", "); |
159 | } |
160 | |
161 | void NodeArrayNode::output(OutputBuffer &OB, OutputFlags Flags, |
162 | StringView Separator) const { |
163 | if (Count == 0) |
164 | return; |
165 | if (Nodes[0]) |
166 | Nodes[0]->output(OB, Flags); |
167 | for (size_t I = 1; I < Count; ++I) { |
168 | OB << Separator; |
169 | Nodes[I]->output(OB, Flags); |
170 | } |
171 | } |
172 | |
173 | void EncodedStringLiteralNode::output(OutputBuffer &OB, |
174 | OutputFlags Flags) const { |
175 | switch (Char) { |
176 | case CharKind::Wchar: |
177 | OB << "L\""; |
178 | break; |
179 | case CharKind::Char: |
180 | OB << "\""; |
181 | break; |
182 | case CharKind::Char16: |
183 | OB << "u\""; |
184 | break; |
185 | case CharKind::Char32: |
186 | OB << "U\""; |
187 | break; |
188 | } |
189 | OB << DecodedString << "\""; |
190 | if (IsTruncated) |
191 | OB << "..."; |
192 | } |
193 | |
194 | void IntegerLiteralNode::output(OutputBuffer &OB, OutputFlags Flags) const { |
195 | if (IsNegative) |
196 | OB << '-'; |
197 | OB << Value; |
198 | } |
199 | |
200 | void TemplateParameterReferenceNode::output(OutputBuffer &OB, |
201 | OutputFlags Flags) const { |
202 | if (ThunkOffsetCount > 0) |
203 | OB << "{"; |
204 | else if (Affinity == PointerAffinity::Pointer) |
205 | OB << "&"; |
206 | |
207 | if (Symbol) { |
208 | Symbol->output(OB, Flags); |
209 | if (ThunkOffsetCount > 0) |
210 | OB << ", "; |
211 | } |
212 | |
213 | if (ThunkOffsetCount > 0) |
214 | OB << ThunkOffsets[0]; |
215 | for (int I = 1; I < ThunkOffsetCount; ++I) { |
216 | OB << ", " << ThunkOffsets[I]; |
217 | } |
218 | if (ThunkOffsetCount > 0) |
219 | OB << "}"; |
220 | } |
221 | |
222 | void IdentifierNode::outputTemplateParameters(OutputBuffer &OB, |
223 | OutputFlags Flags) const { |
224 | if (!TemplateParams) |
225 | return; |
226 | OB << "<"; |
227 | TemplateParams->output(OB, Flags); |
228 | OB << ">"; |
229 | } |
230 | |
231 | void DynamicStructorIdentifierNode::output(OutputBuffer &OB, |
232 | OutputFlags Flags) const { |
233 | if (IsDestructor) |
234 | OB << "`dynamic atexit destructor for "; |
235 | else |
236 | OB << "`dynamic initializer for "; |
237 | |
238 | if (Variable) { |
239 | OB << "`"; |
240 | Variable->output(OB, Flags); |
241 | OB << "''"; |
242 | } else { |
243 | OB << "'"; |
244 | Name->output(OB, Flags); |
245 | OB << "''"; |
246 | } |
247 | } |
248 | |
249 | void NamedIdentifierNode::output(OutputBuffer &OB, OutputFlags Flags) const { |
250 | OB << Name; |
251 | outputTemplateParameters(OB, Flags); |
252 | } |
253 | |
254 | void IntrinsicFunctionIdentifierNode::output(OutputBuffer &OB, |
255 | OutputFlags Flags) const { |
256 | switch (Operator) { |
257 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, New, "operator new")case IntrinsicFunctionKind::New: OB << "operator new"; break ;; |
258 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Delete, "operator delete")case IntrinsicFunctionKind::Delete: OB << "operator delete" ; break;; |
259 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Assign, "operator=")case IntrinsicFunctionKind::Assign: OB << "operator="; break ;; |
260 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, RightShift, "operator>>")case IntrinsicFunctionKind::RightShift: OB << "operator>>" ; break;; |
261 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LeftShift, "operator<<")case IntrinsicFunctionKind::LeftShift: OB << "operator<<" ; break;; |
262 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalNot, "operator!")case IntrinsicFunctionKind::LogicalNot: OB << "operator!" ; break;; |
263 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Equals, "operator==")case IntrinsicFunctionKind::Equals: OB << "operator=="; break;; |
264 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, NotEquals, "operator!=")case IntrinsicFunctionKind::NotEquals: OB << "operator!=" ; break;; |
265 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArraySubscript,case IntrinsicFunctionKind::ArraySubscript: OB << "operator[]" ; break; |
266 | "operator[]")case IntrinsicFunctionKind::ArraySubscript: OB << "operator[]" ; break;; |
267 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Pointer, "operator->")case IntrinsicFunctionKind::Pointer: OB << "operator->" ; break;; |
268 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Increment, "operator++")case IntrinsicFunctionKind::Increment: OB << "operator++" ; break;; |
269 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Decrement, "operator--")case IntrinsicFunctionKind::Decrement: OB << "operator--" ; break;; |
270 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Minus, "operator-")case IntrinsicFunctionKind::Minus: OB << "operator-"; break ;; |
271 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Plus, "operator+")case IntrinsicFunctionKind::Plus: OB << "operator+"; break ;; |
272 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Dereference, "operator*")case IntrinsicFunctionKind::Dereference: OB << "operator*" ; break;; |
273 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseAnd, "operator&")case IntrinsicFunctionKind::BitwiseAnd: OB << "operator&" ; break;; |
274 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, MemberPointer,case IntrinsicFunctionKind::MemberPointer: OB << "operator->*" ; break; |
275 | "operator->*")case IntrinsicFunctionKind::MemberPointer: OB << "operator->*" ; break;; |
276 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Divide, "operator/")case IntrinsicFunctionKind::Divide: OB << "operator/"; break ;; |
277 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Modulus, "operator%")case IntrinsicFunctionKind::Modulus: OB << "operator%"; break;; |
278 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LessThan, "operator<")case IntrinsicFunctionKind::LessThan: OB << "operator<" ; break;; |
279 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LessThanEqual, "operator<=")case IntrinsicFunctionKind::LessThanEqual: OB << "operator<=" ; break;; |
280 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, GreaterThan, "operator>")case IntrinsicFunctionKind::GreaterThan: OB << "operator>" ; break;; |
281 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, GreaterThanEqual,case IntrinsicFunctionKind::GreaterThanEqual: OB << "operator>=" ; break; |
282 | "operator>=")case IntrinsicFunctionKind::GreaterThanEqual: OB << "operator>=" ; break;; |
283 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Comma, "operator,")case IntrinsicFunctionKind::Comma: OB << "operator,"; break ;; |
284 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Parens, "operator()")case IntrinsicFunctionKind::Parens: OB << "operator()"; break;; |
285 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseNot, "operator~")case IntrinsicFunctionKind::BitwiseNot: OB << "operator~" ; break;; |
286 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseXor, "operator^")case IntrinsicFunctionKind::BitwiseXor: OB << "operator^" ; break;; |
287 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseOr, "operator|")case IntrinsicFunctionKind::BitwiseOr: OB << "operator|" ; break;; |
288 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalAnd, "operator&&")case IntrinsicFunctionKind::LogicalAnd: OB << "operator&&" ; break;; |
289 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LogicalOr, "operator||")case IntrinsicFunctionKind::LogicalOr: OB << "operator||" ; break;; |
290 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, TimesEqual, "operator*=")case IntrinsicFunctionKind::TimesEqual: OB << "operator*=" ; break;; |
291 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, PlusEqual, "operator+=")case IntrinsicFunctionKind::PlusEqual: OB << "operator+=" ; break;; |
292 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, MinusEqual, "operator-=")case IntrinsicFunctionKind::MinusEqual: OB << "operator-=" ; break;; |
293 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, DivEqual, "operator/=")case IntrinsicFunctionKind::DivEqual: OB << "operator/=" ; break;; |
294 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ModEqual, "operator%=")case IntrinsicFunctionKind::ModEqual: OB << "operator%=" ; break;; |
295 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, RshEqual, "operator>>=")case IntrinsicFunctionKind::RshEqual: OB << "operator>>=" ; break;; |
296 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LshEqual, "operator<<=")case IntrinsicFunctionKind::LshEqual: OB << "operator<<=" ; break;; |
297 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseAndEqual,case IntrinsicFunctionKind::BitwiseAndEqual: OB << "operator&=" ; break; |
298 | "operator&=")case IntrinsicFunctionKind::BitwiseAndEqual: OB << "operator&=" ; break;; |
299 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseOrEqual,case IntrinsicFunctionKind::BitwiseOrEqual: OB << "operator|=" ; break; |
300 | "operator|=")case IntrinsicFunctionKind::BitwiseOrEqual: OB << "operator|=" ; break;; |
301 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, BitwiseXorEqual,case IntrinsicFunctionKind::BitwiseXorEqual: OB << "operator^=" ; break; |
302 | "operator^=")case IntrinsicFunctionKind::BitwiseXorEqual: OB << "operator^=" ; break;; |
303 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VbaseDtor, "`vbase dtor'")case IntrinsicFunctionKind::VbaseDtor: OB << "`vbase dtor'" ; break;; |
304 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecDelDtor,case IntrinsicFunctionKind::VecDelDtor: OB << "`vector deleting dtor'" ; break; |
305 | "`vector deleting dtor'")case IntrinsicFunctionKind::VecDelDtor: OB << "`vector deleting dtor'" ; break;; |
306 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, DefaultCtorClosure,case IntrinsicFunctionKind::DefaultCtorClosure: OB << "`default ctor closure'" ; break; |
307 | "`default ctor closure'")case IntrinsicFunctionKind::DefaultCtorClosure: OB << "`default ctor closure'" ; break;; |
308 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ScalarDelDtor,case IntrinsicFunctionKind::ScalarDelDtor: OB << "`scalar deleting dtor'" ; break; |
309 | "`scalar deleting dtor'")case IntrinsicFunctionKind::ScalarDelDtor: OB << "`scalar deleting dtor'" ; break;; |
310 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecCtorIter,case IntrinsicFunctionKind::VecCtorIter: OB << "`vector ctor iterator'" ; break; |
311 | "`vector ctor iterator'")case IntrinsicFunctionKind::VecCtorIter: OB << "`vector ctor iterator'" ; break;; |
312 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecDtorIter,case IntrinsicFunctionKind::VecDtorIter: OB << "`vector dtor iterator'" ; break; |
313 | "`vector dtor iterator'")case IntrinsicFunctionKind::VecDtorIter: OB << "`vector dtor iterator'" ; break;; |
314 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VecVbaseCtorIter,case IntrinsicFunctionKind::VecVbaseCtorIter: OB << "`vector vbase ctor iterator'" ; break; |
315 | "`vector vbase ctor iterator'")case IntrinsicFunctionKind::VecVbaseCtorIter: OB << "`vector vbase ctor iterator'" ; break;; |
316 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VdispMap,case IntrinsicFunctionKind::VdispMap: OB << "`virtual displacement map'" ; break; |
317 | "`virtual displacement map'")case IntrinsicFunctionKind::VdispMap: OB << "`virtual displacement map'" ; break;; |
318 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecCtorIter,case IntrinsicFunctionKind::EHVecCtorIter: OB << "`eh vector ctor iterator'" ; break; |
319 | "`eh vector ctor iterator'")case IntrinsicFunctionKind::EHVecCtorIter: OB << "`eh vector ctor iterator'" ; break;; |
320 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecDtorIter,case IntrinsicFunctionKind::EHVecDtorIter: OB << "`eh vector dtor iterator'" ; break; |
321 | "`eh vector dtor iterator'")case IntrinsicFunctionKind::EHVecDtorIter: OB << "`eh vector dtor iterator'" ; break;; |
322 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVecVbaseCtorIter,case IntrinsicFunctionKind::EHVecVbaseCtorIter: OB << "`eh vector vbase ctor iterator'" ; break; |
323 | "`eh vector vbase ctor iterator'")case IntrinsicFunctionKind::EHVecVbaseCtorIter: OB << "`eh vector vbase ctor iterator'" ; break;; |
324 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, CopyCtorClosure,case IntrinsicFunctionKind::CopyCtorClosure: OB << "`copy ctor closure'" ; break; |
325 | "`copy ctor closure'")case IntrinsicFunctionKind::CopyCtorClosure: OB << "`copy ctor closure'" ; break;; |
326 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, LocalVftableCtorClosure,case IntrinsicFunctionKind::LocalVftableCtorClosure: OB << "`local vftable ctor closure'"; break; |
327 | "`local vftable ctor closure'")case IntrinsicFunctionKind::LocalVftableCtorClosure: OB << "`local vftable ctor closure'"; break;; |
328 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArrayNew, "operator new[]")case IntrinsicFunctionKind::ArrayNew: OB << "operator new[]" ; break;; |
329 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ArrayDelete,case IntrinsicFunctionKind::ArrayDelete: OB << "operator delete[]" ; break; |
330 | "operator delete[]")case IntrinsicFunctionKind::ArrayDelete: OB << "operator delete[]" ; break;; |
331 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorCtorIter,case IntrinsicFunctionKind::ManVectorCtorIter: OB << "`managed vector ctor iterator'" ; break; |
332 | "`managed vector ctor iterator'")case IntrinsicFunctionKind::ManVectorCtorIter: OB << "`managed vector ctor iterator'" ; break;; |
333 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorDtorIter,case IntrinsicFunctionKind::ManVectorDtorIter: OB << "`managed vector dtor iterator'" ; break; |
334 | "`managed vector dtor iterator'")case IntrinsicFunctionKind::ManVectorDtorIter: OB << "`managed vector dtor iterator'" ; break;; |
335 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVectorCopyCtorIter,case IntrinsicFunctionKind::EHVectorCopyCtorIter: OB << "`EH vector copy ctor iterator'"; break; |
336 | "`EH vector copy ctor iterator'")case IntrinsicFunctionKind::EHVectorCopyCtorIter: OB << "`EH vector copy ctor iterator'"; break;; |
337 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, EHVectorVbaseCopyCtorIter,case IntrinsicFunctionKind::EHVectorVbaseCopyCtorIter: OB << "`EH vector vbase copy ctor iterator'"; break; |
338 | "`EH vector vbase copy ctor iterator'")case IntrinsicFunctionKind::EHVectorVbaseCopyCtorIter: OB << "`EH vector vbase copy ctor iterator'"; break;; |
339 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VectorCopyCtorIter,case IntrinsicFunctionKind::VectorCopyCtorIter: OB << "`vector copy ctor iterator'" ; break; |
340 | "`vector copy ctor iterator'")case IntrinsicFunctionKind::VectorCopyCtorIter: OB << "`vector copy ctor iterator'" ; break;; |
341 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, VectorVbaseCopyCtorIter,case IntrinsicFunctionKind::VectorVbaseCopyCtorIter: OB << "`vector vbase copy constructor iterator'"; break; |
342 | "`vector vbase copy constructor iterator'")case IntrinsicFunctionKind::VectorVbaseCopyCtorIter: OB << "`vector vbase copy constructor iterator'"; break;; |
343 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, ManVectorVbaseCopyCtorIter,case IntrinsicFunctionKind::ManVectorVbaseCopyCtorIter: OB << "`managed vector vbase copy constructor iterator'"; break; |
344 | "`managed vector vbase copy constructor iterator'")case IntrinsicFunctionKind::ManVectorVbaseCopyCtorIter: OB << "`managed vector vbase copy constructor iterator'"; break;; |
345 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, CoAwait,case IntrinsicFunctionKind::CoAwait: OB << "operator co_await" ; break; |
346 | "operator co_await")case IntrinsicFunctionKind::CoAwait: OB << "operator co_await" ; break;; |
347 | OUTPUT_ENUM_CLASS_VALUE(IntrinsicFunctionKind, Spaceship, "operator<=>")case IntrinsicFunctionKind::Spaceship: OB << "operator<=>" ; break;; |
348 | case IntrinsicFunctionKind::MaxIntrinsic: |
349 | case IntrinsicFunctionKind::None: |
350 | break; |
351 | } |
352 | outputTemplateParameters(OB, Flags); |
353 | } |
354 | |
355 | void LocalStaticGuardIdentifierNode::output(OutputBuffer &OB, |
356 | OutputFlags Flags) const { |
357 | if (IsThread) |
358 | OB << "`local static thread guard'"; |
359 | else |
360 | OB << "`local static guard'"; |
361 | if (ScopeIndex > 0) |
362 | OB << "{" << ScopeIndex << "}"; |
363 | } |
364 | |
365 | void ConversionOperatorIdentifierNode::output(OutputBuffer &OB, |
366 | OutputFlags Flags) const { |
367 | OB << "operator"; |
368 | outputTemplateParameters(OB, Flags); |
369 | OB << " "; |
370 | TargetType->output(OB, Flags); |
371 | } |
372 | |
373 | void StructorIdentifierNode::output(OutputBuffer &OB, OutputFlags Flags) const { |
374 | if (IsDestructor) |
375 | OB << "~"; |
376 | Class->output(OB, Flags); |
377 | outputTemplateParameters(OB, Flags); |
378 | } |
379 | |
380 | void LiteralOperatorIdentifierNode::output(OutputBuffer &OB, |
381 | OutputFlags Flags) const { |
382 | OB << "operator \"\"" << Name; |
383 | outputTemplateParameters(OB, Flags); |
384 | } |
385 | |
386 | void FunctionSignatureNode::outputPre(OutputBuffer &OB, |
387 | OutputFlags Flags) const { |
388 | if (!(Flags & OF_NoAccessSpecifier)) { |
389 | if (FunctionClass & FC_Public) |
390 | OB << "public: "; |
391 | if (FunctionClass & FC_Protected) |
392 | OB << "protected: "; |
393 | if (FunctionClass & FC_Private) |
394 | OB << "private: "; |
395 | } |
396 | |
397 | if (!(Flags & OF_NoMemberType)) { |
398 | if (!(FunctionClass & FC_Global)) { |
399 | if (FunctionClass & FC_Static) |
400 | OB << "static "; |
401 | } |
402 | if (FunctionClass & FC_Virtual) |
403 | OB << "virtual "; |
404 | |
405 | if (FunctionClass & FC_ExternC) |
406 | OB << "extern \"C\" "; |
407 | } |
408 | |
409 | if (!(Flags & OF_NoReturnType) && ReturnType) { |
410 | ReturnType->outputPre(OB, Flags); |
411 | OB << " "; |
412 | } |
413 | |
414 | if (!(Flags & OF_NoCallingConvention)) |
415 | outputCallingConvention(OB, CallConvention); |
416 | } |
417 | |
418 | void FunctionSignatureNode::outputPost(OutputBuffer &OB, |
419 | OutputFlags Flags) const { |
420 | if (!(FunctionClass & FC_NoParameterList)) { |
421 | OB << "("; |
422 | if (Params) |
423 | Params->output(OB, Flags); |
424 | else |
425 | OB << "void"; |
426 | |
427 | if (IsVariadic) { |
428 | if (OB.back() != '(') |
429 | OB << ", "; |
430 | OB << "..."; |
431 | } |
432 | OB << ")"; |
433 | } |
434 | |
435 | if (Quals & Q_Const) |
436 | OB << " const"; |
437 | if (Quals & Q_Volatile) |
438 | OB << " volatile"; |
439 | if (Quals & Q_Restrict) |
440 | OB << " __restrict"; |
441 | if (Quals & Q_Unaligned) |
442 | OB << " __unaligned"; |
443 | |
444 | if (IsNoexcept) |
445 | OB << " noexcept"; |
446 | |
447 | if (RefQualifier == FunctionRefQualifier::Reference) |
448 | OB << " &"; |
449 | else if (RefQualifier == FunctionRefQualifier::RValueReference) |
450 | OB << " &&"; |
451 | |
452 | if (!(Flags & OF_NoReturnType) && ReturnType) |
453 | ReturnType->outputPost(OB, Flags); |
454 | } |
455 | |
456 | void ThunkSignatureNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const { |
457 | OB << "[thunk]: "; |
458 | |
459 | FunctionSignatureNode::outputPre(OB, Flags); |
460 | } |
461 | |
462 | void ThunkSignatureNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const { |
463 | if (FunctionClass & FC_StaticThisAdjust) { |
464 | OB << "`adjustor{" << ThisAdjust.StaticOffset << "}'"; |
465 | } else if (FunctionClass & FC_VirtualThisAdjust) { |
466 | if (FunctionClass & FC_VirtualThisAdjustEx) { |
467 | OB << "`vtordispex{" << ThisAdjust.VBPtrOffset << ", " |
468 | << ThisAdjust.VBOffsetOffset << ", " << ThisAdjust.VtordispOffset |
469 | << ", " << ThisAdjust.StaticOffset << "}'"; |
470 | } else { |
471 | OB << "`vtordisp{" << ThisAdjust.VtordispOffset << ", " |
472 | << ThisAdjust.StaticOffset << "}'"; |
473 | } |
474 | } |
475 | |
476 | FunctionSignatureNode::outputPost(OB, Flags); |
477 | } |
478 | |
479 | void PointerTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const { |
480 | if (Pointee->kind() == NodeKind::FunctionSignature) { |
481 | // If this is a pointer to a function, don't output the calling convention. |
482 | // It needs to go inside the parentheses. |
483 | const FunctionSignatureNode *Sig = |
484 | static_cast<const FunctionSignatureNode *>(Pointee); |
485 | Sig->outputPre(OB, OF_NoCallingConvention); |
486 | } else |
487 | Pointee->outputPre(OB, Flags); |
488 | |
489 | outputSpaceIfNecessary(OB); |
490 | |
491 | if (Quals & Q_Unaligned) |
492 | OB << "__unaligned "; |
493 | |
494 | if (Pointee->kind() == NodeKind::ArrayType) { |
495 | OB << "("; |
496 | } else if (Pointee->kind() == NodeKind::FunctionSignature) { |
497 | OB << "("; |
498 | const FunctionSignatureNode *Sig = |
499 | static_cast<const FunctionSignatureNode *>(Pointee); |
500 | outputCallingConvention(OB, Sig->CallConvention); |
501 | OB << " "; |
502 | } |
503 | |
504 | if (ClassParent) { |
505 | ClassParent->output(OB, Flags); |
506 | OB << "::"; |
507 | } |
508 | |
509 | switch (Affinity) { |
510 | case PointerAffinity::Pointer: |
511 | OB << "*"; |
512 | break; |
513 | case PointerAffinity::Reference: |
514 | OB << "&"; |
515 | break; |
516 | case PointerAffinity::RValueReference: |
517 | OB << "&&"; |
518 | break; |
519 | default: |
520 | assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail ( "false", "llvm/lib/Demangle/MicrosoftDemangleNodes.cpp", 520, __extension__ __PRETTY_FUNCTION__)); |
521 | } |
522 | outputQualifiers(OB, Quals, false, false); |
523 | } |
524 | |
525 | void PointerTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const { |
526 | if (Pointee->kind() == NodeKind::ArrayType || |
527 | Pointee->kind() == NodeKind::FunctionSignature) |
528 | OB << ")"; |
529 | |
530 | Pointee->outputPost(OB, Flags); |
531 | } |
532 | |
533 | void TagTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const { |
534 | if (!(Flags & OF_NoTagSpecifier)) { |
535 | switch (Tag) { |
536 | OUTPUT_ENUM_CLASS_VALUE(TagKind, Class, "class")case TagKind::Class: OB << "class"; break;; |
537 | OUTPUT_ENUM_CLASS_VALUE(TagKind, Struct, "struct")case TagKind::Struct: OB << "struct"; break;; |
538 | OUTPUT_ENUM_CLASS_VALUE(TagKind, Union, "union")case TagKind::Union: OB << "union"; break;; |
539 | OUTPUT_ENUM_CLASS_VALUE(TagKind, Enum, "enum")case TagKind::Enum: OB << "enum"; break;; |
540 | } |
541 | OB << " "; |
542 | } |
543 | QualifiedName->output(OB, Flags); |
544 | outputQualifiers(OB, Quals, true, false); |
545 | } |
546 | |
547 | void TagTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {} |
548 | |
549 | void ArrayTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const { |
550 | ElementType->outputPre(OB, Flags); |
551 | outputQualifiers(OB, Quals, true, false); |
552 | } |
553 | |
554 | void ArrayTypeNode::outputOneDimension(OutputBuffer &OB, OutputFlags Flags, |
555 | Node *N) const { |
556 | assert(N->kind() == NodeKind::IntegerLiteral)(static_cast <bool> (N->kind() == NodeKind::IntegerLiteral ) ? void (0) : __assert_fail ("N->kind() == NodeKind::IntegerLiteral" , "llvm/lib/Demangle/MicrosoftDemangleNodes.cpp", 556, __extension__ __PRETTY_FUNCTION__)); |
557 | IntegerLiteralNode *ILN = static_cast<IntegerLiteralNode *>(N); |
558 | if (ILN->Value != 0) |
559 | ILN->output(OB, Flags); |
560 | } |
561 | |
562 | void ArrayTypeNode::outputDimensionsImpl(OutputBuffer &OB, |
563 | OutputFlags Flags) const { |
564 | if (Dimensions->Count == 0) |
565 | return; |
566 | |
567 | outputOneDimension(OB, Flags, Dimensions->Nodes[0]); |
568 | for (size_t I = 1; I < Dimensions->Count; ++I) { |
569 | OB << "]["; |
570 | outputOneDimension(OB, Flags, Dimensions->Nodes[I]); |
571 | } |
572 | } |
573 | |
574 | void ArrayTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const { |
575 | OB << "["; |
576 | outputDimensionsImpl(OB, Flags); |
577 | OB << "]"; |
578 | |
579 | ElementType->outputPost(OB, Flags); |
580 | } |
581 | |
582 | void SymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const { |
583 | Name->output(OB, Flags); |
584 | } |
585 | |
586 | void FunctionSymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const { |
587 | Signature->outputPre(OB, Flags); |
588 | outputSpaceIfNecessary(OB); |
589 | Name->output(OB, Flags); |
590 | Signature->outputPost(OB, Flags); |
591 | } |
592 | |
593 | void VariableSymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const { |
594 | const char *AccessSpec = nullptr; |
595 | bool IsStatic = true; |
596 | switch (SC) { |
597 | case StorageClass::PrivateStatic: |
598 | AccessSpec = "private"; |
599 | break; |
600 | case StorageClass::PublicStatic: |
601 | AccessSpec = "public"; |
602 | break; |
603 | case StorageClass::ProtectedStatic: |
604 | AccessSpec = "protected"; |
605 | break; |
606 | default: |
607 | IsStatic = false; |
608 | break; |
609 | } |
610 | if (!(Flags & OF_NoAccessSpecifier) && AccessSpec) |
611 | OB << AccessSpec << ": "; |
612 | if (!(Flags & OF_NoMemberType) && IsStatic) |
613 | OB << "static "; |
614 | |
615 | if (!(Flags & OF_NoVariableType) && Type) { |
616 | Type->outputPre(OB, Flags); |
617 | outputSpaceIfNecessary(OB); |
618 | } |
619 | Name->output(OB, Flags); |
620 | if (!(Flags & OF_NoVariableType) && Type) |
621 | Type->outputPost(OB, Flags); |
622 | } |
623 | |
624 | void CustomTypeNode::outputPre(OutputBuffer &OB, OutputFlags Flags) const { |
625 | Identifier->output(OB, Flags); |
626 | } |
627 | void CustomTypeNode::outputPost(OutputBuffer &OB, OutputFlags Flags) const {} |
628 | |
629 | void QualifiedNameNode::output(OutputBuffer &OB, OutputFlags Flags) const { |
630 | Components->output(OB, Flags, "::"); |
631 | } |
632 | |
633 | void RttiBaseClassDescriptorNode::output(OutputBuffer &OB, |
634 | OutputFlags Flags) const { |
635 | OB << "`RTTI Base Class Descriptor at ("; |
636 | OB << NVOffset << ", " << VBPtrOffset << ", " << VBTableOffset << ", " |
637 | << this->Flags; |
638 | OB << ")'"; |
639 | } |
640 | |
641 | void LocalStaticGuardVariableNode::output(OutputBuffer &OB, |
642 | OutputFlags Flags) const { |
643 | Name->output(OB, Flags); |
644 | } |
645 | |
646 | void VcallThunkIdentifierNode::output(OutputBuffer &OB, |
647 | OutputFlags Flags) const { |
648 | OB << "`vcall'{" << OffsetInVTable << ", {flat}}"; |
649 | } |
650 | |
651 | void SpecialTableSymbolNode::output(OutputBuffer &OB, OutputFlags Flags) const { |
652 | outputQualifiers(OB, Quals, false, true); |
653 | Name->output(OB, Flags); |
654 | if (TargetName) { |
655 | OB << "{for `"; |
656 | TargetName->output(OB, Flags); |
657 | OB << "'}"; |
658 | } |
659 | } |