Coverage Report

Created: 2019-07-24 05:18

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