Coverage Report

Created: 2026-08-31 06:29

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