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