00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "absl/debugging/internal/demangle.h"
00021
00022 #include <cstdint>
00023 #include <cstdio>
00024 #include <limits>
00025
00026 namespace absl {
00027 namespace debugging_internal {
00028
00029 typedef struct {
00030 const char *abbrev;
00031 const char *real_name;
00032
00033 int arity;
00034 } AbbrevPair;
00035
00036
00037 static const AbbrevPair kOperatorList[] = {
00038
00039 {"nw", "new", 0},
00040 {"na", "new[]", 0},
00041
00042
00043 {"dl", "delete", 1},
00044 {"da", "delete[]", 1},
00045
00046 {"ps", "+", 1},
00047 {"ng", "-", 1},
00048 {"ad", "&", 1},
00049 {"de", "*", 1},
00050 {"co", "~", 1},
00051
00052 {"pl", "+", 2},
00053 {"mi", "-", 2},
00054 {"ml", "*", 2},
00055 {"dv", "/", 2},
00056 {"rm", "%", 2},
00057 {"an", "&", 2},
00058 {"or", "|", 2},
00059 {"eo", "^", 2},
00060 {"aS", "=", 2},
00061 {"pL", "+=", 2},
00062 {"mI", "-=", 2},
00063 {"mL", "*=", 2},
00064 {"dV", "/=", 2},
00065 {"rM", "%=", 2},
00066 {"aN", "&=", 2},
00067 {"oR", "|=", 2},
00068 {"eO", "^=", 2},
00069 {"ls", "<<", 2},
00070 {"rs", ">>", 2},
00071 {"lS", "<<=", 2},
00072 {"rS", ">>=", 2},
00073 {"eq", "==", 2},
00074 {"ne", "!=", 2},
00075 {"lt", "<", 2},
00076 {"gt", ">", 2},
00077 {"le", "<=", 2},
00078 {"ge", ">=", 2},
00079 {"nt", "!", 1},
00080 {"aa", "&&", 2},
00081 {"oo", "||", 2},
00082 {"pp", "++", 1},
00083 {"mm", "--", 1},
00084 {"cm", ",", 2},
00085 {"pm", "->*", 2},
00086 {"pt", "->", 0},
00087 {"cl", "()", 0},
00088 {"ix", "[]", 2},
00089 {"qu", "?", 3},
00090 {"st", "sizeof", 0},
00091 {"sz", "sizeof", 1},
00092 {nullptr, nullptr, 0},
00093 };
00094
00095
00096 static const AbbrevPair kBuiltinTypeList[] = {
00097 {"v", "void", 0},
00098 {"w", "wchar_t", 0},
00099 {"b", "bool", 0},
00100 {"c", "char", 0},
00101 {"a", "signed char", 0},
00102 {"h", "unsigned char", 0},
00103 {"s", "short", 0},
00104 {"t", "unsigned short", 0},
00105 {"i", "int", 0},
00106 {"j", "unsigned int", 0},
00107 {"l", "long", 0},
00108 {"m", "unsigned long", 0},
00109 {"x", "long long", 0},
00110 {"y", "unsigned long long", 0},
00111 {"n", "__int128", 0},
00112 {"o", "unsigned __int128", 0},
00113 {"f", "float", 0},
00114 {"d", "double", 0},
00115 {"e", "long double", 0},
00116 {"g", "__float128", 0},
00117 {"z", "ellipsis", 0},
00118 {nullptr, nullptr, 0},
00119 };
00120
00121
00122 static const AbbrevPair kSubstitutionList[] = {
00123 {"St", "", 0},
00124 {"Sa", "allocator", 0},
00125 {"Sb", "basic_string", 0},
00126
00127 {"Ss", "string", 0},
00128
00129 {"Si", "istream", 0},
00130
00131 {"So", "ostream", 0},
00132
00133 {"Sd", "iostream", 0},
00134 {nullptr, nullptr, 0},
00135 };
00136
00137
00138
00139 typedef struct {
00140 int mangled_idx;
00141 int out_cur_idx;
00142 int prev_name_idx;
00143 signed int prev_name_length : 16;
00144 signed int nest_level : 15;
00145 unsigned int append : 1;
00146
00147
00148
00149
00150 } ParseState;
00151
00152 static_assert(sizeof(ParseState) == 4 * sizeof(int),
00153 "unexpected size of ParseState");
00154
00155
00156
00157
00158
00159
00160
00161 typedef struct {
00162 const char *mangled_begin;
00163 char *out;
00164 int out_end_idx;
00165 int recursion_depth;
00166 int steps;
00167 ParseState parse_state;
00168 } State;
00169
00170 namespace {
00171
00172
00173 class ComplexityGuard {
00174 public:
00175 explicit ComplexityGuard(State *state) : state_(state) {
00176 ++state->recursion_depth;
00177 ++state->steps;
00178 }
00179 ~ComplexityGuard() { --state_->recursion_depth; }
00180
00181
00182
00183
00184 static constexpr int kRecursionDepthLimit = 256;
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 static constexpr int kParseStepsLimit = 1 << 17;
00201
00202 bool IsTooComplex() const {
00203 return state_->recursion_depth > kRecursionDepthLimit ||
00204 state_->steps > kParseStepsLimit;
00205 }
00206
00207 private:
00208 State *state_;
00209 };
00210 }
00211
00212
00213
00214 static size_t StrLen(const char *str) {
00215 size_t len = 0;
00216 while (*str != '\0') {
00217 ++str;
00218 ++len;
00219 }
00220 return len;
00221 }
00222
00223
00224 static bool AtLeastNumCharsRemaining(const char *str, int n) {
00225 for (int i = 0; i < n; ++i) {
00226 if (str[i] == '\0') {
00227 return false;
00228 }
00229 }
00230 return true;
00231 }
00232
00233
00234 static bool StrPrefix(const char *str, const char *prefix) {
00235 size_t i = 0;
00236 while (str[i] != '\0' && prefix[i] != '\0' && str[i] == prefix[i]) {
00237 ++i;
00238 }
00239 return prefix[i] == '\0';
00240 }
00241
00242 static void InitState(State *state, const char *mangled, char *out,
00243 int out_size) {
00244 state->mangled_begin = mangled;
00245 state->out = out;
00246 state->out_end_idx = out_size;
00247 state->recursion_depth = 0;
00248 state->steps = 0;
00249
00250 state->parse_state.mangled_idx = 0;
00251 state->parse_state.out_cur_idx = 0;
00252 state->parse_state.prev_name_idx = 0;
00253 state->parse_state.prev_name_length = -1;
00254 state->parse_state.nest_level = -1;
00255 state->parse_state.append = true;
00256 }
00257
00258 static inline const char *RemainingInput(State *state) {
00259 return &state->mangled_begin[state->parse_state.mangled_idx];
00260 }
00261
00262
00263
00264
00265 static bool ParseOneCharToken(State *state, const char one_char_token) {
00266 ComplexityGuard guard(state);
00267 if (guard.IsTooComplex()) return false;
00268 if (RemainingInput(state)[0] == one_char_token) {
00269 ++state->parse_state.mangled_idx;
00270 return true;
00271 }
00272 return false;
00273 }
00274
00275
00276
00277
00278 static bool ParseTwoCharToken(State *state, const char *two_char_token) {
00279 ComplexityGuard guard(state);
00280 if (guard.IsTooComplex()) return false;
00281 if (RemainingInput(state)[0] == two_char_token[0] &&
00282 RemainingInput(state)[1] == two_char_token[1]) {
00283 state->parse_state.mangled_idx += 2;
00284 return true;
00285 }
00286 return false;
00287 }
00288
00289
00290
00291 static bool ParseCharClass(State *state, const char *char_class) {
00292 ComplexityGuard guard(state);
00293 if (guard.IsTooComplex()) return false;
00294 if (RemainingInput(state)[0] == '\0') {
00295 return false;
00296 }
00297 const char *p = char_class;
00298 for (; *p != '\0'; ++p) {
00299 if (RemainingInput(state)[0] == *p) {
00300 ++state->parse_state.mangled_idx;
00301 return true;
00302 }
00303 }
00304 return false;
00305 }
00306
00307 static bool ParseDigit(State *state, int *digit) {
00308 char c = RemainingInput(state)[0];
00309 if (ParseCharClass(state, "0123456789")) {
00310 if (digit != nullptr) {
00311 *digit = c - '0';
00312 }
00313 return true;
00314 }
00315 return false;
00316 }
00317
00318
00319 static bool Optional(bool ) { return true; }
00320
00321
00322 typedef bool (*ParseFunc)(State *);
00323 static bool OneOrMore(ParseFunc parse_func, State *state) {
00324 if (parse_func(state)) {
00325 while (parse_func(state)) {
00326 }
00327 return true;
00328 }
00329 return false;
00330 }
00331
00332
00333
00334
00335
00336 static bool ZeroOrMore(ParseFunc parse_func, State *state) {
00337 while (parse_func(state)) {
00338 }
00339 return true;
00340 }
00341
00342
00343
00344
00345 static void Append(State *state, const char *const str, const int length) {
00346 for (int i = 0; i < length; ++i) {
00347 if (state->parse_state.out_cur_idx + 1 <
00348 state->out_end_idx) {
00349 state->out[state->parse_state.out_cur_idx++] = str[i];
00350 } else {
00351
00352 state->parse_state.out_cur_idx = state->out_end_idx + 1;
00353 break;
00354 }
00355 }
00356 if (state->parse_state.out_cur_idx < state->out_end_idx) {
00357 state->out[state->parse_state.out_cur_idx] =
00358 '\0';
00359 }
00360 }
00361
00362
00363 static bool IsLower(char c) { return c >= 'a' && c <= 'z'; }
00364
00365 static bool IsAlpha(char c) {
00366 return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
00367 }
00368
00369 static bool IsDigit(char c) { return c >= '0' && c <= '9'; }
00370
00371
00372
00373
00374
00375 static bool IsFunctionCloneSuffix(const char *str) {
00376 size_t i = 0;
00377 while (str[i] != '\0') {
00378
00379 if (str[i] != '.' || !IsAlpha(str[i + 1])) {
00380 return false;
00381 }
00382 i += 2;
00383 while (IsAlpha(str[i])) {
00384 ++i;
00385 }
00386 if (str[i] != '.' || !IsDigit(str[i + 1])) {
00387 return false;
00388 }
00389 i += 2;
00390 while (IsDigit(str[i])) {
00391 ++i;
00392 }
00393 }
00394 return true;
00395 }
00396
00397 static bool EndsWith(State *state, const char chr) {
00398 return state->parse_state.out_cur_idx > 0 &&
00399 chr == state->out[state->parse_state.out_cur_idx - 1];
00400 }
00401
00402
00403 static void MaybeAppendWithLength(State *state, const char *const str,
00404 const int length) {
00405 if (state->parse_state.append && length > 0) {
00406
00407
00408 if (str[0] == '<' && EndsWith(state, '<')) {
00409 Append(state, " ", 1);
00410 }
00411
00412 if (IsAlpha(str[0]) || str[0] == '_') {
00413 state->parse_state.prev_name_idx = state->parse_state.out_cur_idx;
00414 state->parse_state.prev_name_length = length;
00415 }
00416 Append(state, str, length);
00417 }
00418 }
00419
00420
00421 static bool MaybeAppendDecimal(State *state, unsigned int val) {
00422
00423 constexpr size_t kMaxLength = 20;
00424 char buf[kMaxLength];
00425
00426
00427
00428 if (state->parse_state.append) {
00429
00430
00431 char *p = &buf[kMaxLength];
00432 do {
00433 *--p = (val % 10) + '0';
00434 val /= 10;
00435 } while (p > buf && val != 0);
00436
00437
00438 Append(state, p, kMaxLength - (p - buf));
00439 }
00440
00441 return true;
00442 }
00443
00444
00445
00446 static bool MaybeAppend(State *state, const char *const str) {
00447 if (state->parse_state.append) {
00448 int length = StrLen(str);
00449 MaybeAppendWithLength(state, str, length);
00450 }
00451 return true;
00452 }
00453
00454
00455 static bool EnterNestedName(State *state) {
00456 state->parse_state.nest_level = 0;
00457 return true;
00458 }
00459
00460
00461 static bool LeaveNestedName(State *state, int16_t prev_value) {
00462 state->parse_state.nest_level = prev_value;
00463 return true;
00464 }
00465
00466
00467 static bool DisableAppend(State *state) {
00468 state->parse_state.append = false;
00469 return true;
00470 }
00471
00472
00473 static bool RestoreAppend(State *state, bool prev_value) {
00474 state->parse_state.append = prev_value;
00475 return true;
00476 }
00477
00478
00479 static void MaybeIncreaseNestLevel(State *state) {
00480 if (state->parse_state.nest_level > -1) {
00481 ++state->parse_state.nest_level;
00482 }
00483 }
00484
00485
00486 static void MaybeAppendSeparator(State *state) {
00487 if (state->parse_state.nest_level >= 1) {
00488 MaybeAppend(state, "::");
00489 }
00490 }
00491
00492
00493 static void MaybeCancelLastSeparator(State *state) {
00494 if (state->parse_state.nest_level >= 1 && state->parse_state.append &&
00495 state->parse_state.out_cur_idx >= 2) {
00496 state->parse_state.out_cur_idx -= 2;
00497 state->out[state->parse_state.out_cur_idx] = '\0';
00498 }
00499 }
00500
00501
00502
00503 static bool IdentifierIsAnonymousNamespace(State *state, int length) {
00504
00505 static const char anon_prefix[] = "_GLOBAL__N_";
00506 return (length > static_cast<int>(sizeof(anon_prefix) - 1) &&
00507 StrPrefix(RemainingInput(state), anon_prefix));
00508 }
00509
00510
00511 static bool ParseMangledName(State *state);
00512 static bool ParseEncoding(State *state);
00513 static bool ParseName(State *state);
00514 static bool ParseUnscopedName(State *state);
00515 static bool ParseNestedName(State *state);
00516 static bool ParsePrefix(State *state);
00517 static bool ParseUnqualifiedName(State *state);
00518 static bool ParseSourceName(State *state);
00519 static bool ParseLocalSourceName(State *state);
00520 static bool ParseUnnamedTypeName(State *state);
00521 static bool ParseNumber(State *state, int *number_out);
00522 static bool ParseFloatNumber(State *state);
00523 static bool ParseSeqId(State *state);
00524 static bool ParseIdentifier(State *state, int length);
00525 static bool ParseOperatorName(State *state, int *arity);
00526 static bool ParseSpecialName(State *state);
00527 static bool ParseCallOffset(State *state);
00528 static bool ParseNVOffset(State *state);
00529 static bool ParseVOffset(State *state);
00530 static bool ParseCtorDtorName(State *state);
00531 static bool ParseDecltype(State *state);
00532 static bool ParseType(State *state);
00533 static bool ParseCVQualifiers(State *state);
00534 static bool ParseBuiltinType(State *state);
00535 static bool ParseFunctionType(State *state);
00536 static bool ParseBareFunctionType(State *state);
00537 static bool ParseClassEnumType(State *state);
00538 static bool ParseArrayType(State *state);
00539 static bool ParsePointerToMemberType(State *state);
00540 static bool ParseTemplateParam(State *state);
00541 static bool ParseTemplateTemplateParam(State *state);
00542 static bool ParseTemplateArgs(State *state);
00543 static bool ParseTemplateArg(State *state);
00544 static bool ParseBaseUnresolvedName(State *state);
00545 static bool ParseUnresolvedName(State *state);
00546 static bool ParseExpression(State *state);
00547 static bool ParseExprPrimary(State *state);
00548 static bool ParseExprCastValue(State *state);
00549 static bool ParseLocalName(State *state);
00550 static bool ParseLocalNameSuffix(State *state);
00551 static bool ParseDiscriminator(State *state);
00552 static bool ParseSubstitution(State *state, bool accept_std);
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586 static bool ParseMangledName(State *state) {
00587 ComplexityGuard guard(state);
00588 if (guard.IsTooComplex()) return false;
00589 return ParseTwoCharToken(state, "_Z") && ParseEncoding(state);
00590 }
00591
00592
00593
00594
00595 static bool ParseEncoding(State *state) {
00596 ComplexityGuard guard(state);
00597 if (guard.IsTooComplex()) return false;
00598
00599
00600
00601
00602
00603 if (ParseName(state) && Optional(ParseBareFunctionType(state))) {
00604 return true;
00605 }
00606
00607 if (ParseSpecialName(state)) {
00608 return true;
00609 }
00610 return false;
00611 }
00612
00613
00614
00615
00616
00617 static bool ParseName(State *state) {
00618 ComplexityGuard guard(state);
00619 if (guard.IsTooComplex()) return false;
00620 if (ParseNestedName(state) || ParseLocalName(state)) {
00621 return true;
00622 }
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 ParseState copy = state->parse_state;
00633
00634 if (ParseSubstitution(state, false) &&
00635 ParseTemplateArgs(state)) {
00636 return true;
00637 }
00638 state->parse_state = copy;
00639
00640
00641
00642 return ParseUnscopedName(state) && Optional(ParseTemplateArgs(state));
00643 }
00644
00645
00646
00647 static bool ParseUnscopedName(State *state) {
00648 ComplexityGuard guard(state);
00649 if (guard.IsTooComplex()) return false;
00650 if (ParseUnqualifiedName(state)) {
00651 return true;
00652 }
00653
00654 ParseState copy = state->parse_state;
00655 if (ParseTwoCharToken(state, "St") && MaybeAppend(state, "std::") &&
00656 ParseUnqualifiedName(state)) {
00657 return true;
00658 }
00659 state->parse_state = copy;
00660 return false;
00661 }
00662
00663
00664
00665 static inline bool ParseRefQualifier(State *state) {
00666 return ParseCharClass(state, "OR");
00667 }
00668
00669
00670
00671
00672
00673 static bool ParseNestedName(State *state) {
00674 ComplexityGuard guard(state);
00675 if (guard.IsTooComplex()) return false;
00676 ParseState copy = state->parse_state;
00677 if (ParseOneCharToken(state, 'N') && EnterNestedName(state) &&
00678 Optional(ParseCVQualifiers(state)) &&
00679 Optional(ParseRefQualifier(state)) && ParsePrefix(state) &&
00680 LeaveNestedName(state, copy.nest_level) &&
00681 ParseOneCharToken(state, 'E')) {
00682 return true;
00683 }
00684 state->parse_state = copy;
00685 return false;
00686 }
00687
00688
00689
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699 static bool ParsePrefix(State *state) {
00700 ComplexityGuard guard(state);
00701 if (guard.IsTooComplex()) return false;
00702 bool has_something = false;
00703 while (true) {
00704 MaybeAppendSeparator(state);
00705 if (ParseTemplateParam(state) ||
00706 ParseSubstitution(state, true) ||
00707 ParseUnscopedName(state) ||
00708 (ParseOneCharToken(state, 'M') && ParseUnnamedTypeName(state))) {
00709 has_something = true;
00710 MaybeIncreaseNestLevel(state);
00711 continue;
00712 }
00713 MaybeCancelLastSeparator(state);
00714 if (has_something && ParseTemplateArgs(state)) {
00715 return ParsePrefix(state);
00716 } else {
00717 break;
00718 }
00719 }
00720 return true;
00721 }
00722
00723
00724
00725
00726
00727
00728 static bool ParseUnqualifiedName(State *state) {
00729 ComplexityGuard guard(state);
00730 if (guard.IsTooComplex()) return false;
00731 return (ParseOperatorName(state, nullptr) || ParseCtorDtorName(state) ||
00732 ParseSourceName(state) || ParseLocalSourceName(state) ||
00733 ParseUnnamedTypeName(state));
00734 }
00735
00736
00737 static bool ParseSourceName(State *state) {
00738 ComplexityGuard guard(state);
00739 if (guard.IsTooComplex()) return false;
00740 ParseState copy = state->parse_state;
00741 int length = -1;
00742 if (ParseNumber(state, &length) && ParseIdentifier(state, length)) {
00743 return true;
00744 }
00745 state->parse_state = copy;
00746 return false;
00747 }
00748
00749
00750
00751
00752
00753
00754 static bool ParseLocalSourceName(State *state) {
00755 ComplexityGuard guard(state);
00756 if (guard.IsTooComplex()) return false;
00757 ParseState copy = state->parse_state;
00758 if (ParseOneCharToken(state, 'L') && ParseSourceName(state) &&
00759 Optional(ParseDiscriminator(state))) {
00760 return true;
00761 }
00762 state->parse_state = copy;
00763 return false;
00764 }
00765
00766
00767
00768
00769
00770 static bool ParseUnnamedTypeName(State *state) {
00771 ComplexityGuard guard(state);
00772 if (guard.IsTooComplex()) return false;
00773 ParseState copy = state->parse_state;
00774
00775
00776 int which = -1;
00777
00778
00779 if (ParseTwoCharToken(state, "Ut") && Optional(ParseNumber(state, &which)) &&
00780 which <= std::numeric_limits<int>::max() - 2 &&
00781 ParseOneCharToken(state, '_')) {
00782 MaybeAppend(state, "{unnamed type#");
00783 MaybeAppendDecimal(state, 2 + which);
00784 MaybeAppend(state, "}");
00785 return true;
00786 }
00787 state->parse_state = copy;
00788
00789
00790 which = -1;
00791 if (ParseTwoCharToken(state, "Ul") && DisableAppend(state) &&
00792 OneOrMore(ParseType, state) && RestoreAppend(state, copy.append) &&
00793 ParseOneCharToken(state, 'E') && Optional(ParseNumber(state, &which)) &&
00794 which <= std::numeric_limits<int>::max() - 2 &&
00795 ParseOneCharToken(state, '_')) {
00796 MaybeAppend(state, "{lambda()#");
00797 MaybeAppendDecimal(state, 2 + which);
00798 MaybeAppend(state, "}");
00799 return true;
00800 }
00801 state->parse_state = copy;
00802
00803 return false;
00804 }
00805
00806
00807
00808
00809 static bool ParseNumber(State *state, int *number_out) {
00810 ComplexityGuard guard(state);
00811 if (guard.IsTooComplex()) return false;
00812 bool negative = false;
00813 if (ParseOneCharToken(state, 'n')) {
00814 negative = true;
00815 }
00816 const char *p = RemainingInput(state);
00817 uint64_t number = 0;
00818 for (; *p != '\0'; ++p) {
00819 if (IsDigit(*p)) {
00820 number = number * 10 + (*p - '0');
00821 } else {
00822 break;
00823 }
00824 }
00825
00826
00827
00828 if (negative) {
00829 number = ~number + 1;
00830 }
00831 if (p != RemainingInput(state)) {
00832 state->parse_state.mangled_idx += p - RemainingInput(state);
00833 if (number_out != nullptr) {
00834
00835 *number_out = number;
00836 }
00837 return true;
00838 }
00839 return false;
00840 }
00841
00842
00843
00844 static bool ParseFloatNumber(State *state) {
00845 ComplexityGuard guard(state);
00846 if (guard.IsTooComplex()) return false;
00847 const char *p = RemainingInput(state);
00848 for (; *p != '\0'; ++p) {
00849 if (!IsDigit(*p) && !(*p >= 'a' && *p <= 'f')) {
00850 break;
00851 }
00852 }
00853 if (p != RemainingInput(state)) {
00854 state->parse_state.mangled_idx += p - RemainingInput(state);
00855 return true;
00856 }
00857 return false;
00858 }
00859
00860
00861
00862 static bool ParseSeqId(State *state) {
00863 ComplexityGuard guard(state);
00864 if (guard.IsTooComplex()) return false;
00865 const char *p = RemainingInput(state);
00866 for (; *p != '\0'; ++p) {
00867 if (!IsDigit(*p) && !(*p >= 'A' && *p <= 'Z')) {
00868 break;
00869 }
00870 }
00871 if (p != RemainingInput(state)) {
00872 state->parse_state.mangled_idx += p - RemainingInput(state);
00873 return true;
00874 }
00875 return false;
00876 }
00877
00878
00879 static bool ParseIdentifier(State *state, int length) {
00880 ComplexityGuard guard(state);
00881 if (guard.IsTooComplex()) return false;
00882 if (length < 0 || !AtLeastNumCharsRemaining(RemainingInput(state), length)) {
00883 return false;
00884 }
00885 if (IdentifierIsAnonymousNamespace(state, length)) {
00886 MaybeAppend(state, "(anonymous namespace)");
00887 } else {
00888 MaybeAppendWithLength(state, RemainingInput(state), length);
00889 }
00890 state->parse_state.mangled_idx += length;
00891 return true;
00892 }
00893
00894
00895
00896
00897 static bool ParseOperatorName(State *state, int *arity) {
00898 ComplexityGuard guard(state);
00899 if (guard.IsTooComplex()) return false;
00900 if (!AtLeastNumCharsRemaining(RemainingInput(state), 2)) {
00901 return false;
00902 }
00903
00904 ParseState copy = state->parse_state;
00905 if (ParseTwoCharToken(state, "cv") && MaybeAppend(state, "operator ") &&
00906 EnterNestedName(state) && ParseType(state) &&
00907 LeaveNestedName(state, copy.nest_level)) {
00908 if (arity != nullptr) {
00909 *arity = 1;
00910 }
00911 return true;
00912 }
00913 state->parse_state = copy;
00914
00915
00916 if (ParseOneCharToken(state, 'v') && ParseDigit(state, arity) &&
00917 ParseSourceName(state)) {
00918 return true;
00919 }
00920 state->parse_state = copy;
00921
00922
00923
00924 if (!(IsLower(RemainingInput(state)[0]) &&
00925 IsAlpha(RemainingInput(state)[1]))) {
00926 return false;
00927 }
00928
00929 const AbbrevPair *p;
00930 for (p = kOperatorList; p->abbrev != nullptr; ++p) {
00931 if (RemainingInput(state)[0] == p->abbrev[0] &&
00932 RemainingInput(state)[1] == p->abbrev[1]) {
00933 if (arity != nullptr) {
00934 *arity = p->arity;
00935 }
00936 MaybeAppend(state, "operator");
00937 if (IsLower(*p->real_name)) {
00938 MaybeAppend(state, " ");
00939 }
00940 MaybeAppend(state, p->real_name);
00941 state->parse_state.mangled_idx += 2;
00942 return true;
00943 }
00944 }
00945 return false;
00946 }
00947
00948
00949
00950
00951
00952
00953
00954
00955
00956
00957
00958
00959
00960
00961
00962
00963
00964
00965
00966 static bool ParseSpecialName(State *state) {
00967 ComplexityGuard guard(state);
00968 if (guard.IsTooComplex()) return false;
00969 ParseState copy = state->parse_state;
00970 if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "VTIS") &&
00971 ParseType(state)) {
00972 return true;
00973 }
00974 state->parse_state = copy;
00975
00976 if (ParseTwoCharToken(state, "Tc") && ParseCallOffset(state) &&
00977 ParseCallOffset(state) && ParseEncoding(state)) {
00978 return true;
00979 }
00980 state->parse_state = copy;
00981
00982 if (ParseTwoCharToken(state, "GV") && ParseName(state)) {
00983 return true;
00984 }
00985 state->parse_state = copy;
00986
00987 if (ParseOneCharToken(state, 'T') && ParseCallOffset(state) &&
00988 ParseEncoding(state)) {
00989 return true;
00990 }
00991 state->parse_state = copy;
00992
00993
00994 if (ParseTwoCharToken(state, "TC") && ParseType(state) &&
00995 ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') &&
00996 DisableAppend(state) && ParseType(state)) {
00997 RestoreAppend(state, copy.append);
00998 return true;
00999 }
01000 state->parse_state = copy;
01001
01002 if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "FJ") &&
01003 ParseType(state)) {
01004 return true;
01005 }
01006 state->parse_state = copy;
01007
01008 if (ParseTwoCharToken(state, "GR") && ParseName(state)) {
01009 return true;
01010 }
01011 state->parse_state = copy;
01012
01013 if (ParseTwoCharToken(state, "GA") && ParseEncoding(state)) {
01014 return true;
01015 }
01016 state->parse_state = copy;
01017
01018 if (ParseOneCharToken(state, 'T') && ParseCharClass(state, "hv") &&
01019 ParseCallOffset(state) && ParseEncoding(state)) {
01020 return true;
01021 }
01022 state->parse_state = copy;
01023 return false;
01024 }
01025
01026
01027
01028 static bool ParseCallOffset(State *state) {
01029 ComplexityGuard guard(state);
01030 if (guard.IsTooComplex()) return false;
01031 ParseState copy = state->parse_state;
01032 if (ParseOneCharToken(state, 'h') && ParseNVOffset(state) &&
01033 ParseOneCharToken(state, '_')) {
01034 return true;
01035 }
01036 state->parse_state = copy;
01037
01038 if (ParseOneCharToken(state, 'v') && ParseVOffset(state) &&
01039 ParseOneCharToken(state, '_')) {
01040 return true;
01041 }
01042 state->parse_state = copy;
01043
01044 return false;
01045 }
01046
01047
01048 static bool ParseNVOffset(State *state) {
01049 ComplexityGuard guard(state);
01050 if (guard.IsTooComplex()) return false;
01051 return ParseNumber(state, nullptr);
01052 }
01053
01054
01055 static bool ParseVOffset(State *state) {
01056 ComplexityGuard guard(state);
01057 if (guard.IsTooComplex()) return false;
01058 ParseState copy = state->parse_state;
01059 if (ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') &&
01060 ParseNumber(state, nullptr)) {
01061 return true;
01062 }
01063 state->parse_state = copy;
01064 return false;
01065 }
01066
01067
01068
01069
01070
01071
01072 static bool ParseCtorDtorName(State *state) {
01073 ComplexityGuard guard(state);
01074 if (guard.IsTooComplex()) return false;
01075 ParseState copy = state->parse_state;
01076 if (ParseOneCharToken(state, 'C') && ParseCharClass(state, "1234")) {
01077 const char *const prev_name = state->out + state->parse_state.prev_name_idx;
01078 MaybeAppendWithLength(state, prev_name,
01079 state->parse_state.prev_name_length);
01080 return true;
01081 }
01082 state->parse_state = copy;
01083
01084 if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "0124")) {
01085 const char *const prev_name = state->out + state->parse_state.prev_name_idx;
01086 MaybeAppend(state, "~");
01087 MaybeAppendWithLength(state, prev_name,
01088 state->parse_state.prev_name_length);
01089 return true;
01090 }
01091 state->parse_state = copy;
01092 return false;
01093 }
01094
01095
01096
01097
01098 static bool ParseDecltype(State *state) {
01099 ComplexityGuard guard(state);
01100 if (guard.IsTooComplex()) return false;
01101
01102 ParseState copy = state->parse_state;
01103 if (ParseOneCharToken(state, 'D') && ParseCharClass(state, "tT") &&
01104 ParseExpression(state) && ParseOneCharToken(state, 'E')) {
01105 return true;
01106 }
01107 state->parse_state = copy;
01108
01109 return false;
01110 }
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130 static bool ParseType(State *state) {
01131 ComplexityGuard guard(state);
01132 if (guard.IsTooComplex()) return false;
01133 ParseState copy = state->parse_state;
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148 if (ParseCVQualifiers(state)) {
01149 const bool result = ParseType(state);
01150 if (!result) state->parse_state = copy;
01151 return result;
01152 }
01153 state->parse_state = copy;
01154
01155
01156
01157
01158
01159 if (ParseCharClass(state, "OPRCG")) {
01160 const bool result = ParseType(state);
01161 if (!result) state->parse_state = copy;
01162 return result;
01163 }
01164 state->parse_state = copy;
01165
01166 if (ParseTwoCharToken(state, "Dp") && ParseType(state)) {
01167 return true;
01168 }
01169 state->parse_state = copy;
01170
01171
01172 if (ParseTwoCharToken(state, "Dn")) {
01173 return true;
01174 }
01175 state->parse_state = copy;
01176
01177 if (ParseOneCharToken(state, 'U') && ParseSourceName(state) &&
01178 ParseType(state)) {
01179 return true;
01180 }
01181 state->parse_state = copy;
01182
01183 if (ParseBuiltinType(state) || ParseFunctionType(state) ||
01184 ParseClassEnumType(state) || ParseArrayType(state) ||
01185 ParsePointerToMemberType(state) || ParseDecltype(state) ||
01186
01187 ParseSubstitution(state, false)) {
01188 return true;
01189 }
01190
01191 if (ParseTemplateTemplateParam(state) && ParseTemplateArgs(state)) {
01192 return true;
01193 }
01194 state->parse_state = copy;
01195
01196
01197 if (ParseTemplateParam(state)) {
01198 return true;
01199 }
01200
01201 return false;
01202 }
01203
01204
01205
01206
01207 static bool ParseCVQualifiers(State *state) {
01208 ComplexityGuard guard(state);
01209 if (guard.IsTooComplex()) return false;
01210 int num_cv_qualifiers = 0;
01211 num_cv_qualifiers += ParseOneCharToken(state, 'r');
01212 num_cv_qualifiers += ParseOneCharToken(state, 'V');
01213 num_cv_qualifiers += ParseOneCharToken(state, 'K');
01214 return num_cv_qualifiers > 0;
01215 }
01216
01217
01218
01219 static bool ParseBuiltinType(State *state) {
01220 ComplexityGuard guard(state);
01221 if (guard.IsTooComplex()) return false;
01222 const AbbrevPair *p;
01223 for (p = kBuiltinTypeList; p->abbrev != nullptr; ++p) {
01224 if (RemainingInput(state)[0] == p->abbrev[0]) {
01225 MaybeAppend(state, p->real_name);
01226 ++state->parse_state.mangled_idx;
01227 return true;
01228 }
01229 }
01230
01231 ParseState copy = state->parse_state;
01232 if (ParseOneCharToken(state, 'u') && ParseSourceName(state)) {
01233 return true;
01234 }
01235 state->parse_state = copy;
01236 return false;
01237 }
01238
01239
01240 static bool ParseFunctionType(State *state) {
01241 ComplexityGuard guard(state);
01242 if (guard.IsTooComplex()) return false;
01243 ParseState copy = state->parse_state;
01244 if (ParseOneCharToken(state, 'F') &&
01245 Optional(ParseOneCharToken(state, 'Y')) && ParseBareFunctionType(state) &&
01246 ParseOneCharToken(state, 'E')) {
01247 return true;
01248 }
01249 state->parse_state = copy;
01250 return false;
01251 }
01252
01253
01254 static bool ParseBareFunctionType(State *state) {
01255 ComplexityGuard guard(state);
01256 if (guard.IsTooComplex()) return false;
01257 ParseState copy = state->parse_state;
01258 DisableAppend(state);
01259 if (OneOrMore(ParseType, state)) {
01260 RestoreAppend(state, copy.append);
01261 MaybeAppend(state, "()");
01262 return true;
01263 }
01264 state->parse_state = copy;
01265 return false;
01266 }
01267
01268
01269 static bool ParseClassEnumType(State *state) {
01270 ComplexityGuard guard(state);
01271 if (guard.IsTooComplex()) return false;
01272 return ParseName(state);
01273 }
01274
01275
01276
01277 static bool ParseArrayType(State *state) {
01278 ComplexityGuard guard(state);
01279 if (guard.IsTooComplex()) return false;
01280 ParseState copy = state->parse_state;
01281 if (ParseOneCharToken(state, 'A') && ParseNumber(state, nullptr) &&
01282 ParseOneCharToken(state, '_') && ParseType(state)) {
01283 return true;
01284 }
01285 state->parse_state = copy;
01286
01287 if (ParseOneCharToken(state, 'A') && Optional(ParseExpression(state)) &&
01288 ParseOneCharToken(state, '_') && ParseType(state)) {
01289 return true;
01290 }
01291 state->parse_state = copy;
01292 return false;
01293 }
01294
01295
01296 static bool ParsePointerToMemberType(State *state) {
01297 ComplexityGuard guard(state);
01298 if (guard.IsTooComplex()) return false;
01299 ParseState copy = state->parse_state;
01300 if (ParseOneCharToken(state, 'M') && ParseType(state) && ParseType(state)) {
01301 return true;
01302 }
01303 state->parse_state = copy;
01304 return false;
01305 }
01306
01307
01308
01309 static bool ParseTemplateParam(State *state) {
01310 ComplexityGuard guard(state);
01311 if (guard.IsTooComplex()) return false;
01312 if (ParseTwoCharToken(state, "T_")) {
01313 MaybeAppend(state, "?");
01314 return true;
01315 }
01316
01317 ParseState copy = state->parse_state;
01318 if (ParseOneCharToken(state, 'T') && ParseNumber(state, nullptr) &&
01319 ParseOneCharToken(state, '_')) {
01320 MaybeAppend(state, "?");
01321 return true;
01322 }
01323 state->parse_state = copy;
01324 return false;
01325 }
01326
01327
01328
01329 static bool ParseTemplateTemplateParam(State *state) {
01330 ComplexityGuard guard(state);
01331 if (guard.IsTooComplex()) return false;
01332 return (ParseTemplateParam(state) ||
01333
01334 ParseSubstitution(state, false));
01335 }
01336
01337
01338 static bool ParseTemplateArgs(State *state) {
01339 ComplexityGuard guard(state);
01340 if (guard.IsTooComplex()) return false;
01341 ParseState copy = state->parse_state;
01342 DisableAppend(state);
01343 if (ParseOneCharToken(state, 'I') && OneOrMore(ParseTemplateArg, state) &&
01344 ParseOneCharToken(state, 'E')) {
01345 RestoreAppend(state, copy.append);
01346 MaybeAppend(state, "<>");
01347 return true;
01348 }
01349 state->parse_state = copy;
01350 return false;
01351 }
01352
01353
01354
01355
01356
01357 static bool ParseTemplateArg(State *state) {
01358 ComplexityGuard guard(state);
01359 if (guard.IsTooComplex()) return false;
01360 ParseState copy = state->parse_state;
01361 if (ParseOneCharToken(state, 'J') && ZeroOrMore(ParseTemplateArg, state) &&
01362 ParseOneCharToken(state, 'E')) {
01363 return true;
01364 }
01365 state->parse_state = copy;
01366
01367
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
01411
01412
01413
01414
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430
01431
01432
01433
01434
01435 if (ParseLocalSourceName(state) && Optional(ParseTemplateArgs(state))) {
01436 copy = state->parse_state;
01437 if (ParseExprCastValue(state) && ParseOneCharToken(state, 'E')) {
01438 return true;
01439 }
01440 state->parse_state = copy;
01441 return true;
01442 }
01443
01444
01445
01446 if (ParseType(state) || ParseExprPrimary(state)) {
01447 return true;
01448 }
01449 state->parse_state = copy;
01450
01451 if (ParseOneCharToken(state, 'X') && ParseExpression(state) &&
01452 ParseOneCharToken(state, 'E')) {
01453 return true;
01454 }
01455 state->parse_state = copy;
01456 return false;
01457 }
01458
01459
01460
01461
01462 static inline bool ParseUnresolvedType(State *state) {
01463
01464 return (ParseTemplateParam(state) && Optional(ParseTemplateArgs(state))) ||
01465 ParseDecltype(state) || ParseSubstitution(state, false);
01466 }
01467
01468
01469 static inline bool ParseSimpleId(State *state) {
01470
01471
01472
01473
01474 return ParseSourceName(state) && Optional(ParseTemplateArgs(state));
01475 }
01476
01477
01478
01479
01480 static bool ParseBaseUnresolvedName(State *state) {
01481 ComplexityGuard guard(state);
01482 if (guard.IsTooComplex()) return false;
01483
01484 if (ParseSimpleId(state)) {
01485 return true;
01486 }
01487
01488 ParseState copy = state->parse_state;
01489 if (ParseTwoCharToken(state, "on") && ParseOperatorName(state, nullptr) &&
01490 Optional(ParseTemplateArgs(state))) {
01491 return true;
01492 }
01493 state->parse_state = copy;
01494
01495 if (ParseTwoCharToken(state, "dn") &&
01496 (ParseUnresolvedType(state) || ParseSimpleId(state))) {
01497 return true;
01498 }
01499 state->parse_state = copy;
01500
01501 return false;
01502 }
01503
01504
01505
01506
01507
01508
01509
01510 static bool ParseUnresolvedName(State *state) {
01511 ComplexityGuard guard(state);
01512 if (guard.IsTooComplex()) return false;
01513
01514 ParseState copy = state->parse_state;
01515 if (Optional(ParseTwoCharToken(state, "gs")) &&
01516 ParseBaseUnresolvedName(state)) {
01517 return true;
01518 }
01519 state->parse_state = copy;
01520
01521 if (ParseTwoCharToken(state, "sr") && ParseUnresolvedType(state) &&
01522 ParseBaseUnresolvedName(state)) {
01523 return true;
01524 }
01525 state->parse_state = copy;
01526
01527 if (ParseTwoCharToken(state, "sr") && ParseOneCharToken(state, 'N') &&
01528 ParseUnresolvedType(state) &&
01529 OneOrMore( ParseSimpleId, state) &&
01530 ParseOneCharToken(state, 'E') && ParseBaseUnresolvedName(state)) {
01531 return true;
01532 }
01533 state->parse_state = copy;
01534
01535 if (Optional(ParseTwoCharToken(state, "gs")) &&
01536 ParseTwoCharToken(state, "sr") &&
01537 OneOrMore( ParseSimpleId, state) &&
01538 ParseOneCharToken(state, 'E') && ParseBaseUnresolvedName(state)) {
01539 return true;
01540 }
01541 state->parse_state = copy;
01542
01543 return false;
01544 }
01545
01546
01547
01548
01549
01550
01551
01552
01553
01554
01555
01556
01557
01558
01559
01560
01561
01562
01563
01564
01565 static bool ParseExpression(State *state) {
01566 ComplexityGuard guard(state);
01567 if (guard.IsTooComplex()) return false;
01568 if (ParseTemplateParam(state) || ParseExprPrimary(state)) {
01569 return true;
01570 }
01571
01572
01573 ParseState copy = state->parse_state;
01574 if (ParseTwoCharToken(state, "cl") && OneOrMore(ParseExpression, state) &&
01575 ParseOneCharToken(state, 'E')) {
01576 return true;
01577 }
01578 state->parse_state = copy;
01579
01580
01581 if (ParseTwoCharToken(state, "fp") && Optional(ParseCVQualifiers(state)) &&
01582 Optional(ParseNumber(state, nullptr)) && ParseOneCharToken(state, '_')) {
01583 return true;
01584 }
01585 state->parse_state = copy;
01586
01587
01588 if (ParseTwoCharToken(state, "fL") && Optional(ParseNumber(state, nullptr)) &&
01589 ParseOneCharToken(state, 'p') && Optional(ParseCVQualifiers(state)) &&
01590 Optional(ParseNumber(state, nullptr)) && ParseOneCharToken(state, '_')) {
01591 return true;
01592 }
01593 state->parse_state = copy;
01594
01595
01596
01597
01598
01599
01600
01601
01602
01603 if (ParseTwoCharToken(state, "cv")) {
01604 if (ParseType(state)) {
01605 ParseState copy2 = state->parse_state;
01606 if (ParseOneCharToken(state, '_') && ZeroOrMore(ParseExpression, state) &&
01607 ParseOneCharToken(state, 'E')) {
01608 return true;
01609 }
01610 state->parse_state = copy2;
01611 if (ParseExpression(state)) {
01612 return true;
01613 }
01614 }
01615 } else {
01616
01617
01618
01619
01620
01621 int arity = -1;
01622 if (ParseOperatorName(state, &arity) &&
01623 arity > 0 &&
01624 (arity < 3 || ParseExpression(state)) &&
01625 (arity < 2 || ParseExpression(state)) &&
01626 (arity < 1 || ParseExpression(state))) {
01627 return true;
01628 }
01629 }
01630 state->parse_state = copy;
01631
01632
01633 if (ParseTwoCharToken(state, "st") && ParseType(state)) {
01634 return true;
01635 }
01636 state->parse_state = copy;
01637
01638
01639 if ((ParseTwoCharToken(state, "dt") || ParseTwoCharToken(state, "pt")) &&
01640 ParseExpression(state) && ParseType(state)) {
01641 return true;
01642 }
01643 state->parse_state = copy;
01644
01645
01646
01647
01648 if (ParseTwoCharToken(state, "ds") && ParseExpression(state) &&
01649 ParseExpression(state)) {
01650 return true;
01651 }
01652 state->parse_state = copy;
01653
01654
01655 if (ParseTwoCharToken(state, "sp") && ParseExpression(state)) {
01656 return true;
01657 }
01658 state->parse_state = copy;
01659
01660 return ParseUnresolvedName(state);
01661 }
01662
01663
01664
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679
01680
01681
01682
01683
01684
01685
01686
01687
01688
01689 static bool ParseExprPrimary(State *state) {
01690 ComplexityGuard guard(state);
01691 if (guard.IsTooComplex()) return false;
01692 ParseState copy = state->parse_state;
01693
01694
01695
01696 if (ParseTwoCharToken(state, "LZ")) {
01697 if (ParseEncoding(state) && ParseOneCharToken(state, 'E')) {
01698 return true;
01699 }
01700
01701 state->parse_state = copy;
01702 return false;
01703 }
01704
01705
01706 if (ParseOneCharToken(state, 'L') && ParseType(state) &&
01707 ParseExprCastValue(state)) {
01708 return true;
01709 }
01710 state->parse_state = copy;
01711
01712 if (ParseOneCharToken(state, 'L') && ParseMangledName(state) &&
01713 ParseOneCharToken(state, 'E')) {
01714 return true;
01715 }
01716 state->parse_state = copy;
01717
01718 return false;
01719 }
01720
01721
01722 static bool ParseExprCastValue(State *state) {
01723 ComplexityGuard guard(state);
01724 if (guard.IsTooComplex()) return false;
01725
01726
01727
01728 ParseState copy = state->parse_state;
01729 if (ParseNumber(state, nullptr) && ParseOneCharToken(state, 'E')) {
01730 return true;
01731 }
01732 state->parse_state = copy;
01733
01734 if (ParseFloatNumber(state) && ParseOneCharToken(state, 'E')) {
01735 return true;
01736 }
01737 state->parse_state = copy;
01738
01739 return false;
01740 }
01741
01742
01743
01744
01745
01746
01747
01748
01749
01750
01751 static bool ParseLocalNameSuffix(State *state) {
01752 ComplexityGuard guard(state);
01753 if (guard.IsTooComplex()) return false;
01754
01755 if (MaybeAppend(state, "::") && ParseName(state) &&
01756 Optional(ParseDiscriminator(state))) {
01757 return true;
01758 }
01759
01760
01761
01762
01763 if (state->parse_state.append) {
01764 state->out[state->parse_state.out_cur_idx - 2] = '\0';
01765 }
01766
01767 return ParseOneCharToken(state, 's') && Optional(ParseDiscriminator(state));
01768 }
01769
01770 static bool ParseLocalName(State *state) {
01771 ComplexityGuard guard(state);
01772 if (guard.IsTooComplex()) return false;
01773 ParseState copy = state->parse_state;
01774 if (ParseOneCharToken(state, 'Z') && ParseEncoding(state) &&
01775 ParseOneCharToken(state, 'E') && ParseLocalNameSuffix(state)) {
01776 return true;
01777 }
01778 state->parse_state = copy;
01779 return false;
01780 }
01781
01782
01783 static bool ParseDiscriminator(State *state) {
01784 ComplexityGuard guard(state);
01785 if (guard.IsTooComplex()) return false;
01786 ParseState copy = state->parse_state;
01787 if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr)) {
01788 return true;
01789 }
01790 state->parse_state = copy;
01791 return false;
01792 }
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805 static bool ParseSubstitution(State *state, bool accept_std) {
01806 ComplexityGuard guard(state);
01807 if (guard.IsTooComplex()) return false;
01808 if (ParseTwoCharToken(state, "S_")) {
01809 MaybeAppend(state, "?");
01810 return true;
01811 }
01812
01813 ParseState copy = state->parse_state;
01814 if (ParseOneCharToken(state, 'S') && ParseSeqId(state) &&
01815 ParseOneCharToken(state, '_')) {
01816 MaybeAppend(state, "?");
01817 return true;
01818 }
01819 state->parse_state = copy;
01820
01821
01822 if (ParseOneCharToken(state, 'S')) {
01823 const AbbrevPair *p;
01824 for (p = kSubstitutionList; p->abbrev != nullptr; ++p) {
01825 if (RemainingInput(state)[0] == p->abbrev[1] &&
01826 (accept_std || p->abbrev[1] != 't')) {
01827 MaybeAppend(state, "std");
01828 if (p->real_name[0] != '\0') {
01829 MaybeAppend(state, "::");
01830 MaybeAppend(state, p->real_name);
01831 }
01832 ++state->parse_state.mangled_idx;
01833 return true;
01834 }
01835 }
01836 }
01837 state->parse_state = copy;
01838 return false;
01839 }
01840
01841
01842
01843 static bool ParseTopLevelMangledName(State *state) {
01844 ComplexityGuard guard(state);
01845 if (guard.IsTooComplex()) return false;
01846 if (ParseMangledName(state)) {
01847 if (RemainingInput(state)[0] != '\0') {
01848
01849 if (IsFunctionCloneSuffix(RemainingInput(state))) {
01850 return true;
01851 }
01852
01853
01854 if (RemainingInput(state)[0] == '@') {
01855 MaybeAppend(state, RemainingInput(state));
01856 return true;
01857 }
01858 return false;
01859 }
01860 return true;
01861 }
01862 return false;
01863 }
01864
01865 static bool Overflowed(const State *state) {
01866 return state->parse_state.out_cur_idx >= state->out_end_idx;
01867 }
01868
01869
01870 bool Demangle(const char *mangled, char *out, int out_size) {
01871 State state;
01872 InitState(&state, mangled, out, out_size);
01873 return ParseTopLevelMangledName(&state) && !Overflowed(&state);
01874 }
01875
01876 }
01877 }