Coverage Report

Created: 2026-01-10 06:27

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.86M
size_t StrLen(const char* str) {
129
3.86M
  size_t len = 0;
130
46.0M
  while (*str != '\0') {
131
42.1M
    ++str;
132
42.1M
    ++len;
133
42.1M
  }
134
3.86M
  return len;
135
3.86M
}
136
137
// Returns true if "str" has at least "n" characters remaining.
138
11.8M
bool AtLeastNumCharsRemaining(const char* str, ssize_t n) {
139
34.5M
  for (ssize_t i = 0; i < n; ++i) {
140
23.1M
    if (str[i] == '\0') {
141
480k
      return false;
142
480k
    }
143
23.1M
  }
144
11.3M
  return true;
145
11.8M
}
146
147
// Returns true if "str" has "prefix" as a prefix.
148
910
bool StrPrefix(const char* str, const char* prefix) {
149
910
  size_t i = 0;
150
7.79k
  while (str[i] != '\0' && prefix[i] != '\0' && str[i] == prefix[i]) {
151
6.88k
    ++i;
152
6.88k
  }
153
910
  return prefix[i] == '\0';  // Consumed everything in "prefix".
154
910
}
155
156
4.70k
void InitState(State* state, const char* mangled, char* out, size_t out_size) {
157
4.70k
  state->mangled_cur = mangled;
158
4.70k
  state->out_cur = out;
159
4.70k
  state->out_begin = out;
160
4.70k
  state->out_end = out + out_size;
161
4.70k
  state->prev_name = nullptr;
162
4.70k
  state->prev_name_length = -1;
163
4.70k
  state->nest_level = -1;
164
4.70k
  state->append = true;
165
4.70k
  state->overflowed = false;
166
4.70k
  state->local_level = 0;
167
4.70k
  state->expr_level = 0;
168
4.70k
  state->arg_level = 0;
169
4.70k
}
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
159M
bool ParseOneCharToken(State* state, const char one_char_token) {
175
159M
  if (state->mangled_cur[0] == one_char_token) {
176
3.85M
    ++state->mangled_cur;
177
3.85M
    return true;
178
3.85M
  }
179
155M
  return false;
180
159M
}
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
53.1M
bool ParseTwoCharToken(State* state, const char* two_char_token) {
186
53.1M
  if (state->mangled_cur[0] == two_char_token[0] &&
187
3.77M
      state->mangled_cur[1] == two_char_token[1]) {
188
3.71M
    state->mangled_cur += 2;
189
3.71M
    return true;
190
3.71M
  }
191
49.4M
  return false;
192
53.1M
}
193
194
// Returns true and advances "mangled_cur" if we find any character in
195
// "char_class" at "mangled_cur" position.
196
3.83M
bool ParseCharClass(State* state, const char* char_class) {
197
3.83M
  const char* p = char_class;
198
22.8M
  for (; *p != '\0'; ++p) {
199
19.0M
    if (state->mangled_cur[0] == *p) {
200
22.7k
      ++state->mangled_cur;
201
22.7k
      return true;
202
22.7k
    }
203
19.0M
  }
204
3.81M
  return false;
205
3.83M
}
206
207
// This function is used for handling an optional non-terminal.
208
3.69M
bool Optional(bool) { return true; }
209
210
// This function is used for handling <non-terminal>+ syntax.
211
using ParseFunc = bool (*)(State*);
212
228k
bool OneOrMore(ParseFunc parse_func, State* state) {
213
228k
  if (parse_func(state)) {
214
25.1k
    while (parse_func(state)) {
215
4.09k
    }
216
21.0k
    return true;
217
21.0k
  }
218
207k
  return false;
219
228k
}
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
2.95k
bool ZeroOrMore(ParseFunc parse_func, State* state) {
226
3.76k
  while (parse_func(state)) {
227
812
  }
228
2.95k
  return true;
229
2.95k
}
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.69M
void Append(State* state, const char* const str, ssize_t length) {
235
3.69M
  if (state->out_cur == nullptr) {
236
0
    state->overflowed = true;
237
0
    return;
238
0
  }
239
9.42M
  for (ssize_t i = 0; i < length; ++i) {
240
8.80M
    if (state->out_cur + 1 < state->out_end) {  // +1 for '\0'
241
5.72M
      *state->out_cur = str[i];
242
5.72M
      ++state->out_cur;
243
5.72M
    } else {
244
3.07M
      state->overflowed = true;
245
3.07M
      break;
246
3.07M
    }
247
8.80M
  }
248
3.69M
  if (!state->overflowed) {
249
618k
    *state->out_cur = '\0';  // Terminate it with '\0'
250
618k
  }
251
3.69M
}
252
253
// We don't use equivalents in libc to avoid locale issues.
254
11.2M
bool IsLower(char c) { return c >= 'a' && c <= 'z'; }
255
256
7.39M
bool IsAlpha(char c) {
257
7.39M
  return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
258
7.39M
}
259
260
11.5M
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.43k
bool IsFunctionCloneSuffix(const char* str) {
267
1.43k
  size_t i = 0;
268
2.07k
  while (str[i] != '\0') {
269
    // Consume a single .<alpha>+.<digit>+ sequence.
270
2.04k
    if (str[i] != '.' || !IsAlpha(str[i + 1])) {
271
1.34k
      return false;
272
1.34k
    }
273
700
    i += 2;
274
1.14k
    while (IsAlpha(str[i])) {
275
445
      ++i;
276
445
    }
277
700
    if (str[i] != '.' || !IsDigit(str[i + 1])) {
278
62
      return false;
279
62
    }
280
638
    i += 2;
281
838
    while (IsDigit(str[i])) {
282
200
      ++i;
283
200
    }
284
638
  }
285
23
  return true;  // Consumed everything in "str".
286
1.43k
}
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.86M
                           ssize_t length) {
292
3.86M
  if (state->append && length > 0) {
293
    // Append a space if the output buffer ends with '<' and "str"
294
    // starts with '<' to avoid <<<.
295
3.69M
    if (str[0] == '<' && state->out_begin < state->out_cur &&
296
1.49k
        state->out_cur[-1] == '<') {
297
388
      Append(state, " ", 1);
298
388
    }
299
    // Remember the last identifier name for ctors/dtors.
300
3.69M
    if (IsAlpha(str[0]) || str[0] == '_') {
301
3.65M
      state->prev_name = state->out_cur;
302
3.65M
      state->prev_name_length = length;
303
3.65M
    }
304
3.69M
    Append(state, str, length);
305
3.69M
  }
306
3.86M
}
307
308
// A convenient wrapper around MaybeAppendWithLength().
309
3.79M
bool MaybeAppend(State* state, const char* const str) {
310
3.79M
  if (state->append) {
311
3.69M
    size_t length = StrLen(str);
312
3.69M
    MaybeAppendWithLength(state, str, static_cast<ssize_t>(length));
313
3.69M
  }
314
3.79M
  return true;
315
3.79M
}
316
317
// This function is used for handling nested names.
318
7.18M
bool EnterNestedName(State* state) {
319
7.18M
  state->nest_level = 0;
320
7.18M
  return true;
321
7.18M
}
322
323
// This function is used for handling nested names.
324
3.51M
bool LeaveNestedName(State* state, short prev_value) {
325
3.51M
  state->nest_level = prev_value;
326
3.51M
  return true;
327
3.51M
}
328
329
// Disable the append mode not to print function parameters, etc.
330
294k
bool DisableAppend(State* state) {
331
294k
  state->append = false;
332
294k
  return true;
333
294k
}
334
335
// Restore the append mode to the previous state.
336
13.3k
bool RestoreAppend(State* state, bool prev_value) {
337
13.3k
  state->append = prev_value;
338
13.3k
  return true;
339
13.3k
}
340
341
// Increase the nest level for nested names.
342
19.6k
void MaybeIncreaseNestLevel(State* state) {
343
19.6k
  if (state->nest_level > -1) {
344
19.6k
    ++state->nest_level;
345
19.6k
  }
346
19.6k
}
347
348
// Appends :: for nested names if necessary.
349
3.53M
void MaybeAppendSeparator(State* state) {
350
3.53M
  if (state->nest_level >= 1) {
351
20.0k
    MaybeAppend(state, "::");
352
20.0k
  }
353
3.53M
}
354
355
// Cancel the last separator if necessary.
356
3.51M
void MaybeCancelLastSeparator(State* state) {
357
3.51M
  if (state->nest_level >= 1 && state->append &&
358
2.78k
      state->out_begin <= state->out_cur - 2) {
359
2.78k
    state->out_cur -= 2;
360
2.78k
    *state->out_cur = '\0';
361
2.78k
  }
362
3.51M
}
363
364
// Returns true if the identifier of the given length pointed to by
365
// "mangled_cur" is anonymous namespace.
366
171k
bool IdentifierIsAnonymousNamespace(State* state, ssize_t length) {
367
171k
  const char anon_prefix[] = "_GLOBAL__N_";
368
171k
  return (length > static_cast<ssize_t>(sizeof(anon_prefix)) -
369
171k
                       1 &&  // Should be longer.
370
910
          StrPrefix(state->mangled_cur, anon_prefix));
371
171k
}
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.10k
bool ParseMangledName(State* state) {
446
9.10k
  return ParseTwoCharToken(state, "_Z") && ParseEncoding(state);
447
9.10k
}
448
449
// <encoding> ::= <(function) name> <bare-function-type>
450
//            ::= <(data) name>
451
//            ::= <special-name>
452
140k
bool ParseEncoding(State* state) {
453
140k
  State copy = *state;
454
140k
  if (ParseName(state) && ParseBareFunctionType(state)) {
455
3.77k
    return true;
456
3.77k
  }
457
136k
  *state = copy;
458
459
136k
  if (ParseName(state) || ParseSpecialName(state)) {
460
40.9k
    return true;
461
40.9k
  }
462
95.9k
  return false;
463
136k
}
464
465
// <name> ::= <nested-name>
466
//        ::= <unscoped-template-name> <template-args>
467
//        ::= <unscoped-name>
468
//        ::= <local-name>
469
4.06M
bool ParseName(State* state) {
470
4.06M
  if (ParseNestedName(state) || ParseLocalName(state)) {
471
5.67k
    return true;
472
5.67k
  }
473
474
4.05M
  State copy = *state;
475
4.05M
  if (ParseUnscopedTemplateName(state) && ParseTemplateArgs(state)) {
476
2.63k
    return true;
477
2.63k
  }
478
4.05M
  *state = copy;
479
480
  // Less greedy than <unscoped-template-name> <template-args>.
481
4.05M
  if (ParseUnscopedName(state)) {
482
77.6k
    return true;
483
77.6k
  }
484
3.97M
  return false;
485
4.05M
}
486
487
// <unscoped-name> ::= <unqualified-name>
488
//                 ::= St <unqualified-name>
489
11.6M
bool ParseUnscopedName(State* state) {
490
11.6M
  if (ParseUnqualifiedName(state)) {
491
162k
    return true;
492
162k
  }
493
494
11.4M
  State copy = *state;
495
11.4M
  if (ParseTwoCharToken(state, "St") && MaybeAppend(state, "std::") &&
496
10.5k
      ParseUnqualifiedName(state)) {
497
6.58k
    return true;
498
6.58k
  }
499
11.4M
  *state = copy;
500
11.4M
  return false;
501
11.4M
}
502
503
// <unscoped-template-name> ::= <unscoped-name>
504
//                          ::= <substitution>
505
4.05M
bool ParseUnscopedTemplateName(State* state) {
506
4.05M
  return ParseUnscopedName(state) || ParseSubstitution(state);
507
4.05M
}
508
509
// <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
510
//               ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
511
4.06M
bool ParseNestedName(State* state) {
512
4.06M
  State copy = *state;
513
4.06M
  if (ParseOneCharToken(state, 'N') && EnterNestedName(state) &&
514
3.51M
      Optional(ParseCVQualifiers(state)) && ParsePrefix(state) &&
515
3.51M
      LeaveNestedName(state, copy.nest_level) &&
516
3.51M
      ParseOneCharToken(state, 'E')) {
517
1.14k
    return true;
518
1.14k
  }
519
4.06M
  *state = copy;
520
4.06M
  return false;
521
4.06M
}
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.51M
bool ParsePrefix(State* state) {
535
3.51M
  bool has_something = false;
536
3.53M
  while (true) {
537
3.53M
    MaybeAppendSeparator(state);
538
3.53M
    if (ParseTemplateParam(state) || ParseSubstitution(state) ||
539
3.52M
        ParseUnscopedName(state)) {
540
19.6k
      has_something = true;
541
19.6k
      MaybeIncreaseNestLevel(state);
542
19.6k
      continue;
543
19.6k
    }
544
3.51M
    MaybeCancelLastSeparator(state);
545
3.51M
    if (has_something && ParseTemplateArgs(state)) {
546
428
      return ParsePrefix(state);
547
3.51M
    } else {
548
3.51M
      break;
549
3.51M
    }
550
3.51M
  }
551
3.51M
  return true;
552
3.51M
}
553
554
// <unqualified-name> ::= <operator-name>
555
//                    ::= <ctor-dtor-name>
556
//                    ::= <source-name> [<abi-tags>]
557
//                    ::= <local-source-name> [<abi-tags>]
558
11.6M
bool ParseUnqualifiedName(State* state) {
559
11.6M
  return (ParseOperatorName(state) || ParseCtorDtorName(state) ||
560
11.6M
          (ParseSourceName(state) && Optional(ParseAbiTags(state))) ||
561
11.4M
          (ParseLocalSourceName(state) && Optional(ParseAbiTags(state))));
562
11.6M
}
563
564
// <source-name> ::= <positive length number> <identifier>
565
11.6M
bool ParseSourceName(State* state) {
566
11.6M
  State copy = *state;
567
11.6M
  int length = -1;
568
11.6M
  if (ParseNumber(state, &length) && ParseIdentifier(state, length)) {
569
170k
    return true;
570
170k
  }
571
11.5M
  *state = copy;
572
11.5M
  return false;
573
11.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
11.4M
bool ParseLocalSourceName(State* state) {
581
11.4M
  State copy = *state;
582
11.4M
  if (ParseOneCharToken(state, 'L') && ParseSourceName(state) &&
583
6.02k
      Optional(ParseDiscriminator(state))) {
584
6.02k
    return true;
585
6.02k
  }
586
11.4M
  *state = copy;
587
11.4M
  return false;
588
11.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
11.6M
bool ParseNumber(State* state, int* number_out) {
594
11.6M
  int sign = 1;
595
11.6M
  if (ParseOneCharToken(state, 'n')) {
596
3.91k
    sign = -1;
597
3.91k
  }
598
11.6M
  const char* p = state->mangled_cur;
599
11.6M
  int number = 0;
600
11.6M
  constexpr int int_max_by_10 = std::numeric_limits<int>::max() / 10;
601
11.9M
  for (; *p != '\0'; ++p) {
602
11.5M
    if (IsDigit(*p)) {
603
      // Prevent signed integer overflow when multiplying
604
247k
      if (number > int_max_by_10) {
605
2.51k
        return false;
606
2.51k
      }
607
608
244k
      const int digit = *p - '0';
609
244k
      const int shifted = number * 10;
610
611
      // Prevent signed integer overflow when summing
612
244k
      if (digit > std::numeric_limits<int>::max() - shifted) {
613
2.68k
        return false;
614
2.68k
      }
615
616
242k
      number = shifted + digit;
617
11.2M
    } else {
618
11.2M
      break;
619
11.2M
    }
620
11.5M
  }
621
11.6M
  if (p != state->mangled_cur) {  // Conversion succeeded.
622
183k
    state->mangled_cur = p;
623
183k
    if (number_out != nullptr) {
624
172k
      *number_out = number * sign;
625
172k
    }
626
183k
    return true;
627
183k
  }
628
11.5M
  return false;
629
11.6M
}
630
631
// Floating-point literals are encoded using a fixed-length lowercase
632
// hexadecimal string.
633
2.05k
bool ParseFloatNumber(State* state) {
634
2.05k
  const char* p = state->mangled_cur;
635
7.63k
  for (; *p != '\0'; ++p) {
636
6.55k
    if (!IsDigit(*p) && !(*p >= 'a' && *p <= 'f')) {
637
964
      break;
638
964
    }
639
6.55k
  }
640
2.05k
  if (p != state->mangled_cur) {  // Conversion succeeded.
641
1.42k
    state->mangled_cur = p;
642
1.42k
    return true;
643
1.42k
  }
644
624
  return false;
645
2.05k
}
646
647
// The <seq-id> is a sequence number in base 36,
648
// using digits and upper case letters
649
14.2k
bool ParseSeqId(State* state) {
650
14.2k
  const char* p = state->mangled_cur;
651
15.1k
  for (; *p != '\0'; ++p) {
652
12.9k
    if (!IsDigit(*p) && !(*p >= 'A' && *p <= 'Z')) {
653
12.0k
      break;
654
12.0k
    }
655
12.9k
  }
656
14.2k
  if (p != state->mangled_cur) {  // Conversion succeeded.
657
862
    state->mangled_cur = p;
658
862
    return true;
659
862
  }
660
13.3k
  return false;
661
14.2k
}
662
663
// <identifier> ::= <unqualified source code identifier> (of given length)
664
172k
bool ParseIdentifier(State* state, ssize_t length) {
665
172k
  if (length == -1 || !AtLeastNumCharsRemaining(state->mangled_cur, length)) {
666
1.11k
    return false;
667
1.11k
  }
668
171k
  if (IdentifierIsAnonymousNamespace(state, length)) {
669
589
    MaybeAppend(state, "(anonymous namespace)");
670
170k
  } else {
671
170k
    MaybeAppendWithLength(state, state->mangled_cur, length);
672
170k
  }
673
171k
  if (length < 0 ||
674
170k
      static_cast<std::size_t>(length) > StrLen(state->mangled_cur)) {
675
659
    return false;
676
659
  }
677
170k
  state->mangled_cur += length;
678
170k
  return true;
679
171k
}
680
681
// <abi-tags> ::= <abi-tag> [<abi-tags>]
682
163k
bool ParseAbiTags(State* state) {
683
163k
  State copy = *state;
684
163k
  DisableAppend(state);
685
163k
  if (OneOrMore(ParseAbiTag, state)) {
686
4.69k
    RestoreAppend(state, copy.append);
687
4.69k
    return true;
688
4.69k
  }
689
159k
  *state = copy;
690
159k
  return false;
691
163k
}
692
693
// <abi-tag> ::= B <source-name>
694
169k
bool ParseAbiTag(State* state) {
695
169k
  return ParseOneCharToken(state, 'B') && ParseSourceName(state);
696
169k
}
697
698
// <operator-name> ::= nw, and other two letters cases
699
//                 ::= cv <type>  # (cast)
700
//                 ::= v  <digit> <source-name> # vendor extended operator
701
11.6M
bool ParseOperatorName(State* state) {
702
11.6M
  if (!AtLeastNumCharsRemaining(state->mangled_cur, 2)) {
703
479k
    return false;
704
479k
  }
705
  // First check with "cv" (cast) case.
706
11.2M
  State copy = *state;
707
11.2M
  if (ParseTwoCharToken(state, "cv") && MaybeAppend(state, "operator ") &&
708
3.67M
      EnterNestedName(state) && ParseType(state) &&
709
1.94k
      LeaveNestedName(state, copy.nest_level)) {
710
1.94k
    return true;
711
1.94k
  }
712
11.2M
  *state = copy;
713
714
  // Then vendor extended operators.
715
11.2M
  if (ParseOneCharToken(state, 'v') && ParseCharClass(state, "0123456789") &&
716
477
      ParseSourceName(state)) {
717
229
    return true;
718
229
  }
719
11.2M
  *state = copy;
720
721
  // Other operator names should start with a lower alphabet followed
722
  // by a lower/upper alphabet.
723
11.2M
  if (!(IsLower(state->mangled_cur[0]) && IsAlpha(state->mangled_cur[1]))) {
724
7.51M
    return false;
725
7.51M
  }
726
  // We may want to perform a binary search if we really need speed.
727
3.69M
  const AbbrevPair* p;
728
184M
  for (p = kOperatorList; p->abbrev != nullptr; ++p) {
729
180M
    if (state->mangled_cur[0] == p->abbrev[0] &&
730
11.0M
        state->mangled_cur[1] == p->abbrev[1]) {
731
7.24k
      MaybeAppend(state, "operator");
732
7.24k
      if (IsLower(*p->real_name)) {  // new, delete, etc.
733
3.12k
        MaybeAppend(state, " ");
734
3.12k
      }
735
7.24k
      MaybeAppend(state, p->real_name);
736
7.24k
      state->mangled_cur += 2;
737
7.24k
      return true;
738
7.24k
    }
739
180M
  }
740
3.68M
  return false;
741
3.69M
}
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
101k
bool ParseSpecialName(State* state) {
762
101k
  State copy = *state;
763
101k
  if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "VTIS") &&
764
502
      ParseType(state)) {
765
252
    return true;
766
252
  }
767
101k
  *state = copy;
768
769
101k
  if (ParseTwoCharToken(state, "Tc") && ParseCallOffset(state) &&
770
678
      ParseCallOffset(state) && ParseEncoding(state)) {
771
226
    return true;
772
226
  }
773
101k
  *state = copy;
774
775
101k
  if (ParseTwoCharToken(state, "GV") && ParseName(state)) {
776
2.12k
    return true;
777
2.12k
  }
778
99.2k
  *state = copy;
779
780
99.2k
  if (ParseOneCharToken(state, 'T') && ParseCallOffset(state) &&
781
678
      ParseEncoding(state)) {
782
226
    return true;
783
226
  }
784
98.9k
  *state = copy;
785
786
  // G++ extensions
787
98.9k
  if (ParseTwoCharToken(state, "TC") && ParseType(state) &&
788
2.22k
      ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') &&
789
454
      DisableAppend(state) && ParseType(state)) {
790
226
    RestoreAppend(state, copy.append);
791
226
    return true;
792
226
  }
793
98.7k
  *state = copy;
794
795
98.7k
  if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "FJ") &&
796
508
      ParseType(state)) {
797
260
    return true;
798
260
  }
799
98.4k
  *state = copy;
800
801
98.4k
  if (ParseTwoCharToken(state, "GR") && ParseName(state)) {
802
2.07k
    return true;
803
2.07k
  }
804
96.4k
  *state = copy;
805
806
96.4k
  if (ParseTwoCharToken(state, "GA") && ParseEncoding(state)) {
807
265
    return true;
808
265
  }
809
96.1k
  *state = copy;
810
811
96.1k
  if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "hv") &&
812
6.24k
      ParseCallOffset(state) && ParseEncoding(state)) {
813
226
    return true;
814
226
  }
815
95.9k
  *state = copy;
816
95.9k
  return false;
817
96.1k
}
818
819
// <call-offset> ::= h <nv-offset> _
820
//               ::= v <v-offset> _
821
18.6k
bool ParseCallOffset(State* state) {
822
18.6k
  State copy = *state;
823
18.6k
  if (ParseOneCharToken(state, 'h') && ParseNVOffset(state) &&
824
2.48k
      ParseOneCharToken(state, '_')) {
825
2.03k
    return true;
826
2.03k
  }
827
16.6k
  *state = copy;
828
829
16.6k
  if (ParseOneCharToken(state, 'v') && ParseVOffset(state) &&
830
655
      ParseOneCharToken(state, '_')) {
831
226
    return true;
832
226
  }
833
16.3k
  *state = copy;
834
835
16.3k
  return false;
836
16.6k
}
837
838
// <nv-offset> ::= <(offset) number>
839
4.25k
bool ParseNVOffset(State* state) { return ParseNumber(state, nullptr); }
840
841
// <v-offset>  ::= <(offset) number> _ <(virtual offset) number>
842
4.17k
bool ParseVOffset(State* state) {
843
4.17k
  State copy = *state;
844
4.17k
  if (ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') &&
845
1.89k
      ParseNumber(state, nullptr)) {
846
655
    return true;
847
655
  }
848
3.51k
  *state = copy;
849
3.51k
  return false;
850
4.17k
}
851
852
// <ctor-dtor-name> ::= C1 | C2 | C3
853
//                  ::= D0 | D1 | D2
854
11.6M
bool ParseCtorDtorName(State* state) {
855
11.6M
  State copy = *state;
856
11.6M
  if (ParseOneCharToken(state, 'C') && ParseCharClass(state, "123")) {
857
303
    const char* const prev_name = state->prev_name;
858
303
    const ssize_t prev_name_length = state->prev_name_length;
859
303
    MaybeAppendWithLength(state, prev_name, prev_name_length);
860
303
    return true;
861
303
  }
862
11.6M
  *state = copy;
863
864
11.6M
  if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "012")) {
865
1.12k
    const char* const prev_name = state->prev_name;
866
1.12k
    const ssize_t prev_name_length = state->prev_name_length;
867
1.12k
    MaybeAppend(state, "~");
868
1.12k
    MaybeAppendWithLength(state, prev_name, prev_name_length);
869
1.12k
    return true;
870
1.12k
  }
871
11.6M
  *state = copy;
872
11.6M
  return false;
873
11.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.79M
bool ParseType(State* state) {
896
  // We should check CV-qualifers, and PRGC things first.
897
3.79M
  State copy = *state;
898
3.79M
  if (ParseCVQualifiers(state) && ParseType(state)) {
899
301
    return true;
900
301
  }
901
3.79M
  *state = copy;
902
903
3.79M
  if (ParseCharClass(state, "OPRCG") && ParseType(state)) {
904
276
    return true;
905
276
  }
906
3.79M
  *state = copy;
907
908
3.79M
  if (ParseTwoCharToken(state, "Dp") && ParseType(state)) {
909
226
    return true;
910
226
  }
911
3.79M
  *state = copy;
912
913
3.79M
  if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "tT") &&
914
847
      ParseExpression(state) && ParseOneCharToken(state, 'E')) {
915
226
    return true;
916
226
  }
917
3.79M
  *state = copy;
918
919
3.79M
  if (ParseOneCharToken(state, 'U') && ParseSourceName(state) &&
920
455
      ParseType(state)) {
921
226
    return true;
922
226
  }
923
3.79M
  *state = copy;
924
925
3.79M
  if (ParseBuiltinType(state) || ParseFunctionType(state) ||
926
3.77M
      ParseClassEnumType(state) || ParseArrayType(state) ||
927
3.76M
      ParsePointerToMemberType(state) || ParseSubstitution(state)) {
928
28.9k
    return true;
929
28.9k
  }
930
931
3.76M
  if (ParseTemplateTemplateParam(state) && ParseTemplateArgs(state)) {
932
452
    return true;
933
452
  }
934
3.76M
  *state = copy;
935
936
  // Less greedy than <template-template-param> <template-args>.
937
3.76M
  if (ParseTemplateParam(state)) {
938
901
    return true;
939
901
  }
940
941
3.76M
  return false;
942
3.76M
}
943
944
// <CV-qualifiers> ::= [r] [V] [K]
945
// We don't allow empty <CV-qualifiers> to avoid infinite loop in
946
// ParseType().
947
7.31M
bool ParseCVQualifiers(State* state) {
948
7.31M
  int num_cv_qualifiers = 0;
949
7.31M
  num_cv_qualifiers += ParseOneCharToken(state, 'r');
950
7.31M
  num_cv_qualifiers += ParseOneCharToken(state, 'V');
951
7.31M
  num_cv_qualifiers += ParseOneCharToken(state, 'K');
952
7.31M
  return num_cv_qualifiers > 0;
953
7.31M
}
954
955
// <builtin-type> ::= v, etc.
956
//                ::= u <source-name>
957
3.79M
bool ParseBuiltinType(State* state) {
958
3.79M
  const AbbrevPair* p;
959
87.0M
  for (p = kBuiltinTypeList; p->abbrev != nullptr; ++p) {
960
83.2M
    if (state->mangled_cur[0] == p->abbrev[0]) {
961
21.1k
      MaybeAppend(state, p->real_name);
962
21.1k
      ++state->mangled_cur;
963
21.1k
      return true;
964
21.1k
    }
965
83.2M
  }
966
967
3.77M
  State copy = *state;
968
3.77M
  if (ParseOneCharToken(state, 'u') && ParseSourceName(state)) {
969
234
    return true;
970
234
  }
971
3.77M
  *state = copy;
972
3.77M
  return false;
973
3.77M
}
974
975
// <function-type> ::= F [Y] <bare-function-type> E
976
3.77M
bool ParseFunctionType(State* state) {
977
3.77M
  State copy = *state;
978
3.77M
  if (ParseOneCharToken(state, 'F') &&
979
3.13k
      Optional(ParseOneCharToken(state, 'Y')) && ParseBareFunctionType(state) &&
980
989
      ParseOneCharToken(state, 'E')) {
981
194
    return true;
982
194
  }
983
3.77M
  *state = copy;
984
3.77M
  return false;
985
3.77M
}
986
987
// <bare-function-type> ::= <(signature) type>+
988
41.9k
bool ParseBareFunctionType(State* state) {
989
41.9k
  State copy = *state;
990
41.9k
  DisableAppend(state);
991
41.9k
  if (OneOrMore(ParseType, state)) {
992
4.76k
    RestoreAppend(state, copy.append);
993
4.76k
    MaybeAppend(state, "()");
994
4.76k
    return true;
995
4.76k
  }
996
37.1k
  *state = copy;
997
37.1k
  return false;
998
41.9k
}
999
1000
// <class-enum-type> ::= <name>
1001
3.77M
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.76M
bool ParseArrayType(State* state) {
1006
3.76M
  State copy = *state;
1007
3.76M
  if (ParseOneCharToken(state, 'A') && ParseNumber(state, nullptr) &&
1008
892
      ParseOneCharToken(state, '_') && ParseType(state)) {
1009
226
    return true;
1010
226
  }
1011
3.76M
  *state = copy;
1012
1013
3.76M
  if (ParseOneCharToken(state, 'A') && Optional(ParseExpression(state)) &&
1014
5.46k
      ParseOneCharToken(state, '_') && ParseType(state)) {
1015
229
    return true;
1016
229
  }
1017
3.76M
  *state = copy;
1018
3.76M
  return false;
1019
3.76M
}
1020
1021
// <pointer-to-member-type> ::= M <(class) type> <(member) type>
1022
3.76M
bool ParsePointerToMemberType(State* state) {
1023
3.76M
  State copy = *state;
1024
3.76M
  if (ParseOneCharToken(state, 'M') && ParseType(state) && ParseType(state)) {
1025
194
    return true;
1026
194
  }
1027
3.76M
  *state = copy;
1028
3.76M
  return false;
1029
3.76M
}
1030
1031
// <template-param> ::= T_
1032
//                  ::= T <parameter-2 non-negative number> _
1033
11.0M
bool ParseTemplateParam(State* state) {
1034
11.0M
  if (ParseTwoCharToken(state, "T_")) {
1035
5.26k
    MaybeAppend(state, "?");  // We don't support template substitutions.
1036
5.26k
    return true;
1037
5.26k
  }
1038
1039
11.0M
  State copy = *state;
1040
11.0M
  if (ParseOneCharToken(state, 'T') && ParseNumber(state, nullptr) &&
1041
760
      ParseOneCharToken(state, '_')) {
1042
389
    MaybeAppend(state, "?");  // We don't support template substitutions.
1043
389
    return true;
1044
389
  }
1045
11.0M
  *state = copy;
1046
11.0M
  return false;
1047
11.0M
}
1048
1049
// <template-template-param> ::= <template-param>
1050
//                           ::= <substitution>
1051
3.76M
bool ParseTemplateTemplateParam(State* state) {
1052
3.76M
  return (ParseTemplateParam(state) || ParseSubstitution(state));
1053
3.76M
}
1054
1055
// <template-args> ::= I <template-arg>+ E
1056
88.2k
bool ParseTemplateArgs(State* state) {
1057
88.2k
  State copy = *state;
1058
88.2k
  DisableAppend(state);
1059
88.2k
  if (ParseOneCharToken(state, 'I') && OneOrMore(ParseTemplateArg, state) &&
1060
11.5k
      ParseOneCharToken(state, 'E')) {
1061
3.70k
    RestoreAppend(state, copy.append);
1062
3.70k
    MaybeAppend(state, "<>");
1063
3.70k
    return true;
1064
3.70k
  }
1065
84.5k
  *state = copy;
1066
84.5k
  return false;
1067
88.2k
}
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.6k
bool ParseTemplateArg(State* state) {
1075
  // Avoid recursion above max_levels
1076
39.6k
  constexpr uint32 max_levels = 6;
1077
1078
39.6k
  if (state->arg_level > max_levels) {
1079
194
    return false;
1080
194
  }
1081
39.5k
  ++state->arg_level;
1082
1083
39.5k
  State copy = *state;
1084
39.5k
  if ((ParseOneCharToken(state, 'I') || ParseOneCharToken(state, 'J')) &&
1085
2.95k
      ZeroOrMore(ParseTemplateArg, state) && ParseOneCharToken(state, 'E')) {
1086
197
    --state->arg_level;
1087
197
    return true;
1088
197
  }
1089
39.3k
  *state = copy;
1090
1091
39.3k
  if (ParseType(state) || ParseExprPrimary(state)) {
1092
13.6k
    --state->arg_level;
1093
13.6k
    return true;
1094
13.6k
  }
1095
25.6k
  *state = copy;
1096
1097
25.6k
  if (ParseOneCharToken(state, 'X') && ParseExpression(state) &&
1098
948
      ParseOneCharToken(state, 'E')) {
1099
196
    --state->arg_level;
1100
196
    return true;
1101
196
  }
1102
25.4k
  *state = copy;
1103
25.4k
  return false;
1104
25.6k
}
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.5k
bool ParseExpression(State* state) {
1116
14.5k
  if (ParseTemplateParam(state) || ParseExprPrimary(state)) {
1117
3.33k
    return true;
1118
3.33k
  }
1119
1120
  // Avoid recursion above max_levels
1121
11.2k
  constexpr uint32 max_levels = 5;
1122
1123
11.2k
  if (state->expr_level > max_levels) {
1124
856
    return false;
1125
856
  }
1126
10.3k
  ++state->expr_level;
1127
1128
10.3k
  State copy = *state;
1129
10.3k
  if (ParseOperatorName(state) && ParseExpression(state) &&
1130
664
      ParseExpression(state) && ParseExpression(state)) {
1131
226
    --state->expr_level;
1132
226
    return true;
1133
226
  }
1134
10.1k
  *state = copy;
1135
1136
10.1k
  if (ParseOperatorName(state) && ParseExpression(state) &&
1137
438
      ParseExpression(state)) {
1138
194
    --state->expr_level;
1139
194
    return true;
1140
194
  }
1141
9.94k
  *state = copy;
1142
1143
9.94k
  if (ParseOperatorName(state) && ParseExpression(state)) {
1144
244
    --state->expr_level;
1145
244
    return true;
1146
244
  }
1147
9.70k
  *state = copy;
1148
1149
9.70k
  if (ParseTwoCharToken(state, "st") && ParseType(state)) {
1150
237
    return true;
1151
0
    --state->expr_level;
1152
0
  }
1153
9.46k
  *state = copy;
1154
1155
9.46k
  if (ParseTwoCharToken(state, "sr") && ParseType(state) &&
1156
646
      ParseUnqualifiedName(state) && ParseTemplateArgs(state)) {
1157
194
    --state->expr_level;
1158
194
    return true;
1159
194
  }
1160
9.27k
  *state = copy;
1161
1162
9.27k
  if (ParseTwoCharToken(state, "sr") && ParseType(state) &&
1163
452
      ParseUnqualifiedName(state)) {
1164
226
    --state->expr_level;
1165
226
    return true;
1166
226
  }
1167
9.04k
  *state = copy;
1168
1169
  // Pack expansion
1170
9.04k
  if (ParseTwoCharToken(state, "sp") && ParseType(state)) {
1171
226
    --state->expr_level;
1172
226
    return true;
1173
226
  }
1174
8.82k
  *state = copy;
1175
1176
8.82k
  return false;
1177
9.04k
}
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.9k
bool ParseExprPrimary(State* state) {
1185
37.9k
  State copy = *state;
1186
37.9k
  if (ParseOneCharToken(state, 'L') && ParseType(state) &&
1187
2.32k
      ParseNumber(state, nullptr) && ParseOneCharToken(state, 'E')) {
1188
271
    return true;
1189
271
  }
1190
37.6k
  *state = copy;
1191
1192
37.6k
  if (ParseOneCharToken(state, 'L') && ParseType(state) &&
1193
2.05k
      ParseFloatNumber(state) && ParseOneCharToken(state, 'E')) {
1194
346
    return true;
1195
346
  }
1196
37.2k
  *state = copy;
1197
1198
37.2k
  if (ParseOneCharToken(state, 'L') && ParseMangledName(state) &&
1199
1.36k
      ParseOneCharToken(state, 'E')) {
1200
203
    return true;
1201
203
  }
1202
37.0k
  *state = copy;
1203
1204
37.0k
  if (ParseTwoCharToken(state, "LZ") && ParseEncoding(state) &&
1205
420
      ParseOneCharToken(state, 'E')) {
1206
208
    return true;
1207
208
  }
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
4.06M
bool ParseLocalName(State* state) {
1217
  // Avoid recursion above max_levels
1218
4.06M
  constexpr uint32 max_levels = 5;
1219
4.06M
  if (state->local_level > max_levels) {
1220
2.27M
    return false;
1221
2.27M
  }
1222
1.79M
  ++state->local_level;
1223
1224
1.79M
  State copy = *state;
1225
1.79M
  if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) &&
1226
21.0k
      ParseOneCharToken(state, 'E') && MaybeAppend(state, "::") &&
1227
5.37k
      ParseName(state) && Optional(ParseDiscriminator(state))) {
1228
2.08k
    --state->local_level;
1229
2.08k
    return true;
1230
2.08k
  }
1231
1.79M
  *state = copy;
1232
1233
1.79M
  if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) &&
1234
18.9k
      ParseTwoCharToken(state, "Es") && Optional(ParseDiscriminator(state))) {
1235
2.45k
    --state->local_level;
1236
2.45k
    return true;
1237
2.45k
  }
1238
1.78M
  *state = copy;
1239
1.78M
  return false;
1240
1.79M
}
1241
1242
// <discriminator> := _ <(non-negative) number>
1243
10.5k
bool ParseDiscriminator(State* state) {
1244
10.5k
  State copy = *state;
1245
10.5k
  if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr)) {
1246
1.72k
    return true;
1247
1.72k
  }
1248
8.83k
  *state = copy;
1249
8.83k
  return false;
1250
10.5k
}
1251
1252
// <substitution> ::= S_
1253
//                ::= S <seq-id> _
1254
//                ::= St, etc.
1255
15.0M
bool ParseSubstitution(State* state) {
1256
15.0M
  if (ParseTwoCharToken(state, "S_")) {
1257
656
    MaybeAppend(state, "?");  // We don't support substitutions.
1258
656
    return true;
1259
656
  }
1260
1261
15.0M
  State copy = *state;
1262
15.0M
  if (ParseOneCharToken(state, 'S') && ParseSeqId(state) &&
1263
862
      ParseOneCharToken(state, '_')) {
1264
415
    MaybeAppend(state, "?");  // We don't support substitutions.
1265
415
    return true;
1266
415
  }
1267
15.0M
  *state = copy;
1268
1269
  // Expand abbreviations like "St" => "std".
1270
15.0M
  if (ParseOneCharToken(state, 'S')) {
1271
13.8k
    const AbbrevPair* p;
1272
49.6k
    for (p = kSubstitutionList; p->abbrev != nullptr; ++p) {
1273
47.0k
      if (state->mangled_cur[0] == p->abbrev[1]) {
1274
11.2k
        MaybeAppend(state, "std");
1275
11.2k
        if (p->real_name[0] != '\0') {
1276
8.52k
          MaybeAppend(state, "::");
1277
8.52k
          MaybeAppend(state, p->real_name);
1278
8.52k
        }
1279
11.2k
        ++state->mangled_cur;
1280
11.2k
        return true;
1281
11.2k
      }
1282
47.0k
    }
1283
13.8k
  }
1284
15.0M
  *state = copy;
1285
15.0M
  return false;
1286
15.0M
}
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.70k
bool ParseTopLevelMangledName(State* state) {
1291
4.70k
  if (ParseMangledName(state)) {
1292
1.91k
    if (state->mangled_cur[0] != '\0') {
1293
      // Drop trailing function clone suffix, if any.
1294
1.43k
      if (IsFunctionCloneSuffix(state->mangled_cur)) {
1295
23
        return true;
1296
23
      }
1297
      // Append trailing version suffix if any.
1298
      // ex. _Z3foo@@GLIBCXX_3.4
1299
1.41k
      if (state->mangled_cur[0] == '@') {
1300
20
        MaybeAppend(state, state->mangled_cur);
1301
20
        return true;
1302
20
      }
1303
1.39k
      return ParseName(state);
1304
1.41k
    }
1305
480
    return true;
1306
1.91k
  }
1307
2.79k
  return false;
1308
4.70k
}
1309
}  // namespace
1310
#endif
1311
1312
// The demangler entry point.
1313
4.70k
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.70k
  State state;
1357
4.70k
  InitState(&state, mangled, out, out_size);
1358
4.70k
  return ParseTopLevelMangledName(&state) && !state.overflowed;
1359
4.70k
#endif
1360
4.70k
}
1361
1362
}  // namespace glog_internal_namespace_
1363
}  // namespace google