Coverage Report

Created: 2026-07-27 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/glog/src/demangle.cc
Line
Count
Source
1
// Copyright (c) 2024, Google Inc.
2
// All rights reserved.
3
//
4
// Redistribution and use in source and binary forms, with or without
5
// modification, are permitted provided that the following conditions are
6
// met:
7
//
8
//     * Redistributions of source code must retain the above copyright
9
// notice, this list of conditions and the following disclaimer.
10
//     * Redistributions in binary form must reproduce the above
11
// copyright notice, this list of conditions and the following disclaimer
12
// in the documentation and/or other materials provided with the
13
// distribution.
14
//     * Neither the name of Google Inc. nor the names of its
15
// contributors may be used to endorse or promote products derived from
16
// this software without specific prior written permission.
17
//
18
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
//
30
// Author: Satoru Takabayashi
31
//
32
// For reference check out:
33
// http://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling
34
//
35
// Note that we only have partial C++0x support yet.
36
37
#include "demangle.h"
38
39
#include <algorithm>
40
#include <cstdlib>
41
#include <limits>
42
43
#include "utilities.h"
44
45
#if defined(HAVE___CXA_DEMANGLE)
46
#  include <cxxabi.h>
47
#endif
48
49
#if defined(GLOG_OS_WINDOWS)
50
#  include <dbghelp.h>
51
#endif
52
53
namespace google {
54
inline namespace glog_internal_namespace_ {
55
56
#if !defined(GLOG_OS_WINDOWS) && !defined(HAVE___CXA_DEMANGLE)
57
namespace {
58
struct AbbrevPair {
59
  const char* const abbrev;
60
  const char* const real_name;
61
};
62
63
// List of operators from Itanium C++ ABI.
64
const AbbrevPair kOperatorList[] = {
65
    {"nw", "new"},    {"na", "new[]"},    {"dl", "delete"}, {"da", "delete[]"},
66
    {"ps", "+"},      {"ng", "-"},        {"ad", "&"},      {"de", "*"},
67
    {"co", "~"},      {"pl", "+"},        {"mi", "-"},      {"ml", "*"},
68
    {"dv", "/"},      {"rm", "%"},        {"an", "&"},      {"or", "|"},
69
    {"eo", "^"},      {"aS", "="},        {"pL", "+="},     {"mI", "-="},
70
    {"mL", "*="},     {"dV", "/="},       {"rM", "%="},     {"aN", "&="},
71
    {"oR", "|="},     {"eO", "^="},       {"ls", "<<"},     {"rs", ">>"},
72
    {"lS", "<<="},    {"rS", ">>="},      {"eq", "=="},     {"ne", "!="},
73
    {"lt", "<"},      {"gt", ">"},        {"le", "<="},     {"ge", ">="},
74
    {"nt", "!"},      {"aa", "&&"},       {"oo", "||"},     {"pp", "++"},
75
    {"mm", "--"},     {"cm", ","},        {"pm", "->*"},    {"pt", "->"},
76
    {"cl", "()"},     {"ix", "[]"},       {"qu", "?"},      {"st", "sizeof"},
77
    {"sz", "sizeof"}, {nullptr, nullptr},
78
};
79
80
// List of builtin types from Itanium C++ ABI.
81
const AbbrevPair kBuiltinTypeList[] = {
82
    {"v", "void"},        {"w", "wchar_t"},
83
    {"b", "bool"},        {"c", "char"},
84
    {"a", "signed char"}, {"h", "unsigned char"},
85
    {"s", "short"},       {"t", "unsigned short"},
86
    {"i", "int"},         {"j", "unsigned int"},
87
    {"l", "long"},        {"m", "unsigned long"},
88
    {"x", "long long"},   {"y", "unsigned long long"},
89
    {"n", "__int128"},    {"o", "unsigned __int128"},
90
    {"f", "float"},       {"d", "double"},
91
    {"e", "long double"}, {"g", "__float128"},
92
    {"z", "ellipsis"},    {"Dn", "decltype(nullptr)"},
93
    {nullptr, nullptr}};
94
95
// List of substitutions Itanium C++ ABI.
96
const AbbrevPair kSubstitutionList[] = {
97
    {"St", ""},
98
    {"Sa", "allocator"},
99
    {"Sb", "basic_string"},
100
    // std::basic_string<char, std::char_traits<char>,std::allocator<char> >
101
    {"Ss", "string"},
102
    // std::basic_istream<char, std::char_traits<char> >
103
    {"Si", "istream"},
104
    // std::basic_ostream<char, std::char_traits<char> >
105
    {"So", "ostream"},
106
    // std::basic_iostream<char, std::char_traits<char> >
107
    {"Sd", "iostream"},
108
    {nullptr, nullptr}};
109
110
// State needed for demangling.
111
struct State {
112
  const char* mangled_cur;   // Cursor of mangled name.
113
  char* out_cur;             // Cursor of output string.
114
  const char* out_begin;     // Beginning of output string.
115
  const char* out_end;       // End of output string.
116
  const char* prev_name;     // For constructors/destructors.
117
  ssize_t prev_name_length;  // For constructors/destructors.
118
  short nest_level;          // For nested names.
119
  bool append;               // Append flag.
120
  bool overflowed;           // True if output gets overflowed.
121
  uint32 local_level;
122
  uint32 expr_level;
123
  uint32 arg_level;
124
};
125
126
// We don't use strlen() in libc since it's not guaranteed to be async
127
// signal safe.
128
3.52M
size_t StrLen(const char* str) {
129
3.52M
  size_t len = 0;
130
43.6M
  while (*str != '\0') {
131
40.1M
    ++str;
132
40.1M
    ++len;
133
40.1M
  }
134
3.52M
  return len;
135
3.52M
}
136
137
// Returns true if "str" has at least "n" characters remaining.
138
10.8M
bool AtLeastNumCharsRemaining(const char* str, ssize_t n) {
139
31.3M
  for (ssize_t i = 0; i < n; ++i) {
140
21.0M
    if (str[i] == '\0') {
141
530k
      return false;
142
530k
    }
143
21.0M
  }
144
10.2M
  return true;
145
10.8M
}
146
147
// Returns true if "str" has "prefix" as a prefix.
148
908
bool StrPrefix(const char* str, const char* prefix) {
149
908
  size_t i = 0;
150
7.61k
  while (str[i] != '\0' && prefix[i] != '\0' && str[i] == prefix[i]) {
151
6.70k
    ++i;
152
6.70k
  }
153
908
  return prefix[i] == '\0';  // Consumed everything in "prefix".
154
908
}
155
156
4.74k
void InitState(State* state, const char* mangled, char* out, size_t out_size) {
157
4.74k
  state->mangled_cur = mangled;
158
4.74k
  state->out_cur = out;
159
4.74k
  state->out_begin = out;
160
4.74k
  state->out_end = out + out_size;
161
4.74k
  state->prev_name = nullptr;
162
4.74k
  state->prev_name_length = -1;
163
4.74k
  state->nest_level = -1;
164
4.74k
  state->append = true;
165
4.74k
  state->overflowed = false;
166
4.74k
  state->local_level = 0;
167
4.74k
  state->expr_level = 0;
168
4.74k
  state->arg_level = 0;
169
4.74k
}
170
171
// Returns true and advances "mangled_cur" if we find "one_char_token"
172
// at "mangled_cur" position.  It is assumed that "one_char_token" does
173
// not contain '\0'.
174
144M
bool ParseOneCharToken(State* state, const char one_char_token) {
175
144M
  if (state->mangled_cur[0] == one_char_token) {
176
3.51M
    ++state->mangled_cur;
177
3.51M
    return true;
178
3.51M
  }
179
141M
  return false;
180
144M
}
181
182
// Returns true and advances "mangled_cur" if we find "two_char_token"
183
// at "mangled_cur" position.  It is assumed that "two_char_token" does
184
// not contain '\0'.
185
48.2M
bool ParseTwoCharToken(State* state, const char* two_char_token) {
186
48.2M
  if (state->mangled_cur[0] == two_char_token[0] &&
187
3.41M
      state->mangled_cur[1] == two_char_token[1]) {
188
3.34M
    state->mangled_cur += 2;
189
3.34M
    return true;
190
3.34M
  }
191
44.9M
  return false;
192
48.2M
}
193
194
// Returns true and advances "mangled_cur" if we find any character in
195
// "char_class" at "mangled_cur" position.
196
3.48M
bool ParseCharClass(State* state, const char* char_class) {
197
3.48M
  const char* p = char_class;
198
20.7M
  for (; *p != '\0'; ++p) {
199
17.2M
    if (state->mangled_cur[0] == *p) {
200
27.2k
      ++state->mangled_cur;
201
27.2k
      return true;
202
27.2k
    }
203
17.2M
  }
204
3.45M
  return false;
205
3.48M
}
206
207
// This function is used for handling an optional non-terminal.
208
3.32M
bool Optional(bool) { return true; }
209
210
// This function is used for handling <non-terminal>+ syntax.
211
using ParseFunc = bool (*)(State*);
212
227k
bool OneOrMore(ParseFunc parse_func, State* state) {
213
227k
  if (parse_func(state)) {
214
25.9k
    while (parse_func(state)) {
215
4.30k
    }
216
21.6k
    return true;
217
21.6k
  }
218
205k
  return false;
219
227k
}
220
221
// This function is used for handling <non-terminal>* syntax. The function
222
// always returns true and must be followed by a termination token or a
223
// terminating sequence not handled by parse_func (e.g.
224
// ParseOneCharToken(state, 'E')).
225
3.04k
bool ZeroOrMore(ParseFunc parse_func, State* state) {
226
4.08k
  while (parse_func(state)) {
227
1.04k
  }
228
3.04k
  return true;
229
3.04k
}
230
231
// Append "str" at "out_cur".  If there is an overflow, "overflowed"
232
// is set to true for later use.  The output string is ensured to
233
// always terminate with '\0' as long as there is no overflow.
234
3.35M
void Append(State* state, const char* const str, ssize_t length) {
235
3.35M
  if (state->out_cur == nullptr) {
236
0
    state->overflowed = true;
237
0
    return;
238
0
  }
239
9.06M
  for (ssize_t i = 0; i < length; ++i) {
240
8.44M
    if (state->out_cur + 1 < state->out_end) {  // +1 for '\0'
241
5.70M
      *state->out_cur = str[i];
242
5.70M
      ++state->out_cur;
243
5.70M
    } else {
244
2.74M
      state->overflowed = true;
245
2.74M
      break;
246
2.74M
    }
247
8.44M
  }
248
3.35M
  if (!state->overflowed) {
249
619k
    *state->out_cur = '\0';  // Terminate it with '\0'
250
619k
  }
251
3.35M
}
252
253
// We don't use equivalents in libc to avoid locale issues.
254
10.1M
bool IsLower(char c) { return c >= 'a' && c <= 'z'; }
255
256
6.68M
bool IsAlpha(char c) {
257
6.68M
  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
258
6.68M
}
259
260
10.4M
bool IsDigit(char c) { return c >= '0' && c <= '9'; }
261
262
// Returns true if "str" is a function clone suffix.  These suffixes are used
263
// by GCC 4.5.x and later versions to indicate functions which have been
264
// cloned during optimization.  We treat any sequence (.<alpha>+.<digit>+)+ as
265
// a function clone suffix.
266
1.45k
bool IsFunctionCloneSuffix(const char* str) {
267
1.45k
  size_t i = 0;
268
2.13k
  while (str[i] != '\0') {
269
    // Consume a single .<alpha>+.<digit>+ sequence.
270
2.11k
    if (str[i] != '.' || !IsAlpha(str[i + 1])) {
271
1.37k
      return false;
272
1.37k
    }
273
745
    i += 2;
274
1.45k
    while (IsAlpha(str[i])) {
275
709
      ++i;
276
709
    }
277
745
    if (str[i] != '.' || !IsDigit(str[i + 1])) {
278
67
      return false;
279
67
    }
280
678
    i += 2;
281
989
    while (IsDigit(str[i])) {
282
311
      ++i;
283
311
    }
284
678
  }
285
20
  return true;  // Consumed everything in "str".
286
1.45k
}
287
288
// Append "str" with some tweaks, iff "append" state is true.
289
// Returns true so that it can be placed in "if" conditions.
290
void MaybeAppendWithLength(State* state, const char* const str,
291
3.53M
                           ssize_t length) {
292
3.53M
  if (state->append && length > 0) {
293
    // Append a space if the output buffer ends with '<' and "str"
294
    // starts with '<' to avoid <<<.
295
3.35M
    if (str[0] == '<' && state->out_begin < state->out_cur &&
296
1.57k
        state->out_cur[-1] == '<') {
297
388
      Append(state, " ", 1);
298
388
    }
299
    // Remember the last identifier name for ctors/dtors.
300
3.35M
    if (IsAlpha(str[0]) || str[0] == '_') {
301
3.31M
      state->prev_name = state->out_cur;
302
3.31M
      state->prev_name_length = length;
303
3.31M
    }
304
3.35M
    Append(state, str, length);
305
3.35M
  }
306
3.53M
}
307
308
// A convenient wrapper around MaybeAppendWithLength().
309
3.43M
bool MaybeAppend(State* state, const char* const str) {
310
3.43M
  if (state->append) {
311
3.35M
    size_t length = StrLen(str);
312
3.35M
    MaybeAppendWithLength(state, str, static_cast<ssize_t>(length));
313
3.35M
  }
314
3.43M
  return true;
315
3.43M
}
316
317
// This function is used for handling nested names.
318
6.44M
bool EnterNestedName(State* state) {
319
6.44M
  state->nest_level = 0;
320
6.44M
  return true;
321
6.44M
}
322
323
// This function is used for handling nested names.
324
3.14M
bool LeaveNestedName(State* state, short prev_value) {
325
3.14M
  state->nest_level = prev_value;
326
3.14M
  return true;
327
3.14M
}
328
329
// Disable the append mode not to print function parameters, etc.
330
293k
bool DisableAppend(State* state) {
331
293k
  state->append = false;
332
293k
  return true;
333
293k
}
334
335
// Restore the append mode to the previous state.
336
13.9k
bool RestoreAppend(State* state, bool prev_value) {
337
13.9k
  state->append = prev_value;
338
13.9k
  return true;
339
13.9k
}
340
341
// Increase the nest level for nested names.
342
20.0k
void MaybeIncreaseNestLevel(State* state) {
343
20.0k
  if (state->nest_level > -1) {
344
20.0k
    ++state->nest_level;
345
20.0k
  }
346
20.0k
}
347
348
// Appends :: for nested names if necessary.
349
3.16M
void MaybeAppendSeparator(State* state) {
350
3.16M
  if (state->nest_level >= 1) {
351
20.4k
    MaybeAppend(state, "::");
352
20.4k
  }
353
3.16M
}
354
355
// Cancel the last separator if necessary.
356
3.14M
void MaybeCancelLastSeparator(State* state) {
357
3.14M
  if (state->nest_level >= 1 && state->append &&
358
2.67k
      state->out_begin <= state->out_cur - 2) {
359
2.67k
    state->out_cur -= 2;
360
2.67k
    *state->out_cur = '\0';
361
2.67k
  }
362
3.14M
}
363
364
// Returns true if the identifier of the given length pointed to by
365
// "mangled_cur" is anonymous namespace.
366
172k
bool IdentifierIsAnonymousNamespace(State* state, ssize_t length) {
367
172k
  const char anon_prefix[] = "_GLOBAL__N_";
368
172k
  return (length > static_cast<ssize_t>(sizeof(anon_prefix)) -
369
172k
                       1 &&  // Should be longer.
370
908
          StrPrefix(state->mangled_cur, anon_prefix));
371
172k
}
372
373
// Forward declarations of our parsing functions.
374
bool ParseMangledName(State* state);
375
bool ParseEncoding(State* state);
376
bool ParseName(State* state);
377
bool ParseUnscopedName(State* state);
378
bool ParseUnscopedTemplateName(State* state);
379
bool ParseNestedName(State* state);
380
bool ParsePrefix(State* state);
381
bool ParseUnqualifiedName(State* state);
382
bool ParseSourceName(State* state);
383
bool ParseLocalSourceName(State* state);
384
bool ParseNumber(State* state, int* number_out);
385
bool ParseFloatNumber(State* state);
386
bool ParseSeqId(State* state);
387
bool ParseIdentifier(State* state, ssize_t length);
388
bool ParseAbiTags(State* state);
389
bool ParseAbiTag(State* state);
390
bool ParseOperatorName(State* state);
391
bool ParseSpecialName(State* state);
392
bool ParseCallOffset(State* state);
393
bool ParseNVOffset(State* state);
394
bool ParseVOffset(State* state);
395
bool ParseCtorDtorName(State* state);
396
bool ParseType(State* state);
397
bool ParseCVQualifiers(State* state);
398
bool ParseBuiltinType(State* state);
399
bool ParseFunctionType(State* state);
400
bool ParseBareFunctionType(State* state);
401
bool ParseClassEnumType(State* state);
402
bool ParseArrayType(State* state);
403
bool ParsePointerToMemberType(State* state);
404
bool ParseTemplateParam(State* state);
405
bool ParseTemplateTemplateParam(State* state);
406
bool ParseTemplateArgs(State* state);
407
bool ParseTemplateArg(State* state);
408
bool ParseExpression(State* state);
409
bool ParseExprPrimary(State* state);
410
bool ParseLocalName(State* state);
411
bool ParseDiscriminator(State* state);
412
bool ParseSubstitution(State* state);
413
414
// Implementation note: the following code is a straightforward
415
// translation of the Itanium C++ ABI defined in BNF with a couple of
416
// exceptions.
417
//
418
// - Support GNU extensions not defined in the Itanium C++ ABI
419
// - <prefix> and <template-prefix> are combined to avoid infinite loop
420
// - Reorder patterns to shorten the code
421
// - Reorder patterns to give greedier functions precedence
422
//   We'll mark "Less greedy than" for these cases in the code
423
//
424
// Each parsing function changes the state and returns true on
425
// success.  Otherwise, don't change the state and returns false.  To
426
// ensure that the state isn't changed in the latter case, we save the
427
// original state before we call more than one parsing functions
428
// consecutively with &&, and restore the state if unsuccessful.  See
429
// ParseEncoding() as an example of this convention.  We follow the
430
// convention throughout the code.
431
//
432
// Originally we tried to do demangling without following the full ABI
433
// syntax but it turned out we needed to follow the full syntax to
434
// parse complicated cases like nested template arguments.  Note that
435
// implementing a full-fledged demangler isn't trivial (libiberty's
436
// cp-demangle.c has +4300 lines).
437
//
438
// Note that (foo) in <(foo) ...> is a modifier to be ignored.
439
//
440
// Reference:
441
// - Itanium C++ ABI
442
//   <http://www.codesourcery.com/cxx-abi/abi.html#mangling>
443
444
// <mangled-name> ::= _Z <encoding>
445
9.14k
bool ParseMangledName(State* state) {
446
9.14k
  return ParseTwoCharToken(state, "_Z") && ParseEncoding(state);
447
9.14k
}
448
449
// <encoding> ::= <(function) name> <bare-function-type>
450
//            ::= <(data) name>
451
//            ::= <special-name>
452
149k
bool ParseEncoding(State* state) {
453
149k
  State copy = *state;
454
149k
  if (ParseName(state) && ParseBareFunctionType(state)) {
455
4.66k
    return true;
456
4.66k
  }
457
145k
  *state = copy;
458
459
145k
  if (ParseName(state) || ParseSpecialName(state)) {
460
39.8k
    return true;
461
39.8k
  }
462
105k
  return false;
463
145k
}
464
465
// <name> ::= <nested-name>
466
//        ::= <unscoped-template-name> <template-args>
467
//        ::= <unscoped-name>
468
//        ::= <local-name>
469
3.73M
bool ParseName(State* state) {
470
3.73M
  if (ParseNestedName(state) || ParseLocalName(state)) {
471
5.84k
    return true;
472
5.84k
  }
473
474
3.72M
  State copy = *state;
475
3.72M
  if (ParseUnscopedTemplateName(state) && ParseTemplateArgs(state)) {
476
2.43k
    return true;
477
2.43k
  }
478
3.72M
  *state = copy;
479
480
  // Less greedy than <unscoped-template-name> <template-args>.
481
3.72M
  if (ParseUnscopedName(state)) {
482
78.1k
    return true;
483
78.1k
  }
484
3.64M
  return false;
485
3.72M
}
486
487
// <unscoped-name> ::= <unqualified-name>
488
//                 ::= St <unqualified-name>
489
10.6M
bool ParseUnscopedName(State* state) {
490
10.6M
  if (ParseUnqualifiedName(state)) {
491
163k
    return true;
492
163k
  }
493
494
10.4M
  State copy = *state;
495
10.4M
  if (ParseTwoCharToken(state, "St") && MaybeAppend(state, "std::") &&
496
11.4k
      ParseUnqualifiedName(state)) {
497
6.61k
    return true;
498
6.61k
  }
499
10.4M
  *state = copy;
500
10.4M
  return false;
501
10.4M
}
502
503
// <unscoped-template-name> ::= <unscoped-name>
504
//                          ::= <substitution>
505
3.72M
bool ParseUnscopedTemplateName(State* state) {
506
3.72M
  return ParseUnscopedName(state) || ParseSubstitution(state);
507
3.72M
}
508
509
// <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
510
//               ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
511
3.73M
bool ParseNestedName(State* state) {
512
3.73M
  State copy = *state;
513
3.73M
  if (ParseOneCharToken(state, 'N') && EnterNestedName(state) &&
514
3.14M
      Optional(ParseCVQualifiers(state)) && ParsePrefix(state) &&
515
3.14M
      LeaveNestedName(state, copy.nest_level) &&
516
3.14M
      ParseOneCharToken(state, 'E')) {
517
1.18k
    return true;
518
1.18k
  }
519
3.73M
  *state = copy;
520
3.73M
  return false;
521
3.73M
}
522
523
// This part is tricky.  If we literally translate them to code, we'll
524
// end up infinite loop.  Hence we merge them to avoid the case.
525
//
526
// <prefix> ::= <prefix> <unqualified-name>
527
//          ::= <template-prefix> <template-args>
528
//          ::= <template-param>
529
//          ::= <substitution>
530
//          ::= # empty
531
// <template-prefix> ::= <prefix> <(template) unqualified-name>
532
//                   ::= <template-param>
533
//                   ::= <substitution>
534
3.14M
bool ParsePrefix(State* state) {
535
3.14M
  bool has_something = false;
536
3.16M
  while (true) {
537
3.16M
    MaybeAppendSeparator(state);
538
3.16M
    if (ParseTemplateParam(state) || ParseSubstitution(state) ||
539
3.15M
        ParseUnscopedName(state)) {
540
20.0k
      has_something = true;
541
20.0k
      MaybeIncreaseNestLevel(state);
542
20.0k
      continue;
543
20.0k
    }
544
3.14M
    MaybeCancelLastSeparator(state);
545
3.14M
    if (has_something && ParseTemplateArgs(state)) {
546
428
      return ParsePrefix(state);
547
3.14M
    } else {
548
3.14M
      break;
549
3.14M
    }
550
3.14M
  }
551
3.14M
  return true;
552
3.14M
}
553
554
// <unqualified-name> ::= <operator-name>
555
//                    ::= <ctor-dtor-name>
556
//                    ::= <source-name> [<abi-tags>]
557
//                    ::= <local-source-name> [<abi-tags>]
558
10.6M
bool ParseUnqualifiedName(State* state) {
559
10.6M
  return (ParseOperatorName(state) || ParseCtorDtorName(state) ||
560
10.6M
          (ParseSourceName(state) && Optional(ParseAbiTags(state))) ||
561
10.4M
          (ParseLocalSourceName(state) && Optional(ParseAbiTags(state))));
562
10.6M
}
563
564
// <source-name> ::= <positive length number> <identifier>
565
10.6M
bool ParseSourceName(State* state) {
566
10.6M
  State copy = *state;
567
10.6M
  int length = -1;
568
10.6M
  if (ParseNumber(state, &length) && ParseIdentifier(state, length)) {
569
171k
    return true;
570
171k
  }
571
10.4M
  *state = copy;
572
10.4M
  return false;
573
10.6M
}
574
575
// <local-source-name> ::= L <source-name> [<discriminator>]
576
//
577
// References:
578
//   http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
579
//   http://gcc.gnu.org/viewcvs?view=rev&revision=124467
580
10.4M
bool ParseLocalSourceName(State* state) {
581
10.4M
  State copy = *state;
582
10.4M
  if (ParseOneCharToken(state, 'L') && ParseSourceName(state) &&
583
6.56k
      Optional(ParseDiscriminator(state))) {
584
6.56k
    return true;
585
6.56k
  }
586
10.4M
  *state = copy;
587
10.4M
  return false;
588
10.4M
}
589
590
// <number> ::= [n] <non-negative decimal integer>
591
// If "number_out" is non-null, then *number_out is set to the value of the
592
// parsed number on success.
593
10.6M
bool ParseNumber(State* state, int* number_out) {
594
10.6M
  int sign = 1;
595
10.6M
  if (ParseOneCharToken(state, 'n')) {
596
4.33k
    sign = -1;
597
4.33k
  }
598
10.6M
  const char* p = state->mangled_cur;
599
10.6M
  int number = 0;
600
10.6M
  constexpr int int_max_by_10 = std::numeric_limits<int>::max() / 10;
601
10.9M
  for (; *p != '\0'; ++p) {
602
10.4M
    if (IsDigit(*p)) {
603
      // Prevent signed integer overflow when multiplying
604
245k
      if (number > int_max_by_10) {
605
2.52k
        return false;
606
2.52k
      }
607
608
242k
      const int digit = *p - '0';
609
242k
      const int shifted = number * 10;
610
611
      // Prevent signed integer overflow when summing
612
242k
      if (digit > std::numeric_limits<int>::max() - shifted) {
613
2.43k
        return false;
614
2.43k
      }
615
616
240k
      number = shifted + digit;
617
10.1M
    } else {
618
10.1M
      break;
619
10.1M
    }
620
10.4M
  }
621
10.6M
  if (p != state->mangled_cur) {  // Conversion succeeded.
622
183k
    state->mangled_cur = p;
623
183k
    if (number_out != nullptr) {
624
173k
      *number_out = number * sign;
625
173k
    }
626
183k
    return true;
627
183k
  }
628
10.4M
  return false;
629
10.6M
}
630
631
// Floating-point literals are encoded using a fixed-length lowercase
632
// hexadecimal string.
633
2.13k
bool ParseFloatNumber(State* state) {
634
2.13k
  const char* p = state->mangled_cur;
635
8.01k
  for (; *p != '\0'; ++p) {
636
6.66k
    if (!IsDigit(*p) && !(*p >= 'a' && *p <= 'f')) {
637
784
      break;
638
784
    }
639
6.66k
  }
640
2.13k
  if (p != state->mangled_cur) {  // Conversion succeeded.
641
1.52k
    state->mangled_cur = p;
642
1.52k
    return true;
643
1.52k
  }
644
608
  return false;
645
2.13k
}
646
647
// The <seq-id> is a sequence number in base 36,
648
// using digits and upper case letters
649
15.1k
bool ParseSeqId(State* state) {
650
15.1k
  const char* p = state->mangled_cur;
651
16.2k
  for (; *p != '\0'; ++p) {
652
13.9k
    if (!IsDigit(*p) && !(*p >= 'A' && *p <= 'Z')) {
653
12.8k
      break;
654
12.8k
    }
655
13.9k
  }
656
15.1k
  if (p != state->mangled_cur) {  // Conversion succeeded.
657
996
    state->mangled_cur = p;
658
996
    return true;
659
996
  }
660
14.1k
  return false;
661
15.1k
}
662
663
// <identifier> ::= <unqualified source code identifier> (of given length)
664
173k
bool ParseIdentifier(State* state, ssize_t length) {
665
173k
  if (length == -1 || !AtLeastNumCharsRemaining(state->mangled_cur, length)) {
666
1.11k
    return false;
667
1.11k
  }
668
172k
  if (IdentifierIsAnonymousNamespace(state, length)) {
669
589
    MaybeAppend(state, "(anonymous namespace)");
670
171k
  } else {
671
171k
    MaybeAppendWithLength(state, state->mangled_cur, length);
672
171k
  }
673
172k
  if (length < 0 ||
674
171k
      static_cast<std::size_t>(length) > StrLen(state->mangled_cur)) {
675
639
    return false;
676
639
  }
677
171k
  state->mangled_cur += length;
678
171k
  return true;
679
172k
}
680
681
// <abi-tags> ::= <abi-tag> [<abi-tags>]
682
164k
bool ParseAbiTags(State* state) {
683
164k
  State copy = *state;
684
164k
  DisableAppend(state);
685
164k
  if (OneOrMore(ParseAbiTag, state)) {
686
4.71k
    RestoreAppend(state, copy.append);
687
4.71k
    return true;
688
4.71k
  }
689
159k
  *state = copy;
690
159k
  return false;
691
164k
}
692
693
// <abi-tag> ::= B <source-name>
694
170k
bool ParseAbiTag(State* state) {
695
170k
  return ParseOneCharToken(state, 'B') && ParseSourceName(state);
696
170k
}
697
698
// <operator-name> ::= nw, and other two letters cases
699
//                 ::= cv <type>  # (cast)
700
//                 ::= v  <digit> <source-name> # vendor extended operator
701
10.6M
bool ParseOperatorName(State* state) {
702
10.6M
  if (!AtLeastNumCharsRemaining(state->mangled_cur, 2)) {
703
529k
    return false;
704
529k
  }
705
  // First check with "cv" (cast) case.
706
10.1M
  State copy = *state;
707
10.1M
  if (ParseTwoCharToken(state, "cv") && MaybeAppend(state, "operator ") &&
708
3.30M
      EnterNestedName(state) && ParseType(state) &&
709
2.25k
      LeaveNestedName(state, copy.nest_level)) {
710
2.25k
    return true;
711
2.25k
  }
712
10.1M
  *state = copy;
713
714
  // Then vendor extended operators.
715
10.1M
  if (ParseOneCharToken(state, 'v') && ParseCharClass(state, "0123456789") &&
716
493
      ParseSourceName(state)) {
717
238
    return true;
718
238
  }
719
10.1M
  *state = copy;
720
721
  // Other operator names should start with a lower alphabet followed
722
  // by a lower/upper alphabet.
723
10.1M
  if (!(IsLower(state->mangled_cur[0]) && IsAlpha(state->mangled_cur[1]))) {
724
6.79M
    return false;
725
6.79M
  }
726
  // We may want to perform a binary search if we really need speed.
727
3.31M
  const AbbrevPair* p;
728
165M
  for (p = kOperatorList; p->abbrev != nullptr; ++p) {
729
162M
    if (state->mangled_cur[0] == p->abbrev[0] &&
730
9.94M
        state->mangled_cur[1] == p->abbrev[1]) {
731
7.25k
      MaybeAppend(state, "operator");
732
7.25k
      if (IsLower(*p->real_name)) {  // new, delete, etc.
733
3.06k
        MaybeAppend(state, " ");
734
3.06k
      }
735
7.25k
      MaybeAppend(state, p->real_name);
736
7.25k
      state->mangled_cur += 2;
737
7.25k
      return true;
738
7.25k
    }
739
162M
  }
740
3.30M
  return false;
741
3.31M
}
742
743
// <special-name> ::= TV <type>
744
//                ::= TT <type>
745
//                ::= TI <type>
746
//                ::= TS <type>
747
//                ::= Tc <call-offset> <call-offset> <(base) encoding>
748
//                ::= GV <(object) name>
749
//                ::= T <call-offset> <(base) encoding>
750
// G++ extensions:
751
//                ::= TC <type> <(offset) number> _ <(base) type>
752
//                ::= TF <type>
753
//                ::= TJ <type>
754
//                ::= GR <name>
755
//                ::= GA <encoding>
756
//                ::= Th <call-offset> <(base) encoding>
757
//                ::= Tv <call-offset> <(base) encoding>
758
//
759
// Note: we don't care much about them since they don't appear in
760
// stack traces.  The are special data.
761
111k
bool ParseSpecialName(State* state) {
762
111k
  State copy = *state;
763
111k
  if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "VTIS") &&
764
640
      ParseType(state)) {
765
256
    return true;
766
256
  }
767
111k
  *state = copy;
768
769
111k
  if (ParseTwoCharToken(state, "Tc") && ParseCallOffset(state) &&
770
678
      ParseCallOffset(state) && ParseEncoding(state)) {
771
226
    return true;
772
226
  }
773
110k
  *state = copy;
774
775
110k
  if (ParseTwoCharToken(state, "GV") && ParseName(state)) {
776
2.24k
    return true;
777
2.24k
  }
778
108k
  *state = copy;
779
780
108k
  if (ParseOneCharToken(state, 'T') && ParseCallOffset(state) &&
781
744
      ParseEncoding(state)) {
782
227
    return true;
783
227
  }
784
108k
  *state = copy;
785
786
  // G++ extensions
787
108k
  if (ParseTwoCharToken(state, "TC") && ParseType(state) &&
788
2.23k
      ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') &&
789
463
      DisableAppend(state) && ParseType(state)) {
790
226
    RestoreAppend(state, copy.append);
791
226
    return true;
792
226
  }
793
108k
  *state = copy;
794
795
108k
  if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "FJ") &&
796
473
      ParseType(state)) {
797
232
    return true;
798
232
  }
799
107k
  *state = copy;
800
801
107k
  if (ParseTwoCharToken(state, "GR") && ParseName(state)) {
802
2.10k
    return true;
803
2.10k
  }
804
105k
  *state = copy;
805
806
105k
  if (ParseTwoCharToken(state, "GA") && ParseEncoding(state)) {
807
253
    return true;
808
253
  }
809
105k
  *state = copy;
810
811
105k
  if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "hv") &&
812
5.93k
      ParseCallOffset(state) && ParseEncoding(state)) {
813
226
    return true;
814
226
  }
815
105k
  *state = copy;
816
105k
  return false;
817
105k
}
818
819
// <call-offset> ::= h <nv-offset> _
820
//               ::= v <v-offset> _
821
18.1k
bool ParseCallOffset(State* state) {
822
18.1k
  State copy = *state;
823
18.1k
  if (ParseOneCharToken(state, 'h') && ParseNVOffset(state) &&
824
2.48k
      ParseOneCharToken(state, '_')) {
825
2.10k
    return true;
826
2.10k
  }
827
16.0k
  *state = copy;
828
829
16.0k
  if (ParseOneCharToken(state, 'v') && ParseVOffset(state) &&
830
589
      ParseOneCharToken(state, '_')) {
831
226
    return true;
832
226
  }
833
15.8k
  *state = copy;
834
835
15.8k
  return false;
836
16.0k
}
837
838
// <nv-offset> ::= <(offset) number>
839
4.26k
bool ParseNVOffset(State* state) { return ParseNumber(state, nullptr); }
840
841
// <v-offset>  ::= <(offset) number> _ <(virtual offset) number>
842
3.79k
bool ParseVOffset(State* state) {
843
3.79k
  State copy = *state;
844
3.79k
  if (ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') &&
845
1.74k
      ParseNumber(state, nullptr)) {
846
589
    return true;
847
589
  }
848
3.20k
  *state = copy;
849
3.20k
  return false;
850
3.79k
}
851
852
// <ctor-dtor-name> ::= C1 | C2 | C3
853
//                  ::= D0 | D1 | D2
854
10.6M
bool ParseCtorDtorName(State* state) {
855
10.6M
  State copy = *state;
856
10.6M
  if (ParseOneCharToken(state, 'C') && ParseCharClass(state, "123")) {
857
519
    const char* const prev_name = state->prev_name;
858
519
    const ssize_t prev_name_length = state->prev_name_length;
859
519
    MaybeAppendWithLength(state, prev_name, prev_name_length);
860
519
    return true;
861
519
  }
862
10.6M
  *state = copy;
863
864
10.6M
  if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "012")) {
865
965
    const char* const prev_name = state->prev_name;
866
965
    const ssize_t prev_name_length = state->prev_name_length;
867
965
    MaybeAppend(state, "~");
868
965
    MaybeAppendWithLength(state, prev_name, prev_name_length);
869
965
    return true;
870
965
  }
871
10.6M
  *state = copy;
872
10.6M
  return false;
873
10.6M
}
874
875
// <type> ::= <CV-qualifiers> <type>
876
//        ::= P <type>   # pointer-to
877
//        ::= R <type>   # reference-to
878
//        ::= O <type>   # rvalue reference-to (C++0x)
879
//        ::= C <type>   # complex pair (C 2000)
880
//        ::= G <type>   # imaginary (C 2000)
881
//        ::= U <source-name> <type>  # vendor extended type qualifier
882
//        ::= <builtin-type>
883
//        ::= <function-type>
884
//        ::= <class-enum-type>
885
//        ::= <array-type>
886
//        ::= <pointer-to-member-type>
887
//        ::= <template-template-param> <template-args>
888
//        ::= <template-param>
889
//        ::= <substitution>
890
//        ::= Dp <type>          # pack expansion of (C++0x)
891
//        ::= Dt <expression> E  # decltype of an id-expression or class
892
//                               # member access (C++0x)
893
//        ::= DT <expression> E  # decltype of an expression (C++0x)
894
//
895
3.44M
bool ParseType(State* state) {
896
  // We should check CV-qualifers, and PRGC things first.
897
3.44M
  State copy = *state;
898
3.44M
  if (ParseCVQualifiers(state) && ParseType(state)) {
899
226
    return true;
900
226
  }
901
3.44M
  *state = copy;
902
903
3.44M
  if (ParseCharClass(state, "OPRCG") && ParseType(state)) {
904
241
    return true;
905
241
  }
906
3.44M
  *state = copy;
907
908
3.44M
  if (ParseTwoCharToken(state, "Dp") && ParseType(state)) {
909
226
    return true;
910
226
  }
911
3.44M
  *state = copy;
912
913
3.44M
  if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "tT") &&
914
922
      ParseExpression(state) && ParseOneCharToken(state, 'E')) {
915
226
    return true;
916
226
  }
917
3.44M
  *state = copy;
918
919
3.44M
  if (ParseOneCharToken(state, 'U') && ParseSourceName(state) &&
920
458
      ParseType(state)) {
921
226
    return true;
922
226
  }
923
3.44M
  *state = copy;
924
925
3.44M
  if (ParseBuiltinType(state) || ParseFunctionType(state) ||
926
3.42M
      ParseClassEnumType(state) || ParseArrayType(state) ||
927
3.41M
      ParsePointerToMemberType(state) || ParseSubstitution(state)) {
928
30.0k
    return true;
929
30.0k
  }
930
931
3.41M
  if (ParseTemplateTemplateParam(state) && ParseTemplateArgs(state)) {
932
460
    return true;
933
460
  }
934
3.41M
  *state = copy;
935
936
  // Less greedy than <template-template-param> <template-args>.
937
3.41M
  if (ParseTemplateParam(state)) {
938
1.15k
    return true;
939
1.15k
  }
940
941
3.41M
  return false;
942
3.41M
}
943
944
// <CV-qualifiers> ::= [r] [V] [K]
945
// We don't allow empty <CV-qualifiers> to avoid infinite loop in
946
// ParseType().
947
6.58M
bool ParseCVQualifiers(State* state) {
948
6.58M
  int num_cv_qualifiers = 0;
949
6.58M
  num_cv_qualifiers += ParseOneCharToken(state, 'r');
950
6.58M
  num_cv_qualifiers += ParseOneCharToken(state, 'V');
951
6.58M
  num_cv_qualifiers += ParseOneCharToken(state, 'K');
952
6.58M
  return num_cv_qualifiers > 0;
953
6.58M
}
954
955
// <builtin-type> ::= v, etc.
956
//                ::= u <source-name>
957
3.44M
bool ParseBuiltinType(State* state) {
958
3.44M
  const AbbrevPair* p;
959
79.0M
  for (p = kBuiltinTypeList; p->abbrev != nullptr; ++p) {
960
75.5M
    if (state->mangled_cur[0] == p->abbrev[0]) {
961
20.6k
      MaybeAppend(state, p->real_name);
962
20.6k
      ++state->mangled_cur;
963
20.6k
      return true;
964
20.6k
    }
965
75.5M
  }
966
967
3.42M
  State copy = *state;
968
3.42M
  if (ParseOneCharToken(state, 'u') && ParseSourceName(state)) {
969
229
    return true;
970
229
  }
971
3.42M
  *state = copy;
972
3.42M
  return false;
973
3.42M
}
974
975
// <function-type> ::= F [Y] <bare-function-type> E
976
3.42M
bool ParseFunctionType(State* state) {
977
3.42M
  State copy = *state;
978
3.42M
  if (ParseOneCharToken(state, 'F') &&
979
1.45k
      Optional(ParseOneCharToken(state, 'Y')) && ParseBareFunctionType(state) &&
980
846
      ParseOneCharToken(state, 'E')) {
981
196
    return true;
982
196
  }
983
3.42M
  *state = copy;
984
3.42M
  return false;
985
3.42M
}
986
987
// <bare-function-type> ::= <(signature) type>+
988
39.9k
bool ParseBareFunctionType(State* state) {
989
39.9k
  State copy = *state;
990
39.9k
  DisableAppend(state);
991
39.9k
  if (OneOrMore(ParseType, state)) {
992
5.51k
    RestoreAppend(state, copy.append);
993
5.51k
    MaybeAppend(state, "()");
994
5.51k
    return true;
995
5.51k
  }
996
34.4k
  *state = copy;
997
34.4k
  return false;
998
39.9k
}
999
1000
// <class-enum-type> ::= <name>
1001
3.42M
bool ParseClassEnumType(State* state) { return ParseName(state); }
1002
1003
// <array-type> ::= A <(positive dimension) number> _ <(element) type>
1004
//              ::= A [<(dimension) expression>] _ <(element) type>
1005
3.41M
bool ParseArrayType(State* state) {
1006
3.41M
  State copy = *state;
1007
3.41M
  if (ParseOneCharToken(state, 'A') && ParseNumber(state, nullptr) &&
1008
842
      ParseOneCharToken(state, '_') && ParseType(state)) {
1009
226
    return true;
1010
226
  }
1011
3.41M
  *state = copy;
1012
1013
3.41M
  if (ParseOneCharToken(state, 'A') && Optional(ParseExpression(state)) &&
1014
5.01k
      ParseOneCharToken(state, '_') && ParseType(state)) {
1015
194
    return true;
1016
194
  }
1017
3.41M
  *state = copy;
1018
3.41M
  return false;
1019
3.41M
}
1020
1021
// <pointer-to-member-type> ::= M <(class) type> <(member) type>
1022
3.41M
bool ParsePointerToMemberType(State* state) {
1023
3.41M
  State copy = *state;
1024
3.41M
  if (ParseOneCharToken(state, 'M') && ParseType(state) && ParseType(state)) {
1025
194
    return true;
1026
194
  }
1027
3.41M
  *state = copy;
1028
3.41M
  return false;
1029
3.41M
}
1030
1031
// <template-param> ::= T_
1032
//                  ::= T <parameter-2 non-negative number> _
1033
10.0M
bool ParseTemplateParam(State* state) {
1034
10.0M
  if (ParseTwoCharToken(state, "T_")) {
1035
5.63k
    MaybeAppend(state, "?");  // We don't support template substitutions.
1036
5.63k
    return true;
1037
5.63k
  }
1038
1039
9.99M
  State copy = *state;
1040
9.99M
  if (ParseOneCharToken(state, 'T') && ParseNumber(state, nullptr) &&
1041
731
      ParseOneCharToken(state, '_')) {
1042
389
    MaybeAppend(state, "?");  // We don't support template substitutions.
1043
389
    return true;
1044
389
  }
1045
9.99M
  *state = copy;
1046
9.99M
  return false;
1047
9.99M
}
1048
1049
// <template-template-param> ::= <template-param>
1050
//                           ::= <substitution>
1051
3.41M
bool ParseTemplateTemplateParam(State* state) {
1052
3.41M
  return (ParseTemplateParam(state) || ParseSubstitution(state));
1053
3.41M
}
1054
1055
// <template-args> ::= I <template-arg>+ E
1056
89.1k
bool ParseTemplateArgs(State* state) {
1057
89.1k
  State copy = *state;
1058
89.1k
  DisableAppend(state);
1059
89.1k
  if (ParseOneCharToken(state, 'I') && OneOrMore(ParseTemplateArg, state) &&
1060
11.3k
      ParseOneCharToken(state, 'E')) {
1061
3.51k
    RestoreAppend(state, copy.append);
1062
3.51k
    MaybeAppend(state, "<>");
1063
3.51k
    return true;
1064
3.51k
  }
1065
85.6k
  *state = copy;
1066
85.6k
  return false;
1067
89.1k
}
1068
1069
// <template-arg>  ::= <type>
1070
//                 ::= <expr-primary>
1071
//                 ::= I <template-arg>* E        # argument pack
1072
//                 ::= J <template-arg>* E        # argument pack
1073
//                 ::= X <expression> E
1074
39.9k
bool ParseTemplateArg(State* state) {
1075
  // Avoid recursion above max_levels
1076
39.9k
  constexpr uint32 max_levels = 6;
1077
1078
39.9k
  if (state->arg_level > max_levels) {
1079
194
    return false;
1080
194
  }
1081
39.7k
  ++state->arg_level;
1082
1083
39.7k
  State copy = *state;
1084
39.7k
  if ((ParseOneCharToken(state, 'I') || ParseOneCharToken(state, 'J')) &&
1085
3.04k
      ZeroOrMore(ParseTemplateArg, state) && ParseOneCharToken(state, 'E')) {
1086
204
    --state->arg_level;
1087
204
    return true;
1088
204
  }
1089
39.5k
  *state = copy;
1090
1091
39.5k
  if (ParseType(state) || ParseExprPrimary(state)) {
1092
13.6k
    --state->arg_level;
1093
13.6k
    return true;
1094
13.6k
  }
1095
25.8k
  *state = copy;
1096
1097
25.8k
  if (ParseOneCharToken(state, 'X') && ParseExpression(state) &&
1098
996
      ParseOneCharToken(state, 'E')) {
1099
202
    --state->arg_level;
1100
202
    return true;
1101
202
  }
1102
25.6k
  *state = copy;
1103
25.6k
  return false;
1104
25.8k
}
1105
1106
// <expression> ::= <template-param>
1107
//              ::= <expr-primary>
1108
//              ::= <unary operator-name> <expression>
1109
//              ::= <binary operator-name> <expression> <expression>
1110
//              ::= <trinary operator-name> <expression> <expression>
1111
//                  <expression>
1112
//              ::= st <type>
1113
//              ::= sr <type> <unqualified-name> <template-args>
1114
//              ::= sr <type> <unqualified-name>
1115
14.2k
bool ParseExpression(State* state) {
1116
14.2k
  if (ParseTemplateParam(state) || ParseExprPrimary(state)) {
1117
3.32k
    return true;
1118
3.32k
  }
1119
1120
  // Avoid recursion above max_levels
1121
10.9k
  constexpr uint32 max_levels = 5;
1122
1123
10.9k
  if (state->expr_level > max_levels) {
1124
856
    return false;
1125
856
  }
1126
10.0k
  ++state->expr_level;
1127
1128
10.0k
  State copy = *state;
1129
10.0k
  if (ParseOperatorName(state) && ParseExpression(state) &&
1130
665
      ParseExpression(state) && ParseExpression(state)) {
1131
228
    --state->expr_level;
1132
228
    return true;
1133
228
  }
1134
9.85k
  *state = copy;
1135
1136
9.85k
  if (ParseOperatorName(state) && ParseExpression(state) &&
1137
437
      ParseExpression(state)) {
1138
194
    --state->expr_level;
1139
194
    return true;
1140
194
  }
1141
9.66k
  *state = copy;
1142
1143
9.66k
  if (ParseOperatorName(state) && ParseExpression(state)) {
1144
243
    --state->expr_level;
1145
243
    return true;
1146
243
  }
1147
9.42k
  *state = copy;
1148
1149
9.42k
  if (ParseTwoCharToken(state, "st") && ParseType(state)) {
1150
218
    return true;
1151
0
    --state->expr_level;
1152
0
  }
1153
9.20k
  *state = copy;
1154
1155
9.20k
  if (ParseTwoCharToken(state, "sr") && ParseType(state) &&
1156
614
      ParseUnqualifiedName(state) && ParseTemplateArgs(state)) {
1157
194
    --state->expr_level;
1158
194
    return true;
1159
194
  }
1160
9.01k
  *state = copy;
1161
1162
9.01k
  if (ParseTwoCharToken(state, "sr") && ParseType(state) &&
1163
420
      ParseUnqualifiedName(state)) {
1164
194
    --state->expr_level;
1165
194
    return true;
1166
194
  }
1167
8.81k
  *state = copy;
1168
1169
  // Pack expansion
1170
8.81k
  if (ParseTwoCharToken(state, "sp") && ParseType(state)) {
1171
194
    --state->expr_level;
1172
194
    return true;
1173
194
  }
1174
8.62k
  *state = copy;
1175
1176
8.62k
  return false;
1177
8.81k
}
1178
1179
// <expr-primary> ::= L <type> <(value) number> E
1180
//                ::= L <type> <(value) float> E
1181
//                ::= L <mangled-name> E
1182
//                // A bug in g++'s C++ ABI version 2 (-fabi-version=2).
1183
//                ::= LZ <encoding> E
1184
37.8k
bool ParseExprPrimary(State* state) {
1185
37.8k
  State copy = *state;
1186
37.8k
  if (ParseOneCharToken(state, 'L') && ParseType(state) &&
1187
2.39k
      ParseNumber(state, nullptr) && ParseOneCharToken(state, 'E')) {
1188
262
    return true;
1189
262
  }
1190
37.5k
  *state = copy;
1191
1192
37.5k
  if (ParseOneCharToken(state, 'L') && ParseType(state) &&
1193
2.13k
      ParseFloatNumber(state) && ParseOneCharToken(state, 'E')) {
1194
344
    return true;
1195
344
  }
1196
37.2k
  *state = copy;
1197
1198
37.2k
  if (ParseOneCharToken(state, 'L') && ParseMangledName(state) &&
1199
1.28k
      ParseOneCharToken(state, 'E')) {
1200
194
    return true;
1201
194
  }
1202
37.0k
  *state = copy;
1203
1204
37.0k
  if (ParseTwoCharToken(state, "LZ") && ParseEncoding(state) &&
1205
422
      ParseOneCharToken(state, 'E')) {
1206
212
    return true;
1207
212
  }
1208
36.8k
  *state = copy;
1209
1210
36.8k
  return false;
1211
37.0k
}
1212
1213
// <local-name> := Z <(function) encoding> E <(entity) name>
1214
//                 [<discriminator>]
1215
//              := Z <(function) encoding> E s [<discriminator>]
1216
3.73M
bool ParseLocalName(State* state) {
1217
  // Avoid recursion above max_levels
1218
3.73M
  constexpr uint32 max_levels = 5;
1219
3.73M
  if (state->local_level > max_levels) {
1220
2.06M
    return false;
1221
2.06M
  }
1222
1.66M
  ++state->local_level;
1223
1224
1.66M
  State copy = *state;
1225
1.66M
  if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) &&
1226
21.1k
      ParseOneCharToken(state, 'E') && MaybeAppend(state, "::") &&
1227
5.53k
      ParseName(state) && Optional(ParseDiscriminator(state))) {
1228
2.28k
    --state->local_level;
1229
2.28k
    return true;
1230
2.28k
  }
1231
1.66M
  *state = copy;
1232
1233
1.66M
  if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) &&
1234
18.8k
      ParseTwoCharToken(state, "Es") && Optional(ParseDiscriminator(state))) {
1235
2.37k
    --state->local_level;
1236
2.37k
    return true;
1237
2.37k
  }
1238
1.66M
  *state = copy;
1239
1.66M
  return false;
1240
1.66M
}
1241
1242
// <discriminator> := _ <(non-negative) number>
1243
11.2k
bool ParseDiscriminator(State* state) {
1244
11.2k
  State copy = *state;
1245
11.2k
  if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr)) {
1246
1.72k
    return true;
1247
1.72k
  }
1248
9.49k
  *state = copy;
1249
9.49k
  return false;
1250
11.2k
}
1251
1252
// <substitution> ::= S_
1253
//                ::= S <seq-id> _
1254
//                ::= St, etc.
1255
13.6M
bool ParseSubstitution(State* state) {
1256
13.6M
  if (ParseTwoCharToken(state, "S_")) {
1257
653
    MaybeAppend(state, "?");  // We don't support substitutions.
1258
653
    return true;
1259
653
  }
1260
1261
13.6M
  State copy = *state;
1262
13.6M
  if (ParseOneCharToken(state, 'S') && ParseSeqId(state) &&
1263
996
      ParseOneCharToken(state, '_')) {
1264
412
    MaybeAppend(state, "?");  // We don't support substitutions.
1265
412
    return true;
1266
412
  }
1267
13.6M
  *state = copy;
1268
1269
  // Expand abbreviations like "St" => "std".
1270
13.6M
  if (ParseOneCharToken(state, 'S')) {
1271
14.7k
    const AbbrevPair* p;
1272
51.1k
    for (p = kSubstitutionList; p->abbrev != nullptr; ++p) {
1273
48.5k
      if (state->mangled_cur[0] == p->abbrev[1]) {
1274
12.0k
        MaybeAppend(state, "std");
1275
12.0k
        if (p->real_name[0] != '\0') {
1276
8.91k
          MaybeAppend(state, "::");
1277
8.91k
          MaybeAppend(state, p->real_name);
1278
8.91k
        }
1279
12.0k
        ++state->mangled_cur;
1280
12.0k
        return true;
1281
12.0k
      }
1282
48.5k
    }
1283
14.7k
  }
1284
13.6M
  *state = copy;
1285
13.6M
  return false;
1286
13.6M
}
1287
1288
// Parse <mangled-name>, optionally followed by either a function-clone suffix
1289
// or version suffix.  Returns true only if all of "mangled_cur" was consumed.
1290
4.74k
bool ParseTopLevelMangledName(State* state) {
1291
4.74k
  if (ParseMangledName(state)) {
1292
1.94k
    if (state->mangled_cur[0] != '\0') {
1293
      // Drop trailing function clone suffix, if any.
1294
1.45k
      if (IsFunctionCloneSuffix(state->mangled_cur)) {
1295
20
        return true;
1296
20
      }
1297
      // Append trailing version suffix if any.
1298
      // ex. _Z3foo@@GLIBCXX_3.4
1299
1.43k
      if (state->mangled_cur[0] == '@') {
1300
26
        MaybeAppend(state, state->mangled_cur);
1301
26
        return true;
1302
26
      }
1303
1.41k
      return ParseName(state);
1304
1.43k
    }
1305
483
    return true;
1306
1.94k
  }
1307
2.79k
  return false;
1308
4.74k
}
1309
}  // namespace
1310
#endif
1311
1312
// The demangler entry point.
1313
4.74k
bool Demangle(const char* mangled, char* out, size_t out_size) {
1314
#if defined(GLOG_OS_WINDOWS)
1315
#  if defined(HAVE_DBGHELP)
1316
  // When built with incremental linking, the Windows debugger
1317
  // library provides a more complicated `Symbol->Name` with the
1318
  // Incremental Linking Table offset, which looks like
1319
  // `@ILT+1105(?func@Foo@@SAXH@Z)`. However, the demangler expects
1320
  // only the mangled symbol, `?func@Foo@@SAXH@Z`. Fortunately, the
1321
  // mangled symbol is guaranteed not to have parentheses,
1322
  // so we search for `(` and extract up to `)`.
1323
  //
1324
  // Since we may be in a signal handler here, we cannot use `std::string`.
1325
  char buffer[1024];  // Big enough for a sane symbol.
1326
  const char* lparen = strchr(mangled, '(');
1327
  if (lparen) {
1328
    // Extract the string `(?...)`
1329
    const char* rparen = strchr(lparen, ')');
1330
    size_t length = static_cast<size_t>(rparen - lparen) - 1;
1331
    strncpy(buffer, lparen + 1, length);
1332
    buffer[length] = '\0';
1333
    mangled = buffer;
1334
  }  // Else the symbol wasn't inside a set of parentheses
1335
  // We use the ANSI version to ensure the string type is always `char *`.
1336
  return UnDecorateSymbolName(mangled, out, out_size, UNDNAME_COMPLETE);
1337
#  else
1338
  (void)mangled;
1339
  (void)out;
1340
  (void)out_size;
1341
  return false;
1342
#  endif
1343
#elif defined(HAVE___CXA_DEMANGLE)
1344
  int status = -1;
1345
  std::size_t n = 0;
1346
  std::unique_ptr<char, decltype(&std::free)> unmangled{
1347
      abi::__cxa_demangle(mangled, nullptr, &n, &status), &std::free};
1348
1349
  if (!unmangled) {
1350
    return false;
1351
  }
1352
1353
  std::copy_n(unmangled.get(), std::min(n, out_size), out);
1354
  return status == 0;
1355
#else
1356
4.74k
  State state;
1357
4.74k
  InitState(&state, mangled, out, out_size);
1358
4.74k
  return ParseTopLevelMangledName(&state) && !state.overflowed;
1359
4.74k
#endif
1360
4.74k
}
1361
1362
}  // namespace glog_internal_namespace_
1363
}  // namespace google