LLVM  13.0.0git
MicrosoftDemangle.cpp
Go to the documentation of this file.
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 // This file has no dependencies on the rest of LLVM so that it can be
12 // easily reused in other programs such as libcxxabi.
13 //
14 //===----------------------------------------------------------------------===//
15 
17 #include "llvm/Demangle/Demangle.h"
19 
22 #include "llvm/Demangle/Utility.h"
23 
24 #include <array>
25 #include <cctype>
26 #include <cstdio>
27 #include <tuple>
28 
29 using namespace llvm;
30 using namespace ms_demangle;
31 
32 static bool startsWithDigit(StringView S) {
33  return !S.empty() && std::isdigit(S.front());
34 }
35 
36 
37 struct NodeList {
38  Node *N = nullptr;
39  NodeList *Next = nullptr;
40 };
41 
42 static bool isMemberPointer(StringView MangledName, bool &Error) {
43  Error = false;
44  switch (MangledName.popFront()) {
45  case '$':
46  // This is probably an rvalue reference (e.g. $$Q), and you cannot have an
47  // rvalue reference to a member.
48  return false;
49  case 'A':
50  // 'A' indicates a reference, and you cannot have a reference to a member
51  // function or member.
52  return false;
53  case 'P':
54  case 'Q':
55  case 'R':
56  case 'S':
57  // These 4 values indicate some kind of pointer, but we still don't know
58  // what.
59  break;
60  default:
61  // isMemberPointer() is called only if isPointerType() returns true,
62  // and it rejects other prefixes.
64  }
65 
66  // If it starts with a number, then 6 indicates a non-member function
67  // pointer, and 8 indicates a member function pointer.
68  if (startsWithDigit(MangledName)) {
69  if (MangledName[0] != '6' && MangledName[0] != '8') {
70  Error = true;
71  return false;
72  }
73  return (MangledName[0] == '8');
74  }
75 
76  // Remove ext qualifiers since those can appear on either type and are
77  // therefore not indicative.
78  MangledName.consumeFront('E'); // 64-bit
79  MangledName.consumeFront('I'); // restrict
80  MangledName.consumeFront('F'); // unaligned
81 
82  if (MangledName.empty()) {
83  Error = true;
84  return false;
85  }
86 
87  // The next value should be either ABCD (non-member) or QRST (member).
88  switch (MangledName.front()) {
89  case 'A':
90  case 'B':
91  case 'C':
92  case 'D':
93  return false;
94  case 'Q':
95  case 'R':
96  case 'S':
97  case 'T':
98  return true;
99  default:
100  Error = true;
101  return false;
102  }
103 }
104 
106 consumeSpecialIntrinsicKind(StringView &MangledName) {
107  if (MangledName.consumeFront("?_7"))
109  if (MangledName.consumeFront("?_8"))
111  if (MangledName.consumeFront("?_9"))
113  if (MangledName.consumeFront("?_A"))
115  if (MangledName.consumeFront("?_B"))
117  if (MangledName.consumeFront("?_C"))
119  if (MangledName.consumeFront("?_P"))
121  if (MangledName.consumeFront("?_R0"))
123  if (MangledName.consumeFront("?_R1"))
125  if (MangledName.consumeFront("?_R2"))
127  if (MangledName.consumeFront("?_R3"))
129  if (MangledName.consumeFront("?_R4"))
131  if (MangledName.consumeFront("?_S"))
133  if (MangledName.consumeFront("?__E"))
135  if (MangledName.consumeFront("?__F"))
137  if (MangledName.consumeFront("?__J"))
140 }
141 
142 static bool startsWithLocalScopePattern(StringView S) {
143  if (!S.consumeFront('?'))
144  return false;
145 
146  size_t End = S.find('?');
147  if (End == StringView::npos)
148  return false;
149  StringView Candidate = S.substr(0, End);
150  if (Candidate.empty())
151  return false;
152 
153  // \?[0-9]\?
154  // ?@? is the discriminator 0.
155  if (Candidate.size() == 1)
156  return Candidate[0] == '@' || (Candidate[0] >= '0' && Candidate[0] <= '9');
157 
158  // If it's not 0-9, then it's an encoded number terminated with an @
159  if (Candidate.back() != '@')
160  return false;
161  Candidate = Candidate.dropBack();
162 
163  // An encoded number starts with B-P and all subsequent digits are in A-P.
164  // Note that the reason the first digit cannot be A is two fold. First, it
165  // would create an ambiguity with ?A which delimits the beginning of an
166  // anonymous namespace. Second, A represents 0, and you don't start a multi
167  // digit number with a leading 0. Presumably the anonymous namespace
168  // ambiguity is also why single digit encoded numbers use 0-9 rather than A-J.
169  if (Candidate[0] < 'B' || Candidate[0] > 'P')
170  return false;
171  Candidate = Candidate.dropFront();
172  while (!Candidate.empty()) {
173  if (Candidate[0] < 'A' || Candidate[0] > 'P')
174  return false;
175  Candidate = Candidate.dropFront();
176  }
177 
178  return true;
179 }
180 
181 static bool isTagType(StringView S) {
182  switch (S.front()) {
183  case 'T': // union
184  case 'U': // struct
185  case 'V': // class
186  case 'W': // enum
187  return true;
188  }
189  return false;
190 }
191 
192 static bool isCustomType(StringView S) { return S[0] == '?'; }
193 
194 static bool isPointerType(StringView S) {
195  if (S.startsWith("$$Q")) // foo &&
196  return true;
197 
198  switch (S.front()) {
199  case 'A': // foo &
200  case 'P': // foo *
201  case 'Q': // foo *const
202  case 'R': // foo *volatile
203  case 'S': // foo *const volatile
204  return true;
205  }
206  return false;
207 }
208 
209 static bool isArrayType(StringView S) { return S[0] == 'Y'; }
210 
211 static bool isFunctionType(StringView S) {
212  return S.startsWith("$$A8@@") || S.startsWith("$$A6");
213 }
214 
216 demangleFunctionRefQualifier(StringView &MangledName) {
217  if (MangledName.consumeFront('G'))
219  else if (MangledName.consumeFront('H'))
222 }
223 
224 static std::pair<Qualifiers, PointerAffinity>
225 demanglePointerCVQualifiers(StringView &MangledName) {
226  if (MangledName.consumeFront("$$Q"))
227  return std::make_pair(Q_None, PointerAffinity::RValueReference);
228 
229  switch (MangledName.popFront()) {
230  case 'A':
231  return std::make_pair(Q_None, PointerAffinity::Reference);
232  case 'P':
233  return std::make_pair(Q_None, PointerAffinity::Pointer);
234  case 'Q':
235  return std::make_pair(Q_Const, PointerAffinity::Pointer);
236  case 'R':
237  return std::make_pair(Q_Volatile, PointerAffinity::Pointer);
238  case 'S':
239  return std::make_pair(Qualifiers(Q_Const | Q_Volatile),
241  }
242  // This function is only called if isPointerType() returns true,
243  // and it only returns true for the six cases listed above.
245 }
246 
247 StringView Demangler::copyString(StringView Borrowed) {
248  char *Stable = Arena.allocUnalignedBuffer(Borrowed.size() + 1);
249  std::strcpy(Stable, Borrowed.begin());
250 
251  return {Stable, Borrowed.size()};
252 }
253 
255 Demangler::demangleSpecialTableSymbolNode(StringView &MangledName,
258  switch (K) {
260  NI->Name = "`vftable'";
261  break;
263  NI->Name = "`vbtable'";
264  break;
266  NI->Name = "`local vftable'";
267  break;
269  NI->Name = "`RTTI Complete Object Locator'";
270  break;
271  default:
273  }
274  QualifiedNameNode *QN = demangleNameScopeChain(MangledName, NI);
276  STSN->Name = QN;
277  bool IsMember = false;
278  if (MangledName.empty()) {
279  Error = true;
280  return nullptr;
281  }
282  char Front = MangledName.popFront();
283  if (Front != '6' && Front != '7') {
284  Error = true;
285  return nullptr;
286  }
287 
288  std::tie(STSN->Quals, IsMember) = demangleQualifiers(MangledName);
289  if (!MangledName.consumeFront('@'))
290  STSN->TargetName = demangleFullyQualifiedTypeName(MangledName);
291  return STSN;
292 }
293 
295 Demangler::demangleLocalStaticGuard(StringView &MangledName, bool IsThread) {
298  LSGI->IsThread = IsThread;
299  QualifiedNameNode *QN = demangleNameScopeChain(MangledName, LSGI);
302  LSGVN->Name = QN;
303 
304  if (MangledName.consumeFront("4IA"))
305  LSGVN->IsVisible = false;
306  else if (MangledName.consumeFront("5"))
307  LSGVN->IsVisible = true;
308  else {
309  Error = true;
310  return nullptr;
311  }
312 
313  if (!MangledName.empty())
314  LSGI->ScopeIndex = demangleUnsigned(MangledName);
315  return LSGVN;
316 }
317 
319  StringView Name) {
321  Id->Name = Name;
322  return Id;
323 }
324 
326  IdentifierNode *Identifier) {
328  QN->Components = Arena.alloc<NodeArrayNode>();
329  QN->Components->Count = 1;
330  QN->Components->Nodes = Arena.allocArray<Node *>(1);
331  QN->Components->Nodes[0] = Identifier;
332  return QN;
333 }
334 
336  StringView Name) {
338  return synthesizeQualifiedName(Arena, Id);
339 }
340 
342  TypeNode *Type,
343  StringView VariableName) {
345  VSN->Type = Type;
346  VSN->Name = synthesizeQualifiedName(Arena, VariableName);
347  return VSN;
348 }
349 
350 VariableSymbolNode *Demangler::demangleUntypedVariable(
351  ArenaAllocator &Arena, StringView &MangledName, StringView VariableName) {
352  NamedIdentifierNode *NI = synthesizeNamedIdentifier(Arena, VariableName);
353  QualifiedNameNode *QN = demangleNameScopeChain(MangledName, NI);
355  VSN->Name = QN;
356  if (MangledName.consumeFront("8"))
357  return VSN;
358 
359  Error = true;
360  return nullptr;
361 }
362 
364 Demangler::demangleRttiBaseClassDescriptorNode(ArenaAllocator &Arena,
365  StringView &MangledName) {
368  RBCDN->NVOffset = demangleUnsigned(MangledName);
369  RBCDN->VBPtrOffset = demangleSigned(MangledName);
370  RBCDN->VBTableOffset = demangleUnsigned(MangledName);
371  RBCDN->Flags = demangleUnsigned(MangledName);
372  if (Error)
373  return nullptr;
374 
376  VSN->Name = demangleNameScopeChain(MangledName, RBCDN);
377  MangledName.consumeFront('8');
378  return VSN;
379 }
380 
381 FunctionSymbolNode *Demangler::demangleInitFiniStub(StringView &MangledName,
382  bool IsDestructor) {
385  DSIN->IsDestructor = IsDestructor;
386 
387  bool IsKnownStaticDataMember = false;
388  if (MangledName.consumeFront('?'))
389  IsKnownStaticDataMember = true;
390 
391  SymbolNode *Symbol = demangleDeclarator(MangledName);
392  if (Error)
393  return nullptr;
394 
395  FunctionSymbolNode *FSN = nullptr;
396 
397  if (Symbol->kind() == NodeKind::VariableSymbol) {
398  DSIN->Variable = static_cast<VariableSymbolNode *>(Symbol);
399 
400  // Older versions of clang mangled this type of symbol incorrectly. They
401  // would omit the leading ? and they would only emit a single @ at the end.
402  // The correct mangling is a leading ? and 2 trailing @ signs. Handle
403  // both cases.
404  int AtCount = IsKnownStaticDataMember ? 2 : 1;
405  for (int I = 0; I < AtCount; ++I) {
406  if (MangledName.consumeFront('@'))
407  continue;
408  Error = true;
409  return nullptr;
410  }
411 
412  FSN = demangleFunctionEncoding(MangledName);
413  if (FSN)
414  FSN->Name = synthesizeQualifiedName(Arena, DSIN);
415  } else {
416  if (IsKnownStaticDataMember) {
417  // This was supposed to be a static data member, but we got a function.
418  Error = true;
419  return nullptr;
420  }
421 
422  FSN = static_cast<FunctionSymbolNode *>(Symbol);
423  DSIN->Name = Symbol->Name;
424  FSN->Name = synthesizeQualifiedName(Arena, DSIN);
425  }
426 
427  return FSN;
428 }
429 
430 SymbolNode *Demangler::demangleSpecialIntrinsic(StringView &MangledName) {
432 
433  switch (SIK) {
435  return nullptr;
436  case SpecialIntrinsicKind::StringLiteralSymbol:
437  return demangleStringLiteral(MangledName);
438  case SpecialIntrinsicKind::Vftable:
439  case SpecialIntrinsicKind::Vbtable:
440  case SpecialIntrinsicKind::LocalVftable:
441  case SpecialIntrinsicKind::RttiCompleteObjLocator:
442  return demangleSpecialTableSymbolNode(MangledName, SIK);
443  case SpecialIntrinsicKind::VcallThunk:
444  return demangleVcallThunkNode(MangledName);
445  case SpecialIntrinsicKind::LocalStaticGuard:
446  return demangleLocalStaticGuard(MangledName, /*IsThread=*/false);
447  case SpecialIntrinsicKind::LocalStaticThreadGuard:
448  return demangleLocalStaticGuard(MangledName, /*IsThread=*/true);
449  case SpecialIntrinsicKind::RttiTypeDescriptor: {
450  TypeNode *T = demangleType(MangledName, QualifierMangleMode::Result);
451  if (Error)
452  break;
453  if (!MangledName.consumeFront("@8"))
454  break;
455  if (!MangledName.empty())
456  break;
457  return synthesizeVariable(Arena, T, "`RTTI Type Descriptor'");
458  }
459  case SpecialIntrinsicKind::RttiBaseClassArray:
460  return demangleUntypedVariable(Arena, MangledName,
461  "`RTTI Base Class Array'");
462  case SpecialIntrinsicKind::RttiClassHierarchyDescriptor:
463  return demangleUntypedVariable(Arena, MangledName,
464  "`RTTI Class Hierarchy Descriptor'");
465  case SpecialIntrinsicKind::RttiBaseClassDescriptor:
466  return demangleRttiBaseClassDescriptorNode(Arena, MangledName);
467  case SpecialIntrinsicKind::DynamicInitializer:
468  return demangleInitFiniStub(MangledName, /*IsDestructor=*/false);
469  case SpecialIntrinsicKind::DynamicAtexitDestructor:
470  return demangleInitFiniStub(MangledName, /*IsDestructor=*/true);
471  case SpecialIntrinsicKind::Typeof:
472  case SpecialIntrinsicKind::UdtReturning:
473  // It's unclear which tools produces these manglings, so demangling
474  // support is not (yet?) implemented.
475  break;
477  DEMANGLE_UNREACHABLE; // Never returned by consumeSpecialIntrinsicKind.
478  }
479  Error = true;
480  return nullptr;
481 }
482 
484 Demangler::demangleFunctionIdentifierCode(StringView &MangledName) {
485  assert(MangledName.startsWith('?'));
486  MangledName = MangledName.dropFront();
487  if (MangledName.empty()) {
488  Error = true;
489  return nullptr;
490  }
491 
492  if (MangledName.consumeFront("__"))
493  return demangleFunctionIdentifierCode(
494  MangledName, FunctionIdentifierCodeGroup::DoubleUnder);
495  if (MangledName.consumeFront("_"))
496  return demangleFunctionIdentifierCode(MangledName,
497  FunctionIdentifierCodeGroup::Under);
498  return demangleFunctionIdentifierCode(MangledName,
500 }
501 
503 Demangler::demangleStructorIdentifier(StringView &MangledName,
504  bool IsDestructor) {
506  N->IsDestructor = IsDestructor;
507  return N;
508 }
509 
511 Demangler::demangleConversionOperatorIdentifier(StringView &MangledName) {
514  return N;
515 }
516 
518 Demangler::demangleLiteralOperatorIdentifier(StringView &MangledName) {
521  N->Name = demangleSimpleString(MangledName, /*Memorize=*/false);
522  return N;
523 }
524 
526 Demangler::translateIntrinsicFunctionCode(char CH,
528  using IFK = IntrinsicFunctionKind;
529  if (!(CH >= '0' && CH <= '9') && !(CH >= 'A' && CH <= 'Z')) {
530  Error = true;
531  return IFK::None;
532  }
533 
534  // Not all ? identifiers are intrinsics *functions*. This function only maps
535  // operator codes for the special functions, all others are handled elsewhere,
536  // hence the IFK::None entries in the table.
537  static IFK Basic[36] = {
538  IFK::None, // ?0 # Foo::Foo()
539  IFK::None, // ?1 # Foo::~Foo()
540  IFK::New, // ?2 # operator new
541  IFK::Delete, // ?3 # operator delete
542  IFK::Assign, // ?4 # operator=
543  IFK::RightShift, // ?5 # operator>>
544  IFK::LeftShift, // ?6 # operator<<
545  IFK::LogicalNot, // ?7 # operator!
546  IFK::Equals, // ?8 # operator==
547  IFK::NotEquals, // ?9 # operator!=
548  IFK::ArraySubscript, // ?A # operator[]
549  IFK::None, // ?B # Foo::operator <type>()
550  IFK::Pointer, // ?C # operator->
551  IFK::Dereference, // ?D # operator*
552  IFK::Increment, // ?E # operator++
553  IFK::Decrement, // ?F # operator--
554  IFK::Minus, // ?G # operator-
555  IFK::Plus, // ?H # operator+
556  IFK::BitwiseAnd, // ?I # operator&
557  IFK::MemberPointer, // ?J # operator->*
558  IFK::Divide, // ?K # operator/
559  IFK::Modulus, // ?L # operator%
560  IFK::LessThan, // ?M operator<
561  IFK::LessThanEqual, // ?N operator<=
562  IFK::GreaterThan, // ?O operator>
563  IFK::GreaterThanEqual, // ?P operator>=
564  IFK::Comma, // ?Q operator,
565  IFK::Parens, // ?R operator()
566  IFK::BitwiseNot, // ?S operator~
567  IFK::BitwiseXor, // ?T operator^
568  IFK::BitwiseOr, // ?U operator|
569  IFK::LogicalAnd, // ?V operator&&
570  IFK::LogicalOr, // ?W operator||
571  IFK::TimesEqual, // ?X operator*=
572  IFK::PlusEqual, // ?Y operator+=
573  IFK::MinusEqual, // ?Z operator-=
574  };
575  static IFK Under[36] = {
576  IFK::DivEqual, // ?_0 operator/=
577  IFK::ModEqual, // ?_1 operator%=
578  IFK::RshEqual, // ?_2 operator>>=
579  IFK::LshEqual, // ?_3 operator<<=
580  IFK::BitwiseAndEqual, // ?_4 operator&=
581  IFK::BitwiseOrEqual, // ?_5 operator|=
582  IFK::BitwiseXorEqual, // ?_6 operator^=
583  IFK::None, // ?_7 # vftable
584  IFK::None, // ?_8 # vbtable
585  IFK::None, // ?_9 # vcall
586  IFK::None, // ?_A # typeof
587  IFK::None, // ?_B # local static guard
588  IFK::None, // ?_C # string literal
589  IFK::VbaseDtor, // ?_D # vbase destructor
590  IFK::VecDelDtor, // ?_E # vector deleting destructor
591  IFK::DefaultCtorClosure, // ?_F # default constructor closure
592  IFK::ScalarDelDtor, // ?_G # scalar deleting destructor
593  IFK::VecCtorIter, // ?_H # vector constructor iterator
594  IFK::VecDtorIter, // ?_I # vector destructor iterator
595  IFK::VecVbaseCtorIter, // ?_J # vector vbase constructor iterator
596  IFK::VdispMap, // ?_K # virtual displacement map
597  IFK::EHVecCtorIter, // ?_L # eh vector constructor iterator
598  IFK::EHVecDtorIter, // ?_M # eh vector destructor iterator
599  IFK::EHVecVbaseCtorIter, // ?_N # eh vector vbase constructor iterator
600  IFK::CopyCtorClosure, // ?_O # copy constructor closure
601  IFK::None, // ?_P<name> # udt returning <name>
602  IFK::None, // ?_Q # <unknown>
603  IFK::None, // ?_R0 - ?_R4 # RTTI Codes
604  IFK::None, // ?_S # local vftable
605  IFK::LocalVftableCtorClosure, // ?_T # local vftable constructor closure
606  IFK::ArrayNew, // ?_U operator new[]
607  IFK::ArrayDelete, // ?_V operator delete[]
608  IFK::None, // ?_W <unused>
609  IFK::None, // ?_X <unused>
610  IFK::None, // ?_Y <unused>
611  IFK::None, // ?_Z <unused>
612  };
613  static IFK DoubleUnder[36] = {
614  IFK::None, // ?__0 <unused>
615  IFK::None, // ?__1 <unused>
616  IFK::None, // ?__2 <unused>
617  IFK::None, // ?__3 <unused>
618  IFK::None, // ?__4 <unused>
619  IFK::None, // ?__5 <unused>
620  IFK::None, // ?__6 <unused>
621  IFK::None, // ?__7 <unused>
622  IFK::None, // ?__8 <unused>
623  IFK::None, // ?__9 <unused>
624  IFK::ManVectorCtorIter, // ?__A managed vector ctor iterator
625  IFK::ManVectorDtorIter, // ?__B managed vector dtor iterator
626  IFK::EHVectorCopyCtorIter, // ?__C EH vector copy ctor iterator
627  IFK::EHVectorVbaseCopyCtorIter, // ?__D EH vector vbase copy ctor iter
628  IFK::None, // ?__E dynamic initializer for `T'
629  IFK::None, // ?__F dynamic atexit destructor for `T'
630  IFK::VectorCopyCtorIter, // ?__G vector copy constructor iter
631  IFK::VectorVbaseCopyCtorIter, // ?__H vector vbase copy ctor iter
632  IFK::ManVectorVbaseCopyCtorIter, // ?__I managed vector vbase copy ctor
633  // iter
634  IFK::None, // ?__J local static thread guard
635  IFK::None, // ?__K operator ""_name
636  IFK::CoAwait, // ?__L operator co_await
637  IFK::Spaceship, // ?__M operator<=>
638  IFK::None, // ?__N <unused>
639  IFK::None, // ?__O <unused>
640  IFK::None, // ?__P <unused>
641  IFK::None, // ?__Q <unused>
642  IFK::None, // ?__R <unused>
643  IFK::None, // ?__S <unused>
644  IFK::None, // ?__T <unused>
645  IFK::None, // ?__U <unused>
646  IFK::None, // ?__V <unused>
647  IFK::None, // ?__W <unused>
648  IFK::None, // ?__X <unused>
649  IFK::None, // ?__Y <unused>
650  IFK::None, // ?__Z <unused>
651  };
652 
653  int Index = (CH >= '0' && CH <= '9') ? (CH - '0') : (CH - 'A' + 10);
654  switch (Group) {
656  return Basic[Index];
657  case FunctionIdentifierCodeGroup::Under:
658  return Under[Index];
659  case FunctionIdentifierCodeGroup::DoubleUnder:
660  return DoubleUnder[Index];
661  }
663 }
664 
666 Demangler::demangleFunctionIdentifierCode(StringView &MangledName,
668  if (MangledName.empty()) {
669  Error = true;
670  return nullptr;
671  }
672  switch (Group) {
674  switch (char CH = MangledName.popFront()) {
675  case '0':
676  case '1':
677  return demangleStructorIdentifier(MangledName, CH == '1');
678  case 'B':
679  return demangleConversionOperatorIdentifier(MangledName);
680  default:
682  translateIntrinsicFunctionCode(CH, Group));
683  }
684  case FunctionIdentifierCodeGroup::Under:
686  translateIntrinsicFunctionCode(MangledName.popFront(), Group));
687  case FunctionIdentifierCodeGroup::DoubleUnder:
688  switch (char CH = MangledName.popFront()) {
689  case 'K':
690  return demangleLiteralOperatorIdentifier(MangledName);
691  default:
693  translateIntrinsicFunctionCode(CH, Group));
694  }
695  }
696 
698 }
699 
700 SymbolNode *Demangler::demangleEncodedSymbol(StringView &MangledName,
702  if (MangledName.empty()) {
703  Error = true;
704  return nullptr;
705  }
706 
707  // Read a variable.
708  switch (MangledName.front()) {
709  case '0':
710  case '1':
711  case '2':
712  case '3':
713  case '4': {
714  StorageClass SC = demangleVariableStorageClass(MangledName);
715  return demangleVariableEncoding(MangledName, SC);
716  }
717  }
718  FunctionSymbolNode *FSN = demangleFunctionEncoding(MangledName);
719 
720  IdentifierNode *UQN = Name->getUnqualifiedIdentifier();
721  if (UQN->kind() == NodeKind::ConversionOperatorIdentifier) {
723  static_cast<ConversionOperatorIdentifierNode *>(UQN);
724  if (FSN)
725  COIN->TargetType = FSN->Signature->ReturnType;
726  }
727  return FSN;
728 }
729 
730 SymbolNode *Demangler::demangleDeclarator(StringView &MangledName) {
731  // What follows is a main symbol name. This may include namespaces or class
732  // back references.
733  QualifiedNameNode *QN = demangleFullyQualifiedSymbolName(MangledName);
734  if (Error)
735  return nullptr;
736 
737  SymbolNode *Symbol = demangleEncodedSymbol(MangledName, QN);
738  if (Error)
739  return nullptr;
740  Symbol->Name = QN;
741 
743  if (UQN->kind() == NodeKind::ConversionOperatorIdentifier) {
745  static_cast<ConversionOperatorIdentifierNode *>(UQN);
746  if (!COIN->TargetType) {
747  Error = true;
748  return nullptr;
749  }
750  }
751  return Symbol;
752 }
753 
754 SymbolNode *Demangler::demangleMD5Name(StringView &MangledName) {
755  assert(MangledName.startsWith("??@"));
756  // This is an MD5 mangled name. We can't demangle it, just return the
757  // mangled name.
758  // An MD5 mangled name is ??@ followed by 32 characters and a terminating @.
759  size_t MD5Last = MangledName.find('@', strlen("??@"));
760  if (MD5Last == StringView::npos) {
761  Error = true;
762  return nullptr;
763  }
764  const char *Start = MangledName.begin();
765  MangledName = MangledName.dropFront(MD5Last + 1);
766 
767  // There are two additional special cases for MD5 names:
768  // 1. For complete object locators where the object name is long enough
769  // for the object to have an MD5 name, the complete object locator is
770  // called ??@...@??_R4@ (with a trailing "??_R4@" instead of the usual
771  // leading "??_R4". This is handled here.
772  // 2. For catchable types, in versions of MSVC before 2015 (<1900) or after
773  // 2017.2 (>= 1914), the catchable type mangling is _CT??@...@??@...@8
774  // instead of_CT??@...@8 with just one MD5 name. Since we don't yet
775  // demangle catchable types anywhere, this isn't handled for MD5 names
776  // either.
777  MangledName.consumeFront("??_R4@");
778 
779  StringView MD5(Start, MangledName.begin());
780  SymbolNode *S = Arena.alloc<SymbolNode>(NodeKind::Md5Symbol);
781  S->Name = synthesizeQualifiedName(Arena, MD5);
782 
783  return S;
784 }
785 
786 SymbolNode *Demangler::demangleTypeinfoName(StringView &MangledName) {
787  assert(MangledName.startsWith('.'));
788  MangledName.consumeFront('.');
789 
790  TypeNode *T = demangleType(MangledName, QualifierMangleMode::Result);
791  if (Error || !MangledName.empty()) {
792  Error = true;
793  return nullptr;
794  }
795  return synthesizeVariable(Arena, T, "`RTTI Type Descriptor Name'");
796 }
797 
798 // Parser entry point.
799 SymbolNode *Demangler::parse(StringView &MangledName) {
800  // Typeinfo names are strings stored in RTTI data. They're not symbol names.
801  // It's still useful to demangle them. They're the only demangled entity
802  // that doesn't start with a "?" but a ".".
803  if (MangledName.startsWith('.'))
804  return demangleTypeinfoName(MangledName);
805 
806  if (MangledName.startsWith("??@"))
807  return demangleMD5Name(MangledName);
808 
809  // MSVC-style mangled symbols must start with '?'.
810  if (!MangledName.startsWith('?')) {
811  Error = true;
812  return nullptr;
813  }
814 
815  MangledName.consumeFront('?');
816 
817  // ?$ is a template instantiation, but all other names that start with ? are
818  // operators / special names.
819  if (SymbolNode *SI = demangleSpecialIntrinsic(MangledName))
820  return SI;
821 
822  return demangleDeclarator(MangledName);
823 }
824 
825 TagTypeNode *Demangler::parseTagUniqueName(StringView &MangledName) {
826  if (!MangledName.consumeFront(".?A"))
827  return nullptr;
828  MangledName.consumeFront(".?A");
829  if (MangledName.empty())
830  return nullptr;
831 
832  return demangleClassType(MangledName);
833 }
834 
835 // <type-encoding> ::= <storage-class> <variable-type>
836 // <storage-class> ::= 0 # private static member
837 // ::= 1 # protected static member
838 // ::= 2 # public static member
839 // ::= 3 # global
840 // ::= 4 # static local
841 
842 VariableSymbolNode *Demangler::demangleVariableEncoding(StringView &MangledName,
843  StorageClass SC) {
845 
846  VSN->Type = demangleType(MangledName, QualifierMangleMode::Drop);
847  VSN->SC = SC;
848 
849  if (Error)
850  return nullptr;
851 
852  // <variable-type> ::= <type> <cvr-qualifiers>
853  // ::= <type> <pointee-cvr-qualifiers> # pointers, references
854  switch (VSN->Type->kind()) {
855  case NodeKind::PointerType: {
856  PointerTypeNode *PTN = static_cast<PointerTypeNode *>(VSN->Type);
857 
858  Qualifiers ExtraChildQuals = Q_None;
859  PTN->Quals = Qualifiers(VSN->Type->Quals |
860  demanglePointerExtQualifiers(MangledName));
861 
862  bool IsMember = false;
863  std::tie(ExtraChildQuals, IsMember) = demangleQualifiers(MangledName);
864 
865  if (PTN->ClassParent) {
866  QualifiedNameNode *BackRefName =
867  demangleFullyQualifiedTypeName(MangledName);
868  (void)BackRefName;
869  }
870  PTN->Pointee->Quals = Qualifiers(PTN->Pointee->Quals | ExtraChildQuals);
871 
872  break;
873  }
874  default:
875  VSN->Type->Quals = demangleQualifiers(MangledName).first;
876  break;
877  }
878 
879  return VSN;
880 }
881 
882 // Sometimes numbers are encoded in mangled symbols. For example,
883 // "int (*x)[20]" is a valid C type (x is a pointer to an array of
884 // length 20), so we need some way to embed numbers as part of symbols.
885 // This function parses it.
886 //
887 // <number> ::= [?] <non-negative integer>
888 //
889 // <non-negative integer> ::= <decimal digit> # when 1 <= Number <= 10
890 // ::= <hex digit>+ @ # when Number == 0 or >= 10
891 //
892 // <hex-digit> ::= [A-P] # A = 0, B = 1, ...
893 std::pair<uint64_t, bool> Demangler::demangleNumber(StringView &MangledName) {
894  bool IsNegative = MangledName.consumeFront('?');
895 
896  if (startsWithDigit(MangledName)) {
897  uint64_t Ret = MangledName[0] - '0' + 1;
898  MangledName = MangledName.dropFront(1);
899  return {Ret, IsNegative};
900  }
901 
902  uint64_t Ret = 0;
903  for (size_t i = 0; i < MangledName.size(); ++i) {
904  char C = MangledName[i];
905  if (C == '@') {
906  MangledName = MangledName.dropFront(i + 1);
907  return {Ret, IsNegative};
908  }
909  if ('A' <= C && C <= 'P') {
910  Ret = (Ret << 4) + (C - 'A');
911  continue;
912  }
913  break;
914  }
915 
916  Error = true;
917  return {0ULL, false};
918 }
919 
920 uint64_t Demangler::demangleUnsigned(StringView &MangledName) {
921  bool IsNegative = false;
922  uint64_t Number = 0;
923  std::tie(Number, IsNegative) = demangleNumber(MangledName);
924  if (IsNegative)
925  Error = true;
926  return Number;
927 }
928 
929 int64_t Demangler::demangleSigned(StringView &MangledName) {
930  bool IsNegative = false;
931  uint64_t Number = 0;
932  std::tie(Number, IsNegative) = demangleNumber(MangledName);
933  if (Number > INT64_MAX)
934  Error = true;
935  int64_t I = static_cast<int64_t>(Number);
936  return IsNegative ? -I : I;
937 }
938 
939 // First 10 strings can be referenced by special BackReferences ?0, ?1, ..., ?9.
940 // Memorize it.
941 void Demangler::memorizeString(StringView S) {
942  if (Backrefs.NamesCount >= BackrefContext::Max)
943  return;
944  for (size_t i = 0; i < Backrefs.NamesCount; ++i)
945  if (S == Backrefs.Names[i]->Name)
946  return;
948  N->Name = S;
949  Backrefs.Names[Backrefs.NamesCount++] = N;
950 }
951 
952 NamedIdentifierNode *Demangler::demangleBackRefName(StringView &MangledName) {
953  assert(startsWithDigit(MangledName));
954 
955  size_t I = MangledName[0] - '0';
956  if (I >= Backrefs.NamesCount) {
957  Error = true;
958  return nullptr;
959  }
960 
961  MangledName = MangledName.dropFront();
962  return Backrefs.Names[I];
963 }
964 
965 void Demangler::memorizeIdentifier(IdentifierNode *Identifier) {
966  // Render this class template name into a string buffer so that we can
967  // memorize it for the purpose of back-referencing.
968  OutputStream OS;
969  if (!initializeOutputStream(nullptr, nullptr, OS, 1024))
970  // FIXME: Propagate out-of-memory as an error?
971  std::terminate();
972  Identifier->output(OS, OF_Default);
973  OS << '\0';
974  char *Name = OS.getBuffer();
975 
976  StringView Owned = copyString(Name);
977  memorizeString(Owned);
978  std::free(Name);
979 }
980 
982 Demangler::demangleTemplateInstantiationName(StringView &MangledName,
983  NameBackrefBehavior NBB) {
984  assert(MangledName.startsWith("?$"));
985  MangledName.consumeFront("?$");
986 
987  BackrefContext OuterContext;
988  std::swap(OuterContext, Backrefs);
989 
991  demangleUnqualifiedSymbolName(MangledName, NBB_Simple);
992  if (!Error)
993  Identifier->TemplateParams = demangleTemplateParameterList(MangledName);
994 
995  std::swap(OuterContext, Backrefs);
996  if (Error)
997  return nullptr;
998 
999  if (NBB & NBB_Template) {
1000  // NBB_Template is only set for types and non-leaf names ("a::" in "a::b").
1001  // Structors and conversion operators only makes sense in a leaf name, so
1002  // reject them in NBB_Template contexts.
1003  if (Identifier->kind() == NodeKind::ConversionOperatorIdentifier ||
1004  Identifier->kind() == NodeKind::StructorIdentifier) {
1005  Error = true;
1006  return nullptr;
1007  }
1008 
1009  memorizeIdentifier(Identifier);
1010  }
1011 
1012  return Identifier;
1013 }
1014 
1015 NamedIdentifierNode *Demangler::demangleSimpleName(StringView &MangledName,
1016  bool Memorize) {
1017  StringView S = demangleSimpleString(MangledName, Memorize);
1018  if (Error)
1019  return nullptr;
1020 
1022  Name->Name = S;
1023  return Name;
1024 }
1025 
1026 static bool isRebasedHexDigit(char C) { return (C >= 'A' && C <= 'P'); }
1027 
1028 static uint8_t rebasedHexDigitToNumber(char C) {
1030  return (C <= 'J') ? (C - 'A') : (10 + C - 'K');
1031 }
1032 
1033 uint8_t Demangler::demangleCharLiteral(StringView &MangledName) {
1034  assert(!MangledName.empty());
1035  if (!MangledName.startsWith('?'))
1036  return MangledName.popFront();
1037 
1038  MangledName = MangledName.dropFront();
1039  if (MangledName.empty())
1040  goto CharLiteralError;
1041 
1042  if (MangledName.consumeFront('$')) {
1043  // Two hex digits
1044  if (MangledName.size() < 2)
1045  goto CharLiteralError;
1046  StringView Nibbles = MangledName.substr(0, 2);
1047  if (!isRebasedHexDigit(Nibbles[0]) || !isRebasedHexDigit(Nibbles[1]))
1048  goto CharLiteralError;
1049  // Don't append the null terminator.
1050  uint8_t C1 = rebasedHexDigitToNumber(Nibbles[0]);
1051  uint8_t C2 = rebasedHexDigitToNumber(Nibbles[1]);
1052  MangledName = MangledName.dropFront(2);
1053  return (C1 << 4) | C2;
1054  }
1055 
1056  if (startsWithDigit(MangledName)) {
1057  const char *Lookup = ",/\\:. \n\t'-";
1058  char C = Lookup[MangledName[0] - '0'];
1059  MangledName = MangledName.dropFront();
1060  return C;
1061  }
1062 
1063  if (MangledName[0] >= 'a' && MangledName[0] <= 'z') {
1064  char Lookup[26] = {'\xE1', '\xE2', '\xE3', '\xE4', '\xE5', '\xE6', '\xE7',
1065  '\xE8', '\xE9', '\xEA', '\xEB', '\xEC', '\xED', '\xEE',
1066  '\xEF', '\xF0', '\xF1', '\xF2', '\xF3', '\xF4', '\xF5',
1067  '\xF6', '\xF7', '\xF8', '\xF9', '\xFA'};
1068  char C = Lookup[MangledName[0] - 'a'];
1069  MangledName = MangledName.dropFront();
1070  return C;
1071  }
1072 
1073  if (MangledName[0] >= 'A' && MangledName[0] <= 'Z') {
1074  char Lookup[26] = {'\xC1', '\xC2', '\xC3', '\xC4', '\xC5', '\xC6', '\xC7',
1075  '\xC8', '\xC9', '\xCA', '\xCB', '\xCC', '\xCD', '\xCE',
1076  '\xCF', '\xD0', '\xD1', '\xD2', '\xD3', '\xD4', '\xD5',
1077  '\xD6', '\xD7', '\xD8', '\xD9', '\xDA'};
1078  char C = Lookup[MangledName[0] - 'A'];
1079  MangledName = MangledName.dropFront();
1080  return C;
1081  }
1082 
1083 CharLiteralError:
1084  Error = true;
1085  return '\0';
1086 }
1087 
1088 wchar_t Demangler::demangleWcharLiteral(StringView &MangledName) {
1089  uint8_t C1, C2;
1090 
1091  C1 = demangleCharLiteral(MangledName);
1092  if (Error || MangledName.empty())
1093  goto WCharLiteralError;
1094  C2 = demangleCharLiteral(MangledName);
1095  if (Error)
1096  goto WCharLiteralError;
1097 
1098  return ((wchar_t)C1 << 8) | (wchar_t)C2;
1099 
1100 WCharLiteralError:
1101  Error = true;
1102  return L'\0';
1103 }
1104 
1105 static void writeHexDigit(char *Buffer, uint8_t Digit) {
1106  assert(Digit <= 15);
1107  *Buffer = (Digit < 10) ? ('0' + Digit) : ('A' + Digit - 10);
1108 }
1109 
1110 static void outputHex(OutputStream &OS, unsigned C) {
1111  assert (C != 0);
1112 
1113  // It's easier to do the math if we can work from right to left, but we need
1114  // to print the numbers from left to right. So render this into a temporary
1115  // buffer first, then output the temporary buffer. Each byte is of the form
1116  // \xAB, which means that each byte needs 4 characters. Since there are at
1117  // most 4 bytes, we need a 4*4+1 = 17 character temporary buffer.
1118  char TempBuffer[17];
1119 
1120  ::memset(TempBuffer, 0, sizeof(TempBuffer));
1121  constexpr int MaxPos = sizeof(TempBuffer) - 1;
1122 
1123  int Pos = MaxPos - 1; // TempBuffer[MaxPos] is the terminating \0.
1124  while (C != 0) {
1125  for (int I = 0; I < 2; ++I) {
1126  writeHexDigit(&TempBuffer[Pos--], C % 16);
1127  C /= 16;
1128  }
1129  }
1130  TempBuffer[Pos--] = 'x';
1131  assert(Pos >= 0);
1132  TempBuffer[Pos--] = '\\';
1133  OS << StringView(&TempBuffer[Pos + 1]);
1134 }
1135 
1136 static void outputEscapedChar(OutputStream &OS, unsigned C) {
1137  switch (C) {
1138  case '\0': // nul
1139  OS << "\\0";
1140  return;
1141  case '\'': // single quote
1142  OS << "\\\'";
1143  return;
1144  case '\"': // double quote
1145  OS << "\\\"";
1146  return;
1147  case '\\': // backslash
1148  OS << "\\\\";
1149  return;
1150  case '\a': // bell
1151  OS << "\\a";
1152  return;
1153  case '\b': // backspace
1154  OS << "\\b";
1155  return;
1156  case '\f': // form feed
1157  OS << "\\f";
1158  return;
1159  case '\n': // new line
1160  OS << "\\n";
1161  return;
1162  case '\r': // carriage return
1163  OS << "\\r";
1164  return;
1165  case '\t': // tab
1166  OS << "\\t";
1167  return;
1168  case '\v': // vertical tab
1169  OS << "\\v";
1170  return;
1171  default:
1172  break;
1173  }
1174 
1175  if (C > 0x1F && C < 0x7F) {
1176  // Standard ascii char.
1177  OS << (char)C;
1178  return;
1179  }
1180 
1181  outputHex(OS, C);
1182 }
1183 
1184 static unsigned countTrailingNullBytes(const uint8_t *StringBytes, int Length) {
1185  const uint8_t *End = StringBytes + Length - 1;
1186  unsigned Count = 0;
1187  while (Length > 0 && *End == 0) {
1188  --Length;
1189  --End;
1190  ++Count;
1191  }
1192  return Count;
1193 }
1194 
1195 static unsigned countEmbeddedNulls(const uint8_t *StringBytes,
1196  unsigned Length) {
1197  unsigned Result = 0;
1198  for (unsigned I = 0; I < Length; ++I) {
1199  if (*StringBytes++ == 0)
1200  ++Result;
1201  }
1202  return Result;
1203 }
1204 
1205 // A mangled (non-wide) string literal stores the total length of the string it
1206 // refers to (passed in NumBytes), and it contains up to 32 bytes of actual text
1207 // (passed in StringBytes, NumChars).
1208 static unsigned guessCharByteSize(const uint8_t *StringBytes, unsigned NumChars,
1209  uint64_t NumBytes) {
1210  assert(NumBytes > 0);
1211 
1212  // If the number of bytes is odd, this is guaranteed to be a char string.
1213  if (NumBytes % 2 == 1)
1214  return 1;
1215 
1216  // All strings can encode at most 32 bytes of data. If it's less than that,
1217  // then we encoded the entire string. In this case we check for a 1-byte,
1218  // 2-byte, or 4-byte null terminator.
1219  if (NumBytes < 32) {
1220  unsigned TrailingNulls = countTrailingNullBytes(StringBytes, NumChars);
1221  if (TrailingNulls >= 4 && NumBytes % 4 == 0)
1222  return 4;
1223  if (TrailingNulls >= 2)
1224  return 2;
1225  return 1;
1226  }
1227 
1228  // The whole string was not able to be encoded. Try to look at embedded null
1229  // terminators to guess. The heuristic is that we count all embedded null
1230  // terminators. If more than 2/3 are null, it's a char32. If more than 1/3
1231  // are null, it's a char16. Otherwise it's a char8. This obviously isn't
1232  // perfect and is biased towards languages that have ascii alphabets, but this
1233  // was always going to be best effort since the encoding is lossy.
1234  unsigned Nulls = countEmbeddedNulls(StringBytes, NumChars);
1235  if (Nulls >= 2 * NumChars / 3 && NumBytes % 4 == 0)
1236  return 4;
1237  if (Nulls >= NumChars / 3)
1238  return 2;
1239  return 1;
1240 }
1241 
1242 static unsigned decodeMultiByteChar(const uint8_t *StringBytes,
1243  unsigned CharIndex, unsigned CharBytes) {
1244  assert(CharBytes == 1 || CharBytes == 2 || CharBytes == 4);
1245  unsigned Offset = CharIndex * CharBytes;
1246  unsigned Result = 0;
1247  StringBytes = StringBytes + Offset;
1248  for (unsigned I = 0; I < CharBytes; ++I) {
1249  unsigned C = static_cast<unsigned>(StringBytes[I]);
1250  Result |= C << (8 * I);
1251  }
1252  return Result;
1253 }
1254 
1255 FunctionSymbolNode *Demangler::demangleVcallThunkNode(StringView &MangledName) {
1258  FSN->Signature = Arena.alloc<ThunkSignatureNode>();
1260 
1261  FSN->Name = demangleNameScopeChain(MangledName, VTIN);
1262  if (!Error)
1263  Error = !MangledName.consumeFront("$B");
1264  if (!Error)
1265  VTIN->OffsetInVTable = demangleUnsigned(MangledName);
1266  if (!Error)
1267  Error = !MangledName.consumeFront('A');
1268  if (!Error)
1269  FSN->Signature->CallConvention = demangleCallingConvention(MangledName);
1270  return (Error) ? nullptr : FSN;
1271 }
1272 
1274 Demangler::demangleStringLiteral(StringView &MangledName) {
1275  // This function uses goto, so declare all variables up front.
1276  OutputStream OS;
1277  StringView CRC;
1278  uint64_t StringByteSize;
1279  bool IsWcharT = false;
1280  bool IsNegative = false;
1281  size_t CrcEndPos = 0;
1282  char *ResultBuffer = nullptr;
1283 
1285 
1286  // Must happen before the first `goto StringLiteralError`.
1287  if (!initializeOutputStream(nullptr, nullptr, OS, 1024))
1288  // FIXME: Propagate out-of-memory as an error?
1289  std::terminate();
1290 
1291  // Prefix indicating the beginning of a string literal
1292  if (!MangledName.consumeFront("@_"))
1293  goto StringLiteralError;
1294  if (MangledName.empty())
1295  goto StringLiteralError;
1296 
1297  // Char Type (regular or wchar_t)
1298  switch (MangledName.popFront()) {
1299  case '1':
1300  IsWcharT = true;
1302  case '0':
1303  break;
1304  default:
1305  goto StringLiteralError;
1306  }
1307 
1308  // Encoded Length
1309  std::tie(StringByteSize, IsNegative) = demangleNumber(MangledName);
1310  if (Error || IsNegative || StringByteSize < (IsWcharT ? 2 : 1))
1311  goto StringLiteralError;
1312 
1313  // CRC 32 (always 8 characters plus a terminator)
1314  CrcEndPos = MangledName.find('@');
1315  if (CrcEndPos == StringView::npos)
1316  goto StringLiteralError;
1317  CRC = MangledName.substr(0, CrcEndPos);
1318  MangledName = MangledName.dropFront(CrcEndPos + 1);
1319  if (MangledName.empty())
1320  goto StringLiteralError;
1321 
1322  if (IsWcharT) {
1323  Result->Char = CharKind::Wchar;
1324  if (StringByteSize > 64)
1325  Result->IsTruncated = true;
1326 
1327  while (!MangledName.consumeFront('@')) {
1328  if (MangledName.size() < 2)
1329  goto StringLiteralError;
1330  wchar_t W = demangleWcharLiteral(MangledName);
1331  if (StringByteSize != 2 || Result->IsTruncated)
1332  outputEscapedChar(OS, W);
1333  StringByteSize -= 2;
1334  if (Error)
1335  goto StringLiteralError;
1336  }
1337  } else {
1338  // The max byte length is actually 32, but some compilers mangled strings
1339  // incorrectly, so we have to assume it can go higher.
1340  constexpr unsigned MaxStringByteLength = 32 * 4;
1341  uint8_t StringBytes[MaxStringByteLength];
1342 
1343  unsigned BytesDecoded = 0;
1344  while (!MangledName.consumeFront('@')) {
1345  if (MangledName.size() < 1 || BytesDecoded >= MaxStringByteLength)
1346  goto StringLiteralError;
1347  StringBytes[BytesDecoded++] = demangleCharLiteral(MangledName);
1348  }
1349 
1350  if (StringByteSize > BytesDecoded)
1351  Result->IsTruncated = true;
1352 
1353  unsigned CharBytes =
1354  guessCharByteSize(StringBytes, BytesDecoded, StringByteSize);
1355  assert(StringByteSize % CharBytes == 0);
1356  switch (CharBytes) {
1357  case 1:
1358  Result->Char = CharKind::Char;
1359  break;
1360  case 2:
1361  Result->Char = CharKind::Char16;
1362  break;
1363  case 4:
1364  Result->Char = CharKind::Char32;
1365  break;
1366  default:
1368  }
1369  const unsigned NumChars = BytesDecoded / CharBytes;
1370  for (unsigned CharIndex = 0; CharIndex < NumChars; ++CharIndex) {
1371  unsigned NextChar =
1372  decodeMultiByteChar(StringBytes, CharIndex, CharBytes);
1373  if (CharIndex + 1 < NumChars || Result->IsTruncated)
1374  outputEscapedChar(OS, NextChar);
1375  }
1376  }
1377 
1378  OS << '\0';
1379  ResultBuffer = OS.getBuffer();
1380  Result->DecodedString = copyString(ResultBuffer);
1381  std::free(ResultBuffer);
1382  return Result;
1383 
1384 StringLiteralError:
1385  Error = true;
1386  std::free(OS.getBuffer());
1387  return nullptr;
1388 }
1389 
1390 // Returns MangledName's prefix before the first '@', or an error if
1391 // MangledName contains no '@' or the prefix has length 0.
1392 StringView Demangler::demangleSimpleString(StringView &MangledName,
1393  bool Memorize) {
1394  StringView S;
1395  for (size_t i = 0; i < MangledName.size(); ++i) {
1396  if (MangledName[i] != '@')
1397  continue;
1398  if (i == 0)
1399  break;
1400  S = MangledName.substr(0, i);
1401  MangledName = MangledName.dropFront(i + 1);
1402 
1403  if (Memorize)
1404  memorizeString(S);
1405  return S;
1406  }
1407 
1408  Error = true;
1409  return {};
1410 }
1411 
1413 Demangler::demangleAnonymousNamespaceName(StringView &MangledName) {
1414  assert(MangledName.startsWith("?A"));
1415  MangledName.consumeFront("?A");
1416 
1418  Node->Name = "`anonymous namespace'";
1419  size_t EndPos = MangledName.find('@');
1420  if (EndPos == StringView::npos) {
1421  Error = true;
1422  return nullptr;
1423  }
1424  StringView NamespaceKey = MangledName.substr(0, EndPos);
1425  memorizeString(NamespaceKey);
1426  MangledName = MangledName.substr(EndPos + 1);
1427  return Node;
1428 }
1429 
1431 Demangler::demangleLocallyScopedNamePiece(StringView &MangledName) {
1432  assert(startsWithLocalScopePattern(MangledName));
1433 
1435  MangledName.consumeFront('?');
1436  uint64_t Number = 0;
1437  bool IsNegative = false;
1438  std::tie(Number, IsNegative) = demangleNumber(MangledName);
1439  assert(!IsNegative);
1440 
1441  // One ? to terminate the number
1442  MangledName.consumeFront('?');
1443 
1444  assert(!Error);
1445  Node *Scope = parse(MangledName);
1446  if (Error)
1447  return nullptr;
1448 
1449  // Render the parent symbol's name into a buffer.
1450  OutputStream OS;
1451  if (!initializeOutputStream(nullptr, nullptr, OS, 1024))
1452  // FIXME: Propagate out-of-memory as an error?
1453  std::terminate();
1454  OS << '`';
1455  Scope->output(OS, OF_Default);
1456  OS << '\'';
1457  OS << "::`" << Number << "'";
1458  OS << '\0';
1459  char *Result = OS.getBuffer();
1460  Identifier->Name = copyString(Result);
1461  std::free(Result);
1462  return Identifier;
1463 }
1464 
1465 // Parses a type name in the form of A@B@C@@ which represents C::B::A.
1467 Demangler::demangleFullyQualifiedTypeName(StringView &MangledName) {
1469  demangleUnqualifiedTypeName(MangledName, /*Memorize=*/true);
1470  if (Error)
1471  return nullptr;
1472  assert(Identifier);
1473 
1474  QualifiedNameNode *QN = demangleNameScopeChain(MangledName, Identifier);
1475  if (Error)
1476  return nullptr;
1477  assert(QN);
1478  return QN;
1479 }
1480 
1481 // Parses a symbol name in the form of A@B@C@@ which represents C::B::A.
1482 // Symbol names have slightly different rules regarding what can appear
1483 // so we separate out the implementations for flexibility.
1485 Demangler::demangleFullyQualifiedSymbolName(StringView &MangledName) {
1486  // This is the final component of a symbol name (i.e. the leftmost component
1487  // of a mangled name. Since the only possible template instantiation that
1488  // can appear in this context is a function template, and since those are
1489  // not saved for the purposes of name backreferences, only backref simple
1490  // names.
1492  demangleUnqualifiedSymbolName(MangledName, NBB_Simple);
1493  if (Error)
1494  return nullptr;
1495 
1496  QualifiedNameNode *QN = demangleNameScopeChain(MangledName, Identifier);
1497  if (Error)
1498  return nullptr;
1499 
1500  if (Identifier->kind() == NodeKind::StructorIdentifier) {
1501  if (QN->Components->Count < 2) {
1502  Error = true;
1503  return nullptr;
1504  }
1505  StructorIdentifierNode *SIN =
1506  static_cast<StructorIdentifierNode *>(Identifier);
1507  Node *ClassNode = QN->Components->Nodes[QN->Components->Count - 2];
1508  SIN->Class = static_cast<IdentifierNode *>(ClassNode);
1509  }
1510  assert(QN);
1511  return QN;
1512 }
1513 
1514 IdentifierNode *Demangler::demangleUnqualifiedTypeName(StringView &MangledName,
1515  bool Memorize) {
1516  // An inner-most name can be a back-reference, because a fully-qualified name
1517  // (e.g. Scope + Inner) can contain other fully qualified names inside of
1518  // them (for example template parameters), and these nested parameters can
1519  // refer to previously mangled types.
1520  if (startsWithDigit(MangledName))
1521  return demangleBackRefName(MangledName);
1522 
1523  if (MangledName.startsWith("?$"))
1524  return demangleTemplateInstantiationName(MangledName, NBB_Template);
1525 
1526  return demangleSimpleName(MangledName, Memorize);
1527 }
1528 
1530 Demangler::demangleUnqualifiedSymbolName(StringView &MangledName,
1531  NameBackrefBehavior NBB) {
1532  if (startsWithDigit(MangledName))
1533  return demangleBackRefName(MangledName);
1534  if (MangledName.startsWith("?$"))
1535  return demangleTemplateInstantiationName(MangledName, NBB);
1536  if (MangledName.startsWith('?'))
1537  return demangleFunctionIdentifierCode(MangledName);
1538  return demangleSimpleName(MangledName, /*Memorize=*/(NBB & NBB_Simple) != 0);
1539 }
1540 
1541 IdentifierNode *Demangler::demangleNameScopePiece(StringView &MangledName) {
1542  if (startsWithDigit(MangledName))
1543  return demangleBackRefName(MangledName);
1544 
1545  if (MangledName.startsWith("?$"))
1546  return demangleTemplateInstantiationName(MangledName, NBB_Template);
1547 
1548  if (MangledName.startsWith("?A"))
1549  return demangleAnonymousNamespaceName(MangledName);
1550 
1551  if (startsWithLocalScopePattern(MangledName))
1552  return demangleLocallyScopedNamePiece(MangledName);
1553 
1554  return demangleSimpleName(MangledName, /*Memorize=*/true);
1555 }
1556 
1558  size_t Count) {
1559  NodeArrayNode *N = Arena.alloc<NodeArrayNode>();
1560  N->Count = Count;
1561  N->Nodes = Arena.allocArray<Node *>(Count);
1562  for (size_t I = 0; I < Count; ++I) {
1563  N->Nodes[I] = Head->N;
1564  Head = Head->Next;
1565  }
1566  return N;
1567 }
1568 
1570 Demangler::demangleNameScopeChain(StringView &MangledName,
1571  IdentifierNode *UnqualifiedName) {
1572  NodeList *Head = Arena.alloc<NodeList>();
1573 
1574  Head->N = UnqualifiedName;
1575 
1576  size_t Count = 1;
1577  while (!MangledName.consumeFront("@")) {
1578  ++Count;
1579  NodeList *NewHead = Arena.alloc<NodeList>();
1580  NewHead->Next = Head;
1581  Head = NewHead;
1582 
1583  if (MangledName.empty()) {
1584  Error = true;
1585  return nullptr;
1586  }
1587 
1588  assert(!Error);
1589  IdentifierNode *Elem = demangleNameScopePiece(MangledName);
1590  if (Error)
1591  return nullptr;
1592 
1593  Head->N = Elem;
1594  }
1595 
1596  QualifiedNameNode *QN = Arena.alloc<QualifiedNameNode>();
1597  QN->Components = nodeListToNodeArray(Arena, Head, Count);
1598  return QN;
1599 }
1600 
1601 FuncClass Demangler::demangleFunctionClass(StringView &MangledName) {
1602  switch (MangledName.popFront()) {
1603  case '9':
1605  case 'A':
1606  return FC_Private;
1607  case 'B':
1608  return FuncClass(FC_Private | FC_Far);
1609  case 'C':
1610  return FuncClass(FC_Private | FC_Static);
1611  case 'D':
1612  return FuncClass(FC_Private | FC_Static | FC_Far);
1613  case 'E':
1614  return FuncClass(FC_Private | FC_Virtual);
1615  case 'F':
1616  return FuncClass(FC_Private | FC_Virtual | FC_Far);
1617  case 'G':
1619  case 'H':
1621  case 'I':
1622  return FuncClass(FC_Protected);
1623  case 'J':
1624  return FuncClass(FC_Protected | FC_Far);
1625  case 'K':
1626  return FuncClass(FC_Protected | FC_Static);
1627  case 'L':
1628  return FuncClass(FC_Protected | FC_Static | FC_Far);
1629  case 'M':
1630  return FuncClass(FC_Protected | FC_Virtual);
1631  case 'N':
1633  case 'O':
1635  case 'P':
1637  case 'Q':
1638  return FuncClass(FC_Public);
1639  case 'R':
1640  return FuncClass(FC_Public | FC_Far);
1641  case 'S':
1642  return FuncClass(FC_Public | FC_Static);
1643  case 'T':
1644  return FuncClass(FC_Public | FC_Static | FC_Far);
1645  case 'U':
1646  return FuncClass(FC_Public | FC_Virtual);
1647  case 'V':
1648  return FuncClass(FC_Public | FC_Virtual | FC_Far);
1649  case 'W':
1651  case 'X':
1653  case 'Y':
1654  return FuncClass(FC_Global);
1655  case 'Z':
1656  return FuncClass(FC_Global | FC_Far);
1657  case '$': {
1659  if (MangledName.consumeFront('R'))
1660  VFlag = FuncClass(VFlag | FC_VirtualThisAdjustEx);
1661  if (MangledName.empty())
1662  break;
1663  switch (MangledName.popFront()) {
1664  case '0':
1665  return FuncClass(FC_Private | FC_Virtual | VFlag);
1666  case '1':
1667  return FuncClass(FC_Private | FC_Virtual | VFlag | FC_Far);
1668  case '2':
1669  return FuncClass(FC_Protected | FC_Virtual | VFlag);
1670  case '3':
1671  return FuncClass(FC_Protected | FC_Virtual | VFlag | FC_Far);
1672  case '4':
1673  return FuncClass(FC_Public | FC_Virtual | VFlag);
1674  case '5':
1675  return FuncClass(FC_Public | FC_Virtual | VFlag | FC_Far);
1676  }
1677  }
1678  }
1679 
1680  Error = true;
1681  return FC_Public;
1682 }
1683 
1684 CallingConv Demangler::demangleCallingConvention(StringView &MangledName) {
1685  if (MangledName.empty()) {
1686  Error = true;
1687  return CallingConv::None;
1688  }
1689 
1690  switch (MangledName.popFront()) {
1691  case 'A':
1692  case 'B':
1693  return CallingConv::Cdecl;
1694  case 'C':
1695  case 'D':
1696  return CallingConv::Pascal;
1697  case 'E':
1698  case 'F':
1699  return CallingConv::Thiscall;
1700  case 'G':
1701  case 'H':
1702  return CallingConv::Stdcall;
1703  case 'I':
1704  case 'J':
1705  return CallingConv::Fastcall;
1706  case 'M':
1707  case 'N':
1708  return CallingConv::Clrcall;
1709  case 'O':
1710  case 'P':
1711  return CallingConv::Eabi;
1712  case 'Q':
1713  return CallingConv::Vectorcall;
1714  case 'S':
1715  return CallingConv::Swift;
1716  }
1717 
1718  return CallingConv::None;
1719 }
1720 
1721 StorageClass Demangler::demangleVariableStorageClass(StringView &MangledName) {
1722  assert(MangledName.front() >= '0' && MangledName.front() <= '4');
1723 
1724  switch (MangledName.popFront()) {
1725  case '0':
1726  return StorageClass::PrivateStatic;
1727  case '1':
1728  return StorageClass::ProtectedStatic;
1729  case '2':
1730  return StorageClass::PublicStatic;
1731  case '3':
1732  return StorageClass::Global;
1733  case '4':
1734  return StorageClass::FunctionLocalStatic;
1735  }
1737 }
1738 
1739 std::pair<Qualifiers, bool>
1740 Demangler::demangleQualifiers(StringView &MangledName) {
1741  if (MangledName.empty()) {
1742  Error = true;
1743  return std::make_pair(Q_None, false);
1744  }
1745 
1746  switch (MangledName.popFront()) {
1747  // Member qualifiers
1748  case 'Q':
1749  return std::make_pair(Q_None, true);
1750  case 'R':
1751  return std::make_pair(Q_Const, true);
1752  case 'S':
1753  return std::make_pair(Q_Volatile, true);
1754  case 'T':
1755  return std::make_pair(Qualifiers(Q_Const | Q_Volatile), true);
1756  // Non-Member qualifiers
1757  case 'A':
1758  return std::make_pair(Q_None, false);
1759  case 'B':
1760  return std::make_pair(Q_Const, false);
1761  case 'C':
1762  return std::make_pair(Q_Volatile, false);
1763  case 'D':
1764  return std::make_pair(Qualifiers(Q_Const | Q_Volatile), false);
1765  }
1766  Error = true;
1767  return std::make_pair(Q_None, false);
1768 }
1769 
1770 // <variable-type> ::= <type> <cvr-qualifiers>
1771 // ::= <type> <pointee-cvr-qualifiers> # pointers, references
1772 TypeNode *Demangler::demangleType(StringView &MangledName,
1773  QualifierMangleMode QMM) {
1774  Qualifiers Quals = Q_None;
1775  bool IsMember = false;
1776  if (QMM == QualifierMangleMode::Mangle) {
1777  std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1778  } else if (QMM == QualifierMangleMode::Result) {
1779  if (MangledName.consumeFront('?'))
1780  std::tie(Quals, IsMember) = demangleQualifiers(MangledName);
1781  }
1782 
1783  if (MangledName.empty()) {
1784  Error = true;
1785  return nullptr;
1786  }
1787 
1788  TypeNode *Ty = nullptr;
1789  if (isTagType(MangledName))
1790  Ty = demangleClassType(MangledName);
1791  else if (isPointerType(MangledName)) {
1792  if (isMemberPointer(MangledName, Error))
1793  Ty = demangleMemberPointerType(MangledName);
1794  else if (!Error)
1795  Ty = demanglePointerType(MangledName);
1796  else
1797  return nullptr;
1798  } else if (isArrayType(MangledName))
1799  Ty = demangleArrayType(MangledName);
1800  else if (isFunctionType(MangledName)) {
1801  if (MangledName.consumeFront("$$A8@@"))
1802  Ty = demangleFunctionType(MangledName, true);
1803  else {
1804  assert(MangledName.startsWith("$$A6"));
1805  MangledName.consumeFront("$$A6");
1806  Ty = demangleFunctionType(MangledName, false);
1807  }
1808  } else if (isCustomType(MangledName)) {
1809  Ty = demangleCustomType(MangledName);
1810  } else {
1811  Ty = demanglePrimitiveType(MangledName);
1812  }
1813 
1814  if (!Ty || Error)
1815  return Ty;
1816  Ty->Quals = Qualifiers(Ty->Quals | Quals);
1817  return Ty;
1818 }
1819 
1820 bool Demangler::demangleThrowSpecification(StringView &MangledName) {
1821  if (MangledName.consumeFront("_E"))
1822  return true;
1823  if (MangledName.consumeFront('Z'))
1824  return false;
1825 
1826  Error = true;
1827  return false;
1828 }
1829 
1830 FunctionSignatureNode *Demangler::demangleFunctionType(StringView &MangledName,
1831  bool HasThisQuals) {
1833 
1834  if (HasThisQuals) {
1835  FTy->Quals = demanglePointerExtQualifiers(MangledName);
1836  FTy->RefQualifier = demangleFunctionRefQualifier(MangledName);
1837  FTy->Quals = Qualifiers(FTy->Quals | demangleQualifiers(MangledName).first);
1838  }
1839 
1840  // Fields that appear on both member and non-member functions.
1841  FTy->CallConvention = demangleCallingConvention(MangledName);
1842 
1843  // <return-type> ::= <type>
1844  // ::= @ # structors (they have no declared return type)
1845  bool IsStructor = MangledName.consumeFront('@');
1846  if (!IsStructor)
1847  FTy->ReturnType = demangleType(MangledName, QualifierMangleMode::Result);
1848 
1849  FTy->Params = demangleFunctionParameterList(MangledName, FTy->IsVariadic);
1850 
1851  FTy->IsNoexcept = demangleThrowSpecification(MangledName);
1852 
1853  return FTy;
1854 }
1855 
1857 Demangler::demangleFunctionEncoding(StringView &MangledName) {
1858  FuncClass ExtraFlags = FC_None;
1859  if (MangledName.consumeFront("$$J0"))
1860  ExtraFlags = FC_ExternC;
1861 
1862  if (MangledName.empty()) {
1863  Error = true;
1864  return nullptr;
1865  }
1866 
1867  FuncClass FC = demangleFunctionClass(MangledName);
1868  FC = FuncClass(ExtraFlags | FC);
1869 
1870  FunctionSignatureNode *FSN = nullptr;
1871  ThunkSignatureNode *TTN = nullptr;
1872  if (FC & FC_StaticThisAdjust) {
1873  TTN = Arena.alloc<ThunkSignatureNode>();
1874  TTN->ThisAdjust.StaticOffset = demangleSigned(MangledName);
1875  } else if (FC & FC_VirtualThisAdjust) {
1876  TTN = Arena.alloc<ThunkSignatureNode>();
1877  if (FC & FC_VirtualThisAdjustEx) {
1878  TTN->ThisAdjust.VBPtrOffset = demangleSigned(MangledName);
1879  TTN->ThisAdjust.VBOffsetOffset = demangleSigned(MangledName);
1880  }
1881  TTN->ThisAdjust.VtordispOffset = demangleSigned(MangledName);
1882  TTN->ThisAdjust.StaticOffset = demangleSigned(MangledName);
1883  }
1884 
1885  if (FC & FC_NoParameterList) {
1886  // This is an extern "C" function whose full signature hasn't been mangled.
1887  // This happens when we need to mangle a local symbol inside of an extern
1888  // "C" function.
1889  FSN = Arena.alloc<FunctionSignatureNode>();
1890  } else {
1891  bool HasThisQuals = !(FC & (FC_Global | FC_Static));
1892  FSN = demangleFunctionType(MangledName, HasThisQuals);
1893  }
1894 
1895  if (Error)
1896  return nullptr;
1897 
1898  if (TTN) {
1899  *static_cast<FunctionSignatureNode *>(TTN) = *FSN;
1900  FSN = TTN;
1901  }
1902  FSN->FunctionClass = FC;
1903 
1905  Symbol->Signature = FSN;
1906  return Symbol;
1907 }
1908 
1909 CustomTypeNode *Demangler::demangleCustomType(StringView &MangledName) {
1910  assert(MangledName.startsWith('?'));
1911  MangledName.popFront();
1912 
1913  CustomTypeNode *CTN = Arena.alloc<CustomTypeNode>();
1914  CTN->Identifier = demangleUnqualifiedTypeName(MangledName, /*Memorize=*/true);
1915  if (!MangledName.consumeFront('@'))
1916  Error = true;
1917  if (Error)
1918  return nullptr;
1919  return CTN;
1920 }
1921 
1922 // Reads a primitive type.
1923 PrimitiveTypeNode *Demangler::demanglePrimitiveType(StringView &MangledName) {
1924  if (MangledName.consumeFront("$$T"))
1925  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Nullptr);
1926 
1927  switch (MangledName.popFront()) {
1928  case 'X':
1929  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Void);
1930  case 'D':
1931  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char);
1932  case 'C':
1933  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Schar);
1934  case 'E':
1935  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Uchar);
1936  case 'F':
1937  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Short);
1938  case 'G':
1939  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Ushort);
1940  case 'H':
1941  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Int);
1942  case 'I':
1943  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Uint);
1944  case 'J':
1945  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Long);
1946  case 'K':
1947  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Ulong);
1948  case 'M':
1950  case 'N':
1952  case 'O':
1953  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Ldouble);
1954  case '_': {
1955  if (MangledName.empty()) {
1956  Error = true;
1957  return nullptr;
1958  }
1959  switch (MangledName.popFront()) {
1960  case 'N':
1962  case 'J':
1964  case 'K':
1965  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Uint64);
1966  case 'W':
1967  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Wchar);
1968  case 'Q':
1969  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char8);
1970  case 'S':
1971  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char16);
1972  case 'U':
1973  return Arena.alloc<PrimitiveTypeNode>(PrimitiveKind::Char32);
1974  }
1975  break;
1976  }
1977  }
1978  Error = true;
1979  return nullptr;
1980 }
1981 
1982 TagTypeNode *Demangler::demangleClassType(StringView &MangledName) {
1983  TagTypeNode *TT = nullptr;
1984 
1985  switch (MangledName.popFront()) {
1986  case 'T':
1987  TT = Arena.alloc<TagTypeNode>(TagKind::Union);
1988  break;
1989  case 'U':
1990  TT = Arena.alloc<TagTypeNode>(TagKind::Struct);
1991  break;
1992  case 'V':
1993  TT = Arena.alloc<TagTypeNode>(TagKind::Class);
1994  break;
1995  case 'W':
1996  if (!MangledName.consumeFront('4')) {
1997  Error = true;
1998  return nullptr;
1999  }
2000  TT = Arena.alloc<TagTypeNode>(TagKind::Enum);
2001  break;
2002  default:
2003  assert(false);
2004  }
2005 
2006  TT->QualifiedName = demangleFullyQualifiedTypeName(MangledName);
2007  return TT;
2008 }
2009 
2010 // <pointer-type> ::= E? <pointer-cvr-qualifiers> <ext-qualifiers> <type>
2011 // # the E is required for 64-bit non-static pointers
2012 PointerTypeNode *Demangler::demanglePointerType(StringView &MangledName) {
2014 
2015  std::tie(Pointer->Quals, Pointer->Affinity) =
2016  demanglePointerCVQualifiers(MangledName);
2017 
2018  if (MangledName.consumeFront("6")) {
2019  Pointer->Pointee = demangleFunctionType(MangledName, false);
2020  return Pointer;
2021  }
2022 
2023  Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
2024  Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
2025 
2026  Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Mangle);
2027  return Pointer;
2028 }
2029 
2030 PointerTypeNode *Demangler::demangleMemberPointerType(StringView &MangledName) {
2032 
2033  std::tie(Pointer->Quals, Pointer->Affinity) =
2034  demanglePointerCVQualifiers(MangledName);
2035  assert(Pointer->Affinity == PointerAffinity::Pointer);
2036 
2037  Qualifiers ExtQuals = demanglePointerExtQualifiers(MangledName);
2038  Pointer->Quals = Qualifiers(Pointer->Quals | ExtQuals);
2039 
2040  // isMemberPointer() only returns true if there is at least one character
2041  // after the qualifiers.
2042  if (MangledName.consumeFront("8")) {
2043  Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
2044  Pointer->Pointee = demangleFunctionType(MangledName, true);
2045  } else {
2046  Qualifiers PointeeQuals = Q_None;
2047  bool IsMember = false;
2048  std::tie(PointeeQuals, IsMember) = demangleQualifiers(MangledName);
2049  assert(IsMember || Error);
2050  Pointer->ClassParent = demangleFullyQualifiedTypeName(MangledName);
2051 
2052  Pointer->Pointee = demangleType(MangledName, QualifierMangleMode::Drop);
2053  if (Pointer->Pointee)
2054  Pointer->Pointee->Quals = PointeeQuals;
2055  }
2056 
2057  return Pointer;
2058 }
2059 
2060 Qualifiers Demangler::demanglePointerExtQualifiers(StringView &MangledName) {
2061  Qualifiers Quals = Q_None;
2062  if (MangledName.consumeFront('E'))
2063  Quals = Qualifiers(Quals | Q_Pointer64);
2064  if (MangledName.consumeFront('I'))
2065  Quals = Qualifiers(Quals | Q_Restrict);
2066  if (MangledName.consumeFront('F'))
2067  Quals = Qualifiers(Quals | Q_Unaligned);
2068 
2069  return Quals;
2070 }
2071 
2072 ArrayTypeNode *Demangler::demangleArrayType(StringView &MangledName) {
2073  assert(MangledName.front() == 'Y');
2074  MangledName.popFront();
2075 
2076  uint64_t Rank = 0;
2077  bool IsNegative = false;
2078  std::tie(Rank, IsNegative) = demangleNumber(MangledName);
2079  if (IsNegative || Rank == 0) {
2080  Error = true;
2081  return nullptr;
2082  }
2083 
2084  ArrayTypeNode *ATy = Arena.alloc<ArrayTypeNode>();
2085  NodeList *Head = Arena.alloc<NodeList>();
2086  NodeList *Tail = Head;
2087 
2088  for (uint64_t I = 0; I < Rank; ++I) {
2089  uint64_t D = 0;
2090  std::tie(D, IsNegative) = demangleNumber(MangledName);
2091  if (Error || IsNegative) {
2092  Error = true;
2093  return nullptr;
2094  }
2095  Tail->N = Arena.alloc<IntegerLiteralNode>(D, IsNegative);
2096  if (I + 1 < Rank) {
2097  Tail->Next = Arena.alloc<NodeList>();
2098  Tail = Tail->Next;
2099  }
2100  }
2101  ATy->Dimensions = nodeListToNodeArray(Arena, Head, Rank);
2102 
2103  if (MangledName.consumeFront("$$C")) {
2104  bool IsMember = false;
2105  std::tie(ATy->Quals, IsMember) = demangleQualifiers(MangledName);
2106  if (IsMember) {
2107  Error = true;
2108  return nullptr;
2109  }
2110  }
2111 
2112  ATy->ElementType = demangleType(MangledName, QualifierMangleMode::Drop);
2113  return ATy;
2114 }
2115 
2116 // Reads a function's parameters.
2117 NodeArrayNode *Demangler::demangleFunctionParameterList(StringView &MangledName,
2118  bool &IsVariadic) {
2119  // Empty parameter list.
2120  if (MangledName.consumeFront('X'))
2121  return nullptr;
2122 
2123  NodeList *Head = Arena.alloc<NodeList>();
2124  NodeList **Current = &Head;
2125  size_t Count = 0;
2126  while (!Error && !MangledName.startsWith('@') &&
2127  !MangledName.startsWith('Z')) {
2128  ++Count;
2129 
2130  if (startsWithDigit(MangledName)) {
2131  size_t N = MangledName[0] - '0';
2132  if (N >= Backrefs.FunctionParamCount) {
2133  Error = true;
2134  return nullptr;
2135  }
2136  MangledName = MangledName.dropFront();
2137 
2138  *Current = Arena.alloc<NodeList>();
2139  (*Current)->N = Backrefs.FunctionParams[N];
2140  Current = &(*Current)->Next;
2141  continue;
2142  }
2143 
2144  size_t OldSize = MangledName.size();
2145 
2146  *Current = Arena.alloc<NodeList>();
2147  TypeNode *TN = demangleType(MangledName, QualifierMangleMode::Drop);
2148  if (!TN || Error)
2149  return nullptr;
2150 
2151  (*Current)->N = TN;
2152 
2153  size_t CharsConsumed = OldSize - MangledName.size();
2154  assert(CharsConsumed != 0);
2155 
2156  // Single-letter types are ignored for backreferences because memorizing
2157  // them doesn't save anything.
2158  if (Backrefs.FunctionParamCount <= 9 && CharsConsumed > 1)
2159  Backrefs.FunctionParams[Backrefs.FunctionParamCount++] = TN;
2160 
2161  Current = &(*Current)->Next;
2162  }
2163 
2164  if (Error)
2165  return nullptr;
2166 
2167  NodeArrayNode *NA = nodeListToNodeArray(Arena, Head, Count);
2168  // A non-empty parameter list is terminated by either 'Z' (variadic) parameter
2169  // list or '@' (non variadic). Careful not to consume "@Z", as in that case
2170  // the following Z could be a throw specifier.
2171  if (MangledName.consumeFront('@'))
2172  return NA;
2173 
2174  if (MangledName.consumeFront('Z')) {
2175  IsVariadic = true;
2176  return NA;
2177  }
2178 
2180 }
2181 
2182 NodeArrayNode *
2183 Demangler::demangleTemplateParameterList(StringView &MangledName) {
2184  NodeList *Head = nullptr;
2185  NodeList **Current = &Head;
2186  size_t Count = 0;
2187 
2188  while (!MangledName.startsWith('@')) {
2189  if (MangledName.consumeFront("$S") || MangledName.consumeFront("$$V") ||
2190  MangledName.consumeFront("$$$V") || MangledName.consumeFront("$$Z")) {
2191  // parameter pack separator
2192  continue;
2193  }
2194 
2195  ++Count;
2196 
2197  // Template parameter lists don't participate in back-referencing.
2198  *Current = Arena.alloc<NodeList>();
2199 
2200  NodeList &TP = **Current;
2201 
2202  TemplateParameterReferenceNode *TPRN = nullptr;
2203  if (MangledName.consumeFront("$$Y")) {
2204  // Template alias
2205  TP.N = demangleFullyQualifiedTypeName(MangledName);
2206  } else if (MangledName.consumeFront("$$B")) {
2207  // Array
2208  TP.N = demangleType(MangledName, QualifierMangleMode::Drop);
2209  } else if (MangledName.consumeFront("$$C")) {
2210  // Type has qualifiers.
2211  TP.N = demangleType(MangledName, QualifierMangleMode::Mangle);
2212  } else if (MangledName.startsWith("$1") || MangledName.startsWith("$H") ||
2213  MangledName.startsWith("$I") || MangledName.startsWith("$J")) {
2214  // Pointer to member
2215  TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();
2216  TPRN->IsMemberPointer = true;
2217 
2218  MangledName = MangledName.dropFront();
2219  // 1 - single inheritance <name>
2220  // H - multiple inheritance <name> <number>
2221  // I - virtual inheritance <name> <number> <number>
2222  // J - unspecified inheritance <name> <number> <number> <number>
2223  char InheritanceSpecifier = MangledName.popFront();
2224  SymbolNode *S = nullptr;
2225  if (MangledName.startsWith('?')) {
2226  S = parse(MangledName);
2227  if (Error || !S->Name) {
2228  Error = true;
2229  return nullptr;
2230  }
2231  memorizeIdentifier(S->Name->getUnqualifiedIdentifier());
2232  }
2233 
2234  switch (InheritanceSpecifier) {
2235  case 'J':
2236  TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
2237  demangleSigned(MangledName);
2239  case 'I':
2240  TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
2241  demangleSigned(MangledName);
2243  case 'H':
2244  TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
2245  demangleSigned(MangledName);
2247  case '1':
2248  break;
2249  default:
2251  }
2252  TPRN->Affinity = PointerAffinity::Pointer;
2253  TPRN->Symbol = S;
2254  } else if (MangledName.startsWith("$E?")) {
2255  MangledName.consumeFront("$E");
2256  // Reference to symbol
2257  TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();
2258  TPRN->Symbol = parse(MangledName);
2259  TPRN->Affinity = PointerAffinity::Reference;
2260  } else if (MangledName.startsWith("$F") || MangledName.startsWith("$G")) {
2261  TP.N = TPRN = Arena.alloc<TemplateParameterReferenceNode>();
2262 
2263  // Data member pointer.
2264  MangledName = MangledName.dropFront();
2265  char InheritanceSpecifier = MangledName.popFront();
2266 
2267  switch (InheritanceSpecifier) {
2268  case 'G':
2269  TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
2270  demangleSigned(MangledName);
2272  case 'F':
2273  TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
2274  demangleSigned(MangledName);
2275  TPRN->ThunkOffsets[TPRN->ThunkOffsetCount++] =
2276  demangleSigned(MangledName);
2277  break;
2278  default:
2280  }
2281  TPRN->IsMemberPointer = true;
2282 
2283  } else if (MangledName.consumeFront("$0")) {
2284  // Integral non-type template parameter
2285  bool IsNegative = false;
2286  uint64_t Value = 0;
2287  std::tie(Value, IsNegative) = demangleNumber(MangledName);
2288 
2289  TP.N = Arena.alloc<IntegerLiteralNode>(Value, IsNegative);
2290  } else {
2291  TP.N = demangleType(MangledName, QualifierMangleMode::Drop);
2292  }
2293  if (Error)
2294  return nullptr;
2295 
2296  Current = &TP.Next;
2297  }
2298 
2299  // The loop above returns nullptr on Error.
2300  assert(!Error);
2301 
2302  // Template parameter lists cannot be variadic, so it can only be terminated
2303  // by @ (as opposed to 'Z' in the function parameter case).
2304  assert(MangledName.startsWith('@')); // The above loop exits only on '@'.
2305  MangledName.consumeFront('@');
2306  return nodeListToNodeArray(Arena, Head, Count);
2307 }
2308 
2309 void Demangler::dumpBackReferences() {
2310  std::printf("%d function parameter backreferences\n",
2311  (int)Backrefs.FunctionParamCount);
2312 
2313  // Create an output stream so we can render each type.
2314  OutputStream OS;
2315  if (!initializeOutputStream(nullptr, nullptr, OS, 1024))
2316  std::terminate();
2317  for (size_t I = 0; I < Backrefs.FunctionParamCount; ++I) {
2318  OS.setCurrentPosition(0);
2319 
2320  TypeNode *T = Backrefs.FunctionParams[I];
2321  T->output(OS, OF_Default);
2322 
2323  std::printf(" [%d] - %.*s\n", (int)I, (int)OS.getCurrentPosition(),
2324  OS.getBuffer());
2325  }
2326  std::free(OS.getBuffer());
2327 
2328  if (Backrefs.FunctionParamCount > 0)
2329  std::printf("\n");
2330  std::printf("%d name backreferences\n", (int)Backrefs.NamesCount);
2331  for (size_t I = 0; I < Backrefs.NamesCount; ++I) {
2332  std::printf(" [%d] - %.*s\n", (int)I, (int)Backrefs.Names[I]->Name.size(),
2333  Backrefs.Names[I]->Name.begin());
2334  }
2335  if (Backrefs.NamesCount > 0)
2336  std::printf("\n");
2337 }
2338 
2339 char *llvm::microsoftDemangle(const char *MangledName, size_t *NMangled,
2340  char *Buf, size_t *N,
2341  int *Status, MSDemangleFlags Flags) {
2342  Demangler D;
2343  OutputStream S;
2344 
2345  StringView Name{MangledName};
2346  SymbolNode *AST = D.parse(Name);
2347  if (!D.Error && NMangled)
2348  *NMangled = Name.begin() - MangledName;
2349 
2350  if (Flags & MSDF_DumpBackrefs)
2351  D.dumpBackReferences();
2352 
2353  OutputFlags OF = OF_Default;
2354  if (Flags & MSDF_NoCallingConvention)
2356  if (Flags & MSDF_NoAccessSpecifier)
2357  OF = OutputFlags(OF | OF_NoAccessSpecifier);
2358  if (Flags & MSDF_NoReturnType)
2359  OF = OutputFlags(OF | OF_NoReturnType);
2360  if (Flags & MSDF_NoMemberType)
2361  OF = OutputFlags(OF | OF_NoMemberType);
2362 
2363  int InternalStatus = demangle_success;
2364  if (D.Error)
2365  InternalStatus = demangle_invalid_mangled_name;
2366  else if (!initializeOutputStream(Buf, N, S, 1024))
2367  InternalStatus = demangle_memory_alloc_failure;
2368  else {
2369  AST->output(S, OF);
2370  S += '\0';
2371  if (N != nullptr)
2372  *N = S.getCurrentPosition();
2373  Buf = S.getBuffer();
2374  }
2375 
2376  if (Status)
2377  *Status = InternalStatus;
2378  return InternalStatus == demangle_success ? Buf : nullptr;
2379 }
llvm::ms_demangle::DynamicStructorIdentifierNode
Definition: MicrosoftDemangleNodes.h:372
isArrayType
static bool isArrayType(StringView S)
Definition: MicrosoftDemangle.cpp:209
synthesizeQualifiedName
static QualifiedNameNode * synthesizeQualifiedName(ArenaAllocator &Arena, IdentifierNode *Identifier)
Definition: MicrosoftDemangle.cpp:325
llvm::ms_demangle::FunctionSignatureNode::FunctionClass
FuncClass FunctionClass
Definition: MicrosoftDemangleNodes.h:338
i
i
Definition: README.txt:29
consumeSpecialIntrinsicKind
static SpecialIntrinsicKind consumeSpecialIntrinsicKind(StringView &MangledName)
Definition: MicrosoftDemangle.cpp:106
llvm::CallingConv::Swift
@ Swift
Definition: CallingConv.h:73
llvm::ms_demangle::DynamicStructorIdentifierNode::Name
QualifiedNameNode * Name
Definition: MicrosoftDemangleNodes.h:379
llvm::ms_demangle::ArenaAllocator::allocUnalignedBuffer
char * allocUnalignedBuffer(size_t Size)
Definition: MicrosoftDemangle.h:58
llvm::ms_demangle::FunctionRefQualifier::Reference
@ Reference
llvm::ms_demangle::NameBackrefBehavior
NameBackrefBehavior
Definition: MicrosoftDemangle.h:129
llvm::ms_demangle::SpecialIntrinsicKind::DynamicInitializer
@ DynamicInitializer
llvm::ms_demangle::NodeArrayNode::Nodes
Node ** Nodes
Definition: MicrosoftDemangleNodes.h:522
llvm::ms_demangle::FC_Private
@ FC_Private
Definition: MicrosoftDemangleNodes.h:211
llvm::ms_demangle::OF_Default
@ OF_Default
Definition: MicrosoftDemangleNodes.h:76
llvm::ms_demangle::ArrayTypeNode
Definition: MicrosoftDemangleNodes.h:485
llvm::ms_demangle::Node
Definition: MicrosoftDemangleNodes.h:257
llvm
Definition: AllocatorList.h:23
llvm::ms_demangle::SpecialIntrinsicKind::Vbtable
@ Vbtable
llvm::ms_demangle::SpecialIntrinsicKind::RttiClassHierarchyDescriptor
@ RttiClassHierarchyDescriptor
llvm::ms_demangle::TemplateParameterReferenceNode::Symbol
SymbolNode * Symbol
Definition: MicrosoftDemangleNodes.h:545
llvm::ms_demangle::IntegerLiteralNode
Definition: MicrosoftDemangleNodes.h:553
llvm::ARM::PredBlockMask::TT
@ TT
llvm::ms_demangle::TemplateParameterReferenceNode::Affinity
PointerAffinity Affinity
Definition: MicrosoftDemangleNodes.h:549
llvm::ms_demangle::CustomTypeNode
Definition: MicrosoftDemangleNodes.h:506
outputEscapedChar
static void outputEscapedChar(OutputStream &OS, unsigned C)
Definition: MicrosoftDemangle.cpp:1136
isMemberPointer
static bool isMemberPointer(StringView MangledName, bool &Error)
Definition: MicrosoftDemangle.cpp:42
llvm::ms_demangle::QualifiedNameNode::Components
NodeArrayNode * Components
Definition: MicrosoftDemangleNodes.h:531
llvm::ms_demangle::SpecialIntrinsicKind::LocalVftable
@ LocalVftable
demanglePointerCVQualifiers
static std::pair< Qualifiers, PointerAffinity > demanglePointerCVQualifiers(StringView &MangledName)
Definition: MicrosoftDemangle.cpp:225
llvm::ms_demangle::SpecialTableSymbolNode::TargetName
QualifiedNameNode * TargetName
Definition: MicrosoftDemangleNodes.h:587
llvm::MSDF_NoAccessSpecifier
@ MSDF_NoAccessSpecifier
Definition: Demangle.h:38
writeHexDigit
static void writeHexDigit(char *Buffer, uint8_t Digit)
Definition: MicrosoftDemangle.cpp:1105
llvm::pdb::Int64
@ Int64
Definition: PDBTypes.h:399
llvm::ms_demangle::ThunkSignatureNode::ThisAdjustor::VBPtrOffset
int32_t VBPtrOffset
Definition: MicrosoftDemangleNodes.h:451
llvm::ms_demangle::PointerAffinity::Pointer
@ Pointer
llvm::ms_demangle::TemplateParameterReferenceNode::IsMemberPointer
bool IsMemberPointer
Definition: MicrosoftDemangleNodes.h:550
C1
instcombine should handle this C2 when C1
Definition: README.txt:263
llvm::ms_demangle::FunctionIdentifierCodeGroup
FunctionIdentifierCodeGroup
Definition: MicrosoftDemangle.h:135
decodeMultiByteChar
static unsigned decodeMultiByteChar(const uint8_t *StringBytes, unsigned CharIndex, unsigned CharBytes)
Definition: MicrosoftDemangle.cpp:1242
llvm::RISCVFenceField::W
@ W
Definition: RISCVBaseInfo.h:181
CH
AMD64 Optimization Manual has some nice information about optimizing integer multiplication by a constant How much of it applies to Intel s X86 implementation There are definite trade offs to xmm0 cvttss2siq rdx jb L3 subss xmm0 rax cvttss2siq rdx xorq rdx rax ret instead of xmm1 cvttss2siq rcx movaps xmm2 subss xmm2 cvttss2siq rax rdx xorq rax ucomiss xmm0 cmovb rax ret Seems like the jb branch has high likelihood of being taken It would have saved a few instructions It s not possible to reference CH
Definition: README-X86-64.txt:44
llvm::ms_demangle::Q_Restrict
@ Q_Restrict
Definition: MicrosoftDemangleNodes.h:42
R600_InstFlag::FC
@ FC
Definition: R600Defines.h:32
llvm::ms_demangle::FunctionSignatureNode
Definition: MicrosoftDemangleNodes.h:323
llvm::ms_demangle::FunctionSymbolNode::Signature
FunctionSignatureNode * Signature
Definition: MicrosoftDemangleNodes.h:624
llvm::ms_demangle::SpecialTableSymbolNode::Quals
Qualifiers Quals
Definition: MicrosoftDemangleNodes.h:588
llvm::ms_demangle::Q_Unaligned
@ Q_Unaligned
Definition: MicrosoftDemangleNodes.h:41
rebasedHexDigitToNumber
static uint8_t rebasedHexDigitToNumber(char C)
Definition: MicrosoftDemangle.cpp:1028
llvm::ms_demangle::IntrinsicFunctionIdentifierNode
Definition: MicrosoftDemangleNodes.h:391
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:46
Utility.h
llvm::ms_demangle::DynamicStructorIdentifierNode::Variable
VariableSymbolNode * Variable
Definition: MicrosoftDemangleNodes.h:378
llvm::ms_demangle::ArenaAllocator::allocArray
T * allocArray(size_t Count)
Definition: MicrosoftDemangle.h:72
T
#define T
Definition: Mips16ISelLowering.cpp:341
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::MipsISD::Ret
@ Ret
Definition: MipsISelLowering.h:116
llvm::ms_demangle::Q_Const
@ Q_Const
Definition: MicrosoftDemangleNodes.h:37
llvm::ms_demangle::ArrayTypeNode::Dimensions
NodeArrayNode * Dimensions
Definition: MicrosoftDemangleNodes.h:495
llvm::ms_demangle::Qualifiers
Qualifiers
Definition: MicrosoftDemangleNodes.h:35
llvm::ms_demangle::SpecialIntrinsicKind::UdtReturning
@ UdtReturning
llvm::codeview::PointerMode::Pointer
@ Pointer
llvm::pdb::Double
@ Double
Definition: PDBTypes.h:401
llvm::ms_demangle::TemplateParameterReferenceNode
Definition: MicrosoftDemangleNodes.h:539
llvm::ms_demangle::QualifiedNameNode
Definition: MicrosoftDemangleNodes.h:526
isTagType
static bool isTagType(StringView S)
Definition: MicrosoftDemangle.cpp:181
llvm::ms_demangle::SpecialIntrinsicKind::RttiCompleteObjLocator
@ RttiCompleteObjLocator
llvm::ms_demangle::VariableSymbolNode::SC
StorageClass SC
Definition: MicrosoftDemangleNodes.h:615
llvm::ms_demangle::FC_Global
@ FC_Global
Definition: MicrosoftDemangleNodes.h:212
llvm::ms_demangle::StorageClass
StorageClass
Definition: MicrosoftDemangleNodes.h:46
llvm::ms_demangle::FC_Static
@ FC_Static
Definition: MicrosoftDemangleNodes.h:213
llvm::ms_demangle::SpecialIntrinsicKind::LocalStaticThreadGuard
@ LocalStaticThreadGuard
llvm::ms_demangle::CallingConv
CallingConv
Definition: MicrosoftDemangleNodes.h:59
llvm::ms_demangle::OF_NoCallingConvention
@ OF_NoCallingConvention
Definition: MicrosoftDemangleNodes.h:77
llvm::PPCISD::SC
@ SC
CHAIN = SC CHAIN, Imm128 - System call.
Definition: PPCISelLowering.h:410
llvm::ms_demangle::FC_NoParameterList
@ FC_NoParameterList
Definition: MicrosoftDemangleNodes.h:217
llvm::ms_demangle::IntrinsicFunctionKind
IntrinsicFunctionKind
Definition: MicrosoftDemangleNodes.h:116
llvm::ms_demangle::FunctionSignatureNode::CallConvention
CallingConv CallConvention
Definition: MicrosoftDemangleNodes.h:335
llvm::ms_demangle::FunctionSignatureNode::ReturnType
TypeNode * ReturnType
Definition: MicrosoftDemangleNodes.h:343
llvm::ms_demangle::SpecialIntrinsicKind
SpecialIntrinsicKind
Definition: MicrosoftDemangleNodes.h:185
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::ms_demangle::FunctionRefQualifier::None
@ None
llvm::ms_demangle::QualifiedNameNode::getUnqualifiedIdentifier
IdentifierNode * getUnqualifiedIdentifier()
Definition: MicrosoftDemangleNodes.h:533
llvm::ms_demangle::FunctionIdentifierCodeGroup::DoubleUnder
@ DoubleUnder
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::ms_demangle::ArenaAllocator::alloc
T * alloc(Args &&... ConstructorArgs)
Definition: MicrosoftDemangle.h:91
demangleFunctionRefQualifier
static FunctionRefQualifier demangleFunctionRefQualifier(StringView &MangledName)
Definition: MicrosoftDemangle.cpp:216
NodeList
Definition: MicrosoftDemangle.cpp:37
llvm::ms_demangle::LocalStaticGuardVariableNode
Definition: MicrosoftDemangleNodes.h:591
StringView::npos
static const size_t npos
Definition: StringView.h:28
llvm::ms_demangle::PointerTypeNode::Pointee
TypeNode * Pointee
Definition: MicrosoftDemangleNodes.h:472
DEMANGLE_FALLTHROUGH
#define DEMANGLE_FALLTHROUGH
Definition: DemangleConfig.h:82
llvm::ms_demangle::FC_StaticThisAdjust
@ FC_StaticThisAdjust
Definition: MicrosoftDemangleNodes.h:220
INT64_MAX
#define INT64_MAX
Definition: DataTypes.h:71
llvm::ms_demangle::RttiBaseClassDescriptorNode::VBPtrOffset
int32_t VBPtrOffset
Definition: MicrosoftDemangleNodes.h:571
llvm::ms_demangle::OF_NoReturnType
@ OF_NoReturnType
Definition: MicrosoftDemangleNodes.h:81
llvm::ms_demangle::ThunkSignatureNode::ThisAdjustor::StaticOffset
uint32_t StaticOffset
Definition: MicrosoftDemangleNodes.h:450
startsWithDigit
static bool startsWithDigit(StringView S)
Definition: MicrosoftDemangle.cpp:32
llvm::ms_demangle::LocalStaticGuardIdentifierNode
Definition: MicrosoftDemangleNodes.h:410
llvm::ms_demangle::QualifierMangleMode
QualifierMangleMode
Definition: MicrosoftDemangle.h:127
llvm::MSDF_NoCallingConvention
@ MSDF_NoCallingConvention
Definition: Demangle.h:39
llvm::ms_demangle::IdentifierNode
Definition: MicrosoftDemangleNodes.h:355
llvm::ms_demangle::RttiBaseClassDescriptorNode::NVOffset
uint32_t NVOffset
Definition: MicrosoftDemangleNodes.h:570
llvm::None
const NoneType None
Definition: None.h:23
llvm::ms_demangle::LocalStaticGuardIdentifierNode::IsThread
bool IsThread
Definition: MicrosoftDemangleNodes.h:416
llvm::ms_demangle::TagTypeNode
Definition: MicrosoftDemangleNodes.h:475
llvm::ms_demangle::SpecialIntrinsicKind::RttiBaseClassArray
@ RttiBaseClassArray
StringView.h
llvm::ms_demangle::SpecialIntrinsicKind::StringLiteralSymbol
@ StringLiteralSymbol
llvm::demangle_success
@ demangle_success
Definition: Demangle.h:28
llvm::ms_demangle::OF_NoMemberType
@ OF_NoMemberType
Definition: MicrosoftDemangleNodes.h:80
llvm::ms_demangle::SymbolNode
Definition: MicrosoftDemangleNodes.h:576
llvm::ms_demangle::LocalStaticGuardVariableNode::IsVisible
bool IsVisible
Definition: MicrosoftDemangleNodes.h:597
llvm::ms_demangle::Node::kind
NodeKind kind() const
Definition: MicrosoftDemangleNodes.h:261
llvm::ms_demangle::FunctionSignatureNode::RefQualifier
FunctionRefQualifier RefQualifier
Definition: MicrosoftDemangleNodes.h:340
llvm::ms_demangle::ConversionOperatorIdentifierNode
Definition: MicrosoftDemangleNodes.h:420
llvm::ms_demangle::StructorIdentifierNode::Class
IdentifierNode * Class
Definition: MicrosoftDemangleNodes.h:439
llvm::ms_demangle::ThunkSignatureNode
Definition: MicrosoftDemangleNodes.h:443
nodeListToNodeArray
static NodeArrayNode * nodeListToNodeArray(ArenaAllocator &Arena, NodeList *Head, size_t Count)
Definition: MicrosoftDemangle.cpp:1557
llvm::ms_demangle::VariableSymbolNode::Type
TypeNode * Type
Definition: MicrosoftDemangleNodes.h:616
llvm::ms_demangle::NamedIdentifierNode
Definition: MicrosoftDemangleNodes.h:383
llvm::ms_demangle::NodeArrayNode::Count
size_t Count
Definition: MicrosoftDemangleNodes.h:523
guessCharByteSize
static unsigned guessCharByteSize(const uint8_t *StringBytes, unsigned NumChars, uint64_t NumBytes)
Definition: MicrosoftDemangle.cpp:1208
llvm::ms_demangle::PrimitiveTypeNode
Definition: MicrosoftDemangleNodes.h:313
isPointerType
static bool isPointerType(StringView S)
Definition: MicrosoftDemangle.cpp:194
llvm::ms_demangle::FC_Public
@ FC_Public
Definition: MicrosoftDemangleNodes.h:209
Index
uint32_t Index
Definition: ELFObjHandler.cpp:84
llvm::pdb::Unknown
@ Unknown
Definition: PDBTypes.h:395
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
llvm::ms_demangle::Q_None
@ Q_None
Definition: MicrosoftDemangleNodes.h:36
llvm::ms_demangle::FC_VirtualThisAdjustEx
@ FC_VirtualThisAdjustEx
Definition: MicrosoftDemangleNodes.h:219
llvm::ms_demangle::DynamicStructorIdentifierNode::IsDestructor
bool IsDestructor
Definition: MicrosoftDemangleNodes.h:380
llvm::ms_demangle::LiteralOperatorIdentifierNode
Definition: MicrosoftDemangleNodes.h:401
llvm::MSDF_NoReturnType
@ MSDF_NoReturnType
Definition: Demangle.h:40
llvm::ms_demangle::FunctionIdentifierCodeGroup::Under
@ Under
countEmbeddedNulls
static unsigned countEmbeddedNulls(const uint8_t *StringBytes, unsigned Length)
Definition: MicrosoftDemangle.cpp:1195
llvm::ms_demangle::SpecialIntrinsicKind::Typeof
@ Typeof
llvm::MD5
Definition: MD5.h:41
Qualifiers
Qualifiers
Definition: ItaniumDemangle.h:306
llvm::CallingConv::Tail
@ Tail
Tail - This calling convention attemps to make calls as fast as possible while guaranteeing that tail...
Definition: CallingConv.h:81
llvm::NVPTX::PTXLdStInstCode::Float
@ Float
Definition: NVPTX.h:118
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::ms_demangle::NamedIdentifierNode::Name
StringView Name
Definition: MicrosoftDemangleNodes.h:388
llvm::ms_demangle::SpecialTableSymbolNode
Definition: MicrosoftDemangleNodes.h:582
llvm::ms_demangle::SpecialIntrinsicKind::Vftable
@ Vftable
llvm::ms_demangle::Q_Volatile
@ Q_Volatile
Definition: MicrosoftDemangleNodes.h:38
MicrosoftDemangleNodes.h
llvm::ms_demangle::FC_None
@ FC_None
Definition: MicrosoftDemangleNodes.h:208
llvm::ms_demangle::CustomTypeNode::Identifier
IdentifierNode * Identifier
Definition: MicrosoftDemangleNodes.h:512
llvm::ms_demangle::FunctionRefQualifier::RValueReference
@ RValueReference
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::demangle_memory_alloc_failure
@ demangle_memory_alloc_failure
Definition: Demangle.h:27
std::swap
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:840
SI
StandardInstrumentations SI(Debug, VerifyEach)
DEMANGLE_UNREACHABLE
#define DEMANGLE_UNREACHABLE
Definition: DemangleConfig.h:58
llvm::ms_demangle::PointerTypeNode
Definition: MicrosoftDemangleNodes.h:459
synthesizeNamedIdentifier
static NamedIdentifierNode * synthesizeNamedIdentifier(ArenaAllocator &Arena, StringView Name)
Definition: MicrosoftDemangle.cpp:318
llvm::ms_demangle::TemplateParameterReferenceNode::ThunkOffsets
std::array< int64_t, 3 > ThunkOffsets
Definition: MicrosoftDemangleNodes.h:548
isCustomType
static bool isCustomType(StringView S)
Definition: MicrosoftDemangle.cpp:192
Status
Definition: SIModeRegister.cpp:28
llvm::ms_demangle::RttiBaseClassDescriptorNode
Definition: MicrosoftDemangleNodes.h:564
llvm::demangle_invalid_mangled_name
@ demangle_invalid_mangled_name
Definition: Demangle.h:26
llvm::ms_demangle::FuncClass
FuncClass
Definition: MicrosoftDemangleNodes.h:207
llvm::ms_demangle::BackrefContext
Definition: MicrosoftDemangle.h:115
llvm::ms_demangle::ConversionOperatorIdentifierNode::TargetType
TypeNode * TargetType
Definition: MicrosoftDemangleNodes.h:427
llvm::ms_demangle::Q_Pointer64
@ Q_Pointer64
Definition: MicrosoftDemangleNodes.h:43
Demangle.h
llvm::ms_demangle::SpecialIntrinsicKind::DynamicAtexitDestructor
@ DynamicAtexitDestructor
llvm::ms_demangle::SpecialIntrinsicKind::RttiBaseClassDescriptor
@ RttiBaseClassDescriptor
llvm::MSDemangleFlags
MSDemangleFlags
Definition: Demangle.h:35
isRebasedHexDigit
static bool isRebasedHexDigit(char C)
Definition: MicrosoftDemangle.cpp:1026
if
if(llvm_vc STREQUAL "") set(fake_version_inc "$
Definition: CMakeLists.txt:14
llvm::ms_demangle::FC_VirtualThisAdjust
@ FC_VirtualThisAdjust
Definition: MicrosoftDemangleNodes.h:218
Number
uint32_t Number
Definition: Profile.cpp:47
parse
static llvm::Error parse(DataExtractor &Data, uint64_t BaseAddr, LineEntryCallback const &Callback)
Definition: LineTable.cpp:54
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::ms_demangle::VcallThunkIdentifierNode
Definition: MicrosoftDemangleNodes.h:364
llvm::ms_demangle::ThunkSignatureNode::ThisAdjust
ThisAdjustor ThisAdjust
Definition: MicrosoftDemangleNodes.h:456
llvm::ms_demangle::Demangler
Definition: MicrosoftDemangle.h:140
llvm::MSDF_DumpBackrefs
@ MSDF_DumpBackrefs
Definition: Demangle.h:37
llvm::pdb::Bool
@ Bool
Definition: PDBTypes.h:406
llvm::ms_demangle::FunctionRefQualifier
FunctionRefQualifier
Definition: MicrosoftDemangleNodes.h:56
llvm::object::Comma
@ Comma
Definition: COFFModuleDefinition.cpp:37
llvm::ms_demangle::RttiBaseClassDescriptorNode::VBTableOffset
uint32_t VBTableOffset
Definition: MicrosoftDemangleNodes.h:572
DemangleConfig.h
llvm::ms_demangle::OF_NoAccessSpecifier
@ OF_NoAccessSpecifier
Definition: MicrosoftDemangleNodes.h:79
llvm::GraphProgram::Name
Name
Definition: GraphWriter.h:52
llvm::ms_demangle::FunctionSignatureNode::Params
NodeArrayNode * Params
Definition: MicrosoftDemangleNodes.h:349
llvm::ms_demangle::TypeNode::Quals
Qualifiers Quals
Definition: MicrosoftDemangleNodes.h:310
llvm::ms_demangle::ArrayTypeNode::ElementType
TypeNode * ElementType
Definition: MicrosoftDemangleNodes.h:498
llvm::Error
Lightweight error class with error context and mandatory checking.
Definition: Error.h:157
llvm::ms_demangle::ThunkSignatureNode::ThisAdjustor::VBOffsetOffset
int32_t VBOffsetOffset
Definition: MicrosoftDemangleNodes.h:452
llvm::ms_demangle::ArenaAllocator
Definition: MicrosoftDemangle.h:28
llvm::ms_demangle::ThunkSignatureNode::ThisAdjustor::VtordispOffset
int32_t VtordispOffset
Definition: MicrosoftDemangleNodes.h:453
llvm::ms_demangle::SpecialIntrinsicKind::RttiTypeDescriptor
@ RttiTypeDescriptor
NodeList::Next
NodeList * Next
Definition: MicrosoftDemangle.cpp:39
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::ms_demangle::SpecialIntrinsicKind::None
@ None
llvm::object::Identifier
@ Identifier
Definition: COFFModuleDefinition.cpp:36
llvm::ms_demangle::FunctionSignatureNode::IsVariadic
bool IsVariadic
Definition: MicrosoftDemangleNodes.h:346
Lookup
static int Lookup(ArrayRef< TableEntry > Table, unsigned Opcode)
Definition: X86FloatingPoint.cpp:599
llvm::microsoftDemangle
char * microsoftDemangle(const char *mangled_name, size_t *n_read, char *buf, size_t *n_buf, int *status, MSDemangleFlags Flags=MSDF_None)
Demangles the Microsoft symbol pointed at by mangled_name and returns it.
Definition: MicrosoftDemangle.cpp:2339
llvm::ms_demangle::PointerTypeNode::ClassParent
QualifiedNameNode * ClassParent
Definition: MicrosoftDemangleNodes.h:468
llvm::tgtok::Class
@ Class
Definition: TGLexer.h:50
llvm::ms_demangle::SpecialIntrinsicKind::LocalStaticGuard
@ LocalStaticGuard
llvm::ARMBuildAttrs::Symbol
@ Symbol
Definition: ARMBuildAttributes.h:79
llvm::ms_demangle::FC_Far
@ FC_Far
Definition: MicrosoftDemangleNodes.h:215
isFunctionType
static bool isFunctionType(StringView S)
Definition: MicrosoftDemangle.cpp:211
startsWithLocalScopePattern
static bool startsWithLocalScopePattern(StringView S)
Definition: MicrosoftDemangle.cpp:142
llvm::ms_demangle::FC_Protected
@ FC_Protected
Definition: MicrosoftDemangleNodes.h:210
llvm::ms_demangle::PointerAffinity::Reference
@ Reference
llvm::ms_demangle::StructorIdentifierNode
Definition: MicrosoftDemangleNodes.h:430
llvm::ms_demangle::FC_Virtual
@ FC_Virtual
Definition: MicrosoftDemangleNodes.h:214
llvm::ms_demangle::TemplateParameterReferenceNode::ThunkOffsetCount
int ThunkOffsetCount
Definition: MicrosoftDemangleNodes.h:547
N
#define N
llvm::codeview::Basic
@ Basic
Definition: CodeView.h:149
llvm::ms_demangle::SymbolNode::output
void output(OutputStream &OS, OutputFlags Flags) const override
Definition: MicrosoftDemangleNodes.cpp:580
llvm::ms_demangle::FC_ExternC
@ FC_ExternC
Definition: MicrosoftDemangleNodes.h:216
countTrailingNullBytes
static unsigned countTrailingNullBytes(const uint8_t *StringBytes, int Length)
Definition: MicrosoftDemangle.cpp:1184
llvm::ms_demangle::NodeArrayNode
Definition: MicrosoftDemangleNodes.h:515
NodeList::N
Node * N
Definition: MicrosoftDemangle.cpp:38
llvm::ms_demangle::NBB_Simple
@ NBB_Simple
Definition: MicrosoftDemangle.h:132
llvm::ms_demangle::SymbolNode::Name
QualifiedNameNode * Name
Definition: MicrosoftDemangleNodes.h:579
llvm::ms_demangle::VariableSymbolNode
Definition: MicrosoftDemangleNodes.h:610
llvm::ms_demangle::NBB_Template
@ NBB_Template
Definition: MicrosoftDemangle.h:131
MicrosoftDemangle.h
llvm::ms_demangle::TypeNode
Definition: MicrosoftDemangleNodes.h:299
outputHex
static void outputHex(OutputStream &OS, unsigned C)
Definition: MicrosoftDemangle.cpp:1110
llvm::ms_demangle::FunctionSignatureNode::IsNoexcept
bool IsNoexcept
Definition: MicrosoftDemangleNodes.h:352
llvm::ms_demangle::RttiBaseClassDescriptorNode::Flags
uint32_t Flags
Definition: MicrosoftDemangleNodes.h:573
llvm::ms_demangle::OutputFlags
OutputFlags
Definition: MicrosoftDemangleNodes.h:75
llvm::AMDGPU::VGPRIndexMode::Id
Id
Definition: SIDefines.h:221
synthesizeVariable
static VariableSymbolNode * synthesizeVariable(ArenaAllocator &Arena, TypeNode *Type, StringView VariableName)
Definition: MicrosoftDemangle.cpp:341
llvm::ms_demangle::SpecialIntrinsicKind::VcallThunk
@ VcallThunk
llvm::ms_demangle::EncodedStringLiteralNode
Definition: MicrosoftDemangleNodes.h:600
initializeOutputStream
bool initializeOutputStream(char *Buf, size_t *N, OutputStream &S, size_t InitSize)
Definition: Utility.h:174
llvm::MSDF_NoMemberType
@ MSDF_NoMemberType
Definition: Demangle.h:41
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::ms_demangle::LocalStaticGuardIdentifierNode::ScopeIndex
uint32_t ScopeIndex
Definition: MicrosoftDemangleNodes.h:417
llvm::ms_demangle::PointerAffinity::RValueReference
@ RValueReference
llvm::ms_demangle::FunctionSymbolNode
Definition: MicrosoftDemangleNodes.h:619