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