demangle.cc
Go to the documentation of this file.
00001 // Copyright 2018 The Abseil Authors.
00002 //
00003 // Licensed under the Apache License, Version 2.0 (the "License");
00004 // you may not use this file except in compliance with the License.
00005 // You may obtain a copy of the License at
00006 //
00007 //      https://www.apache.org/licenses/LICENSE-2.0
00008 //
00009 // Unless required by applicable law or agreed to in writing, software
00010 // distributed under the License is distributed on an "AS IS" BASIS,
00011 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00012 // See the License for the specific language governing permissions and
00013 // limitations under the License.
00014 
00015 // For reference check out:
00016 // https://itanium-cxx-abi.github.io/cxx-abi/abi.html#mangling
00017 //
00018 // Note that we only have partial C++11 support yet.
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   // Number of arguments in <expression> context, or 0 if disallowed.
00033   int arity;
00034 } AbbrevPair;
00035 
00036 // List of operators from Itanium C++ ABI.
00037 static const AbbrevPair kOperatorList[] = {
00038     // New has special syntax (not currently supported).
00039     {"nw", "new", 0},
00040     {"na", "new[]", 0},
00041 
00042     // Works except that the 'gs' prefix is not supported.
00043     {"dl", "delete", 1},
00044     {"da", "delete[]", 1},
00045 
00046     {"ps", "+", 1},  // "positive"
00047     {"ng", "-", 1},  // "negative"
00048     {"ad", "&", 1},  // "address-of"
00049     {"de", "*", 1},  // "dereference"
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},  // Special syntax
00087     {"cl", "()", 0},  // Special syntax
00088     {"ix", "[]", 2},
00089     {"qu", "?", 3},
00090     {"st", "sizeof", 0},  // Special syntax
00091     {"sz", "sizeof", 1},  // Not a real operator name, but used in expressions.
00092     {nullptr, nullptr, 0},
00093 };
00094 
00095 // List of builtin types from Itanium C++ ABI.
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 // List of substitutions Itanium C++ ABI.
00122 static const AbbrevPair kSubstitutionList[] = {
00123     {"St", "", 0},
00124     {"Sa", "allocator", 0},
00125     {"Sb", "basic_string", 0},
00126     // std::basic_string<char, std::char_traits<char>,std::allocator<char> >
00127     {"Ss", "string", 0},
00128     // std::basic_istream<char, std::char_traits<char> >
00129     {"Si", "istream", 0},
00130     // std::basic_ostream<char, std::char_traits<char> >
00131     {"So", "ostream", 0},
00132     // std::basic_iostream<char, std::char_traits<char> >
00133     {"Sd", "iostream", 0},
00134     {nullptr, nullptr, 0},
00135 };
00136 
00137 // State needed for demangling.  This struct is copied in almost every stack
00138 // frame, so every byte counts.
00139 typedef struct {
00140   int mangled_idx;                   // Cursor of mangled name.
00141   int out_cur_idx;                   // Cursor of output std::string.
00142   int prev_name_idx;                 // For constructors/destructors.
00143   signed int prev_name_length : 16;  // For constructors/destructors.
00144   signed int nest_level : 15;        // For nested names.
00145   unsigned int append : 1;           // Append flag.
00146   // Note: for some reason MSVC can't pack "bool append : 1" into the same int
00147   // with the above two fields, so we use an int instead.  Amusingly it can pack
00148   // "signed bool" as expected, but relying on that to continue to be a legal
00149   // type seems ill-advised (as it's illegal in at least clang).
00150 } ParseState;
00151 
00152 static_assert(sizeof(ParseState) == 4 * sizeof(int),
00153               "unexpected size of ParseState");
00154 
00155 // One-off state for demangling that's not subject to backtracking -- either
00156 // constant data, data that's intentionally immune to backtracking (steps), or
00157 // data that would never be changed by backtracking anyway (recursion_depth).
00158 //
00159 // Only one copy of this exists for each call to Demangle, so the size of this
00160 // struct is nearly inconsequential.
00161 typedef struct {
00162   const char *mangled_begin;  // Beginning of input std::string.
00163   char *out;                  // Beginning of output std::string.
00164   int out_end_idx;            // One past last allowed output character.
00165   int recursion_depth;        // For stack exhaustion prevention.
00166   int steps;               // Cap how much work we'll do, regardless of depth.
00167   ParseState parse_state;  // Backtrackable state copied for most frames.
00168 } State;
00169 
00170 namespace {
00171 // Prevent deep recursion / stack exhaustion.
00172 // Also prevent unbounded handling of complex inputs.
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   // 256 levels of recursion seems like a reasonable upper limit on depth.
00182   // 128 is not enough to demagle synthetic tests from demangle_unittest.txt:
00183   // "_ZaaZZZZ..." and "_ZaaZcvZcvZ..."
00184   static constexpr int kRecursionDepthLimit = 256;
00185 
00186   // We're trying to pick a charitable upper-limit on how many parse steps are
00187   // necessary to handle something that a human could actually make use of.
00188   // This is mostly in place as a bound on how much work we'll do if we are
00189   // asked to demangle an mangled name from an untrusted source, so it should be
00190   // much larger than the largest expected symbol, but much smaller than the
00191   // amount of work we can do in, e.g., a second.
00192   //
00193   // Some real-world symbols from an arbitrary binary started failing between
00194   // 2^12 and 2^13, so we multiply the latter by an extra factor of 16 to set
00195   // the limit.
00196   //
00197   // Spending one second on 2^17 parse steps would require each step to take
00198   // 7.6us, or ~30000 clock cycles, so it's safe to say this can be done in
00199   // under a second.
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 }  // namespace
00211 
00212 // We don't use strlen() in libc since it's not guaranteed to be async
00213 // signal safe.
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 // Returns true if "str" has at least "n" characters remaining.
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 // Returns true if "str" has "prefix" as a prefix.
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';  // Consumed everything in "prefix".
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 // Returns true and advances "mangled_idx" if we find "one_char_token"
00263 // at "mangled_idx" position.  It is assumed that "one_char_token" does
00264 // not contain '\0'.
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 // Returns true and advances "mangled_cur" if we find "two_char_token"
00276 // at "mangled_cur" position.  It is assumed that "two_char_token" does
00277 // not contain '\0'.
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 // Returns true and advances "mangled_cur" if we find any character in
00290 // "char_class" at "mangled_cur" position.
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 // This function is used for handling an optional non-terminal.
00319 static bool Optional(bool /*status*/) { return true; }
00320 
00321 // This function is used for handling <non-terminal>+ syntax.
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 // This function is used for handling <non-terminal>* syntax. The function
00333 // always returns true and must be followed by a termination token or a
00334 // terminating sequence not handled by parse_func (e.g.
00335 // ParseOneCharToken(state, 'E')).
00336 static bool ZeroOrMore(ParseFunc parse_func, State *state) {
00337   while (parse_func(state)) {
00338   }
00339   return true;
00340 }
00341 
00342 // Append "str" at "out_cur_idx".  If there is an overflow, out_cur_idx is
00343 // set to out_end_idx+1.  The output string is ensured to
00344 // always terminate with '\0' as long as there is no overflow.
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) {  // +1 for '\0'
00349       state->out[state->parse_state.out_cur_idx++] = str[i];
00350     } else {
00351       // signal overflow
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';  // Terminate it with '\0'
00359   }
00360 }
00361 
00362 // We don't use equivalents in libc to avoid locale issues.
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 // Returns true if "str" is a function clone suffix.  These suffixes are used
00372 // by GCC 4.5.x and later versions (and our locally-modified version of GCC
00373 // 4.4.x) to indicate functions which have been cloned during optimization.
00374 // We treat any sequence (.<alpha>+.<digit>+)+ as a function clone suffix.
00375 static bool IsFunctionCloneSuffix(const char *str) {
00376   size_t i = 0;
00377   while (str[i] != '\0') {
00378     // Consume a single .<alpha>+.<digit>+ sequence.
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;  // Consumed everything in "str".
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 // Append "str" with some tweaks, iff "append" state is true.
00403 static void MaybeAppendWithLength(State *state, const char *const str,
00404                                   const int length) {
00405   if (state->parse_state.append && length > 0) {
00406     // Append a space if the output buffer ends with '<' and "str"
00407     // starts with '<' to avoid <<<.
00408     if (str[0] == '<' && EndsWith(state, '<')) {
00409       Append(state, " ", 1);
00410     }
00411     // Remember the last identifier name for ctors/dtors.
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 // Appends a positive decimal number to the output if appending is enabled.
00421 static bool MaybeAppendDecimal(State *state, unsigned int val) {
00422   // Max {32-64}-bit unsigned int is 20 digits.
00423   constexpr size_t kMaxLength = 20;
00424   char buf[kMaxLength];
00425 
00426   // We can't use itoa or sprintf as neither is specified to be
00427   // async-signal-safe.
00428   if (state->parse_state.append) {
00429     // We can't have a one-before-the-beginning pointer, so instead start with
00430     // one-past-the-end and manipulate one character before the pointer.
00431     char *p = &buf[kMaxLength];
00432     do {  // val=0 is the only input that should write a leading zero digit.
00433       *--p = (val % 10) + '0';
00434       val /= 10;
00435     } while (p > buf && val != 0);
00436 
00437     // 'p' landed on the last character we set.  How convenient.
00438     Append(state, p, kMaxLength - (p - buf));
00439   }
00440 
00441   return true;
00442 }
00443 
00444 // A convenient wrapper around MaybeAppendWithLength().
00445 // Returns true so that it can be placed in "if" conditions.
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 // This function is used for handling nested names.
00455 static bool EnterNestedName(State *state) {
00456   state->parse_state.nest_level = 0;
00457   return true;
00458 }
00459 
00460 // This function is used for handling nested names.
00461 static bool LeaveNestedName(State *state, int16_t prev_value) {
00462   state->parse_state.nest_level = prev_value;
00463   return true;
00464 }
00465 
00466 // Disable the append mode not to print function parameters, etc.
00467 static bool DisableAppend(State *state) {
00468   state->parse_state.append = false;
00469   return true;
00470 }
00471 
00472 // Restore the append mode to the previous state.
00473 static bool RestoreAppend(State *state, bool prev_value) {
00474   state->parse_state.append = prev_value;
00475   return true;
00476 }
00477 
00478 // Increase the nest level for nested names.
00479 static void MaybeIncreaseNestLevel(State *state) {
00480   if (state->parse_state.nest_level > -1) {
00481     ++state->parse_state.nest_level;
00482   }
00483 }
00484 
00485 // Appends :: for nested names if necessary.
00486 static void MaybeAppendSeparator(State *state) {
00487   if (state->parse_state.nest_level >= 1) {
00488     MaybeAppend(state, "::");
00489   }
00490 }
00491 
00492 // Cancel the last separator if necessary.
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 // Returns true if the identifier of the given length pointed to by
00502 // "mangled_cur" is anonymous namespace.
00503 static bool IdentifierIsAnonymousNamespace(State *state, int length) {
00504   // Returns true if "anon_prefix" is a proper prefix of "mangled_cur".
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 // Forward declarations of our parsing functions.
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 // Implementation note: the following code is a straightforward
00555 // translation of the Itanium C++ ABI defined in BNF with a couple of
00556 // exceptions.
00557 //
00558 // - Support GNU extensions not defined in the Itanium C++ ABI
00559 // - <prefix> and <template-prefix> are combined to avoid infinite loop
00560 // - Reorder patterns to shorten the code
00561 // - Reorder patterns to give greedier functions precedence
00562 //   We'll mark "Less greedy than" for these cases in the code
00563 //
00564 // Each parsing function changes the parse state and returns true on
00565 // success, or returns false and doesn't change the parse state (note:
00566 // the parse-steps counter increases regardless of success or failure).
00567 // To ensure that the parse state isn't changed in the latter case, we
00568 // save the original state before we call multiple parsing functions
00569 // consecutively with &&, and restore it if unsuccessful.  See
00570 // ParseEncoding() as an example of this convention.  We follow the
00571 // convention throughout the code.
00572 //
00573 // Originally we tried to do demangling without following the full ABI
00574 // syntax but it turned out we needed to follow the full syntax to
00575 // parse complicated cases like nested template arguments.  Note that
00576 // implementing a full-fledged demangler isn't trivial (libiberty's
00577 // cp-demangle.c has +4300 lines).
00578 //
00579 // Note that (foo) in <(foo) ...> is a modifier to be ignored.
00580 //
00581 // Reference:
00582 // - Itanium C++ ABI
00583 //   <https://mentorembedded.github.io/cxx-abi/abi.html#mangling>
00584 
00585 // <mangled-name> ::= _Z <encoding>
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 // <encoding> ::= <(function) name> <bare-function-type>
00593 //            ::= <(data) name>
00594 //            ::= <special-name>
00595 static bool ParseEncoding(State *state) {
00596   ComplexityGuard guard(state);
00597   if (guard.IsTooComplex()) return false;
00598   // Implementing the first two productions together as <name>
00599   // [<bare-function-type>] avoids exponential blowup of backtracking.
00600   //
00601   // Since Optional(...) can't fail, there's no need to copy the state for
00602   // backtracking.
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 // <name> ::= <nested-name>
00614 //        ::= <unscoped-template-name> <template-args>
00615 //        ::= <unscoped-name>
00616 //        ::= <local-name>
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   // We reorganize the productions to avoid re-parsing unscoped names.
00625   // - Inline <unscoped-template-name> productions:
00626   //   <name> ::= <substitution> <template-args>
00627   //          ::= <unscoped-name> <template-args>
00628   //          ::= <unscoped-name>
00629   // - Merge the two productions that start with unscoped-name:
00630   //   <name> ::= <unscoped-name> [<template-args>]
00631 
00632   ParseState copy = state->parse_state;
00633   // "std<...>" isn't a valid name.
00634   if (ParseSubstitution(state, /*accept_std=*/false) &&
00635       ParseTemplateArgs(state)) {
00636     return true;
00637   }
00638   state->parse_state = copy;
00639 
00640   // Note there's no need to restore state after this since only the first
00641   // subparser can fail.
00642   return ParseUnscopedName(state) && Optional(ParseTemplateArgs(state));
00643 }
00644 
00645 // <unscoped-name> ::= <unqualified-name>
00646 //                 ::= St <unqualified-name>
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 // <ref-qualifer> ::= R // lvalue method reference qualifier
00664 //                ::= O // rvalue method reference qualifier
00665 static inline bool ParseRefQualifier(State *state) {
00666   return ParseCharClass(state, "OR");
00667 }
00668 
00669 // <nested-name> ::= N [<CV-qualifiers>] [<ref-qualifier>] <prefix>
00670 //                   <unqualified-name> E
00671 //               ::= N [<CV-qualifiers>] [<ref-qualifier>] <template-prefix>
00672 //                   <template-args> E
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 // This part is tricky.  If we literally translate them to code, we'll
00689 // end up infinite loop.  Hence we merge them to avoid the case.
00690 //
00691 // <prefix> ::= <prefix> <unqualified-name>
00692 //          ::= <template-prefix> <template-args>
00693 //          ::= <template-param>
00694 //          ::= <substitution>
00695 //          ::= # empty
00696 // <template-prefix> ::= <prefix> <(template) unqualified-name>
00697 //                   ::= <template-param>
00698 //                   ::= <substitution>
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, /*accept_std=*/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 // <unqualified-name> ::= <operator-name>
00724 //                    ::= <ctor-dtor-name>
00725 //                    ::= <source-name>
00726 //                    ::= <local-source-name> // GCC extension; see below.
00727 //                    ::= <unnamed-type-name>
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 // <source-name> ::= <positive length number> <identifier>
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 // <local-source-name> ::= L <source-name> [<discriminator>]
00750 //
00751 // References:
00752 //   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
00753 //   https://gcc.gnu.org/viewcvs?view=rev&revision=124467
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 // <unnamed-type-name> ::= Ut [<(nonnegative) number>] _
00767 //                     ::= <closure-type-name>
00768 // <closure-type-name> ::= Ul <lambda-sig> E [<(nonnegative) number>] _
00769 // <lambda-sig>        ::= <(parameter) type>+
00770 static bool ParseUnnamedTypeName(State *state) {
00771   ComplexityGuard guard(state);
00772   if (guard.IsTooComplex()) return false;
00773   ParseState copy = state->parse_state;
00774   // Type's 1-based index n is encoded as { "", n == 1; itoa(n-2), otherwise }.
00775   // Optionally parse the encoded value into 'which' and add 2 to get the index.
00776   int which = -1;
00777 
00778   // Unnamed type local to function or class.
00779   if (ParseTwoCharToken(state, "Ut") && Optional(ParseNumber(state, &which)) &&
00780       which <= std::numeric_limits<int>::max() - 2 &&  // Don't overflow.
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   // Closure type.
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 &&  // Don't overflow.
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 // <number> ::= [n] <non-negative decimal integer>
00807 // If "number_out" is non-null, then *number_out is set to the value of the
00808 // parsed number on success.
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   // Apply the sign with uint64_t arithmetic so overflows aren't UB.  Gives
00826   // "incorrect" results for out-of-range inputs, but negative values only
00827   // appear for literals, which aren't printed.
00828   if (negative) {
00829     number = ~number + 1;
00830   }
00831   if (p != RemainingInput(state)) {  // Conversion succeeded.
00832     state->parse_state.mangled_idx += p - RemainingInput(state);
00833     if (number_out != nullptr) {
00834       // Note: possibly truncate "number".
00835       *number_out = number;
00836     }
00837     return true;
00838   }
00839   return false;
00840 }
00841 
00842 // Floating-point literals are encoded using a fixed-length lowercase
00843 // hexadecimal string.
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)) {  // Conversion succeeded.
00854     state->parse_state.mangled_idx += p - RemainingInput(state);
00855     return true;
00856   }
00857   return false;
00858 }
00859 
00860 // The <seq-id> is a sequence number in base 36,
00861 // using digits and upper case letters
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)) {  // Conversion succeeded.
00872     state->parse_state.mangled_idx += p - RemainingInput(state);
00873     return true;
00874   }
00875   return false;
00876 }
00877 
00878 // <identifier> ::= <unqualified source code identifier> (of given length)
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 // <operator-name> ::= nw, and other two letters cases
00895 //                 ::= cv <type>  # (cast)
00896 //                 ::= v  <digit> <source-name> # vendor extended operator
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   // First check with "cv" (cast) case.
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   // Then vendor extended operators.
00916   if (ParseOneCharToken(state, 'v') && ParseDigit(state, arity) &&
00917       ParseSourceName(state)) {
00918     return true;
00919   }
00920   state->parse_state = copy;
00921 
00922   // Other operator names should start with a lower alphabet followed
00923   // by a lower/upper alphabet.
00924   if (!(IsLower(RemainingInput(state)[0]) &&
00925         IsAlpha(RemainingInput(state)[1]))) {
00926     return false;
00927   }
00928   // We may want to perform a binary search if we really need speed.
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)) {  // new, delete, etc.
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 // <special-name> ::= TV <type>
00949 //                ::= TT <type>
00950 //                ::= TI <type>
00951 //                ::= TS <type>
00952 //                ::= Tc <call-offset> <call-offset> <(base) encoding>
00953 //                ::= GV <(object) name>
00954 //                ::= T <call-offset> <(base) encoding>
00955 // G++ extensions:
00956 //                ::= TC <type> <(offset) number> _ <(base) type>
00957 //                ::= TF <type>
00958 //                ::= TJ <type>
00959 //                ::= GR <name>
00960 //                ::= GA <encoding>
00961 //                ::= Th <call-offset> <(base) encoding>
00962 //                ::= Tv <call-offset> <(base) encoding>
00963 //
00964 // Note: we don't care much about them since they don't appear in
00965 // stack traces.  The are special data.
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   // G++ extensions
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 // <call-offset> ::= h <nv-offset> _
01027 //               ::= v <v-offset> _
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 // <nv-offset> ::= <(offset) number>
01048 static bool ParseNVOffset(State *state) {
01049   ComplexityGuard guard(state);
01050   if (guard.IsTooComplex()) return false;
01051   return ParseNumber(state, nullptr);
01052 }
01053 
01054 // <v-offset>  ::= <(offset) number> _ <(virtual offset) number>
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 // <ctor-dtor-name> ::= C1 | C2 | C3
01068 //                  ::= D0 | D1 | D2
01069 // # GCC extensions: "unified" constructor/destructor.  See
01070 // # https://github.com/gcc-mirror/gcc/blob/7ad17b583c3643bd4557f29b8391ca7ef08391f5/gcc/cp/mangle.c#L1847
01071 //                  ::= C4 | D4
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 // <decltype> ::= Dt <expression> E  # decltype of an id-expression or class
01096 //                                   # member access (C++0x)
01097 //            ::= DT <expression> E  # decltype of an expression (C++0x)
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 // <type> ::= <CV-qualifiers> <type>
01113 //        ::= P <type>   # pointer-to
01114 //        ::= R <type>   # reference-to
01115 //        ::= O <type>   # rvalue reference-to (C++0x)
01116 //        ::= C <type>   # complex pair (C 2000)
01117 //        ::= G <type>   # imaginary (C 2000)
01118 //        ::= U <source-name> <type>  # vendor extended type qualifier
01119 //        ::= <builtin-type>
01120 //        ::= <function-type>
01121 //        ::= <class-enum-type>  # note: just an alias for <name>
01122 //        ::= <array-type>
01123 //        ::= <pointer-to-member-type>
01124 //        ::= <template-template-param> <template-args>
01125 //        ::= <template-param>
01126 //        ::= <decltype>
01127 //        ::= <substitution>
01128 //        ::= Dp <type>          # pack expansion of (C++0x)
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   // We should check CV-qualifers, and PRGC things first.
01136   //
01137   // CV-qualifiers overlap with some operator names, but an operator name is not
01138   // valid as a type.  To avoid an ambiguity that can lead to exponential time
01139   // complexity, refuse to backtrack the CV-qualifiers.
01140   //
01141   // _Z4aoeuIrMvvE
01142   //  => _Z 4aoeuI        rM  v     v   E
01143   //         aoeu<operator%=, void, void>
01144   //  => _Z 4aoeuI r Mv v              E
01145   //         aoeu<void void::* restrict>
01146   //
01147   // By consuming the CV-qualifiers first, the former parse is disabled.
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   // Similarly, these tag characters can overlap with other <name>s resulting in
01156   // two different parse prefixes that land on <template-args> in the same
01157   // place, such as "C3r1xI...".  So, disable the "ctor-name = C3" parse by
01158   // refusing to backtrack the tag characters.
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   // nullptr_t, i.e. decltype(nullptr).
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       // "std" on its own isn't a type.
01187       ParseSubstitution(state, /*accept_std=*/false)) {
01188     return true;
01189   }
01190 
01191   if (ParseTemplateTemplateParam(state) && ParseTemplateArgs(state)) {
01192     return true;
01193   }
01194   state->parse_state = copy;
01195 
01196   // Less greedy than <template-template-param> <template-args>.
01197   if (ParseTemplateParam(state)) {
01198     return true;
01199   }
01200 
01201   return false;
01202 }
01203 
01204 // <CV-qualifiers> ::= [r] [V] [K]
01205 // We don't allow empty <CV-qualifiers> to avoid infinite loop in
01206 // ParseType().
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 // <builtin-type> ::= v, etc.
01218 //                ::= u <source-name>
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 // <function-type> ::= F [Y] <bare-function-type> E
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 // <bare-function-type> ::= <(signature) type>+
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 // <class-enum-type> ::= <name>
01269 static bool ParseClassEnumType(State *state) {
01270   ComplexityGuard guard(state);
01271   if (guard.IsTooComplex()) return false;
01272   return ParseName(state);
01273 }
01274 
01275 // <array-type> ::= A <(positive dimension) number> _ <(element) type>
01276 //              ::= A [<(dimension) expression>] _ <(element) type>
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 // <pointer-to-member-type> ::= M <(class) type> <(member) type>
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 // <template-param> ::= T_
01308 //                  ::= T <parameter-2 non-negative number> _
01309 static bool ParseTemplateParam(State *state) {
01310   ComplexityGuard guard(state);
01311   if (guard.IsTooComplex()) return false;
01312   if (ParseTwoCharToken(state, "T_")) {
01313     MaybeAppend(state, "?");  // We don't support template substitutions.
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, "?");  // We don't support template substitutions.
01321     return true;
01322   }
01323   state->parse_state = copy;
01324   return false;
01325 }
01326 
01327 // <template-template-param> ::= <template-param>
01328 //                           ::= <substitution>
01329 static bool ParseTemplateTemplateParam(State *state) {
01330   ComplexityGuard guard(state);
01331   if (guard.IsTooComplex()) return false;
01332   return (ParseTemplateParam(state) ||
01333           // "std" on its own isn't a template.
01334           ParseSubstitution(state, /*accept_std=*/false));
01335 }
01336 
01337 // <template-args> ::= I <template-arg>+ E
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 // <template-arg>  ::= <type>
01354 //                 ::= <expr-primary>
01355 //                 ::= J <template-arg>* E        # argument pack
01356 //                 ::= X <expression> E
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   // There can be significant overlap between the following leading to
01368   // exponential backtracking:
01369   //
01370   //   <expr-primary> ::= L <type> <expr-cast-value> E
01371   //                 e.g. L 2xxIvE 1                 E
01372   //   <type>         ==> <local-source-name> <template-args>
01373   //                 e.g. L 2xx               IvE
01374   //
01375   // This means parsing an entire <type> twice, and <type> can contain
01376   // <template-arg>, so this can generate exponential backtracking.  There is
01377   // only overlap when the remaining input starts with "L <source-name>", so
01378   // parse all cases that can start this way jointly to share the common prefix.
01379   //
01380   // We have:
01381   //
01382   //   <template-arg> ::= <type>
01383   //                  ::= <expr-primary>
01384   //
01385   // First, drop all the productions of <type> that must start with something
01386   // other than 'L'.  All that's left is <class-enum-type>; inline it.
01387   //
01388   //   <type> ::= <nested-name> # starts with 'N'
01389   //          ::= <unscoped-name>
01390   //          ::= <unscoped-template-name> <template-args>
01391   //          ::= <local-name> # starts with 'Z'
01392   //
01393   // Drop and inline again:
01394   //
01395   //   <type> ::= <unscoped-name>
01396   //          ::= <unscoped-name> <template-args>
01397   //          ::= <substitution> <template-args> # starts with 'S'
01398   //
01399   // Merge the first two, inline <unscoped-name>, drop last:
01400   //
01401   //   <type> ::= <unqualified-name> [<template-args>]
01402   //          ::= St <unqualified-name> [<template-args>] # starts with 'S'
01403   //
01404   // Drop and inline:
01405   //
01406   //   <type> ::= <operator-name> [<template-args>] # starts with lowercase
01407   //          ::= <ctor-dtor-name> [<template-args>] # starts with 'C' or 'D'
01408   //          ::= <source-name> [<template-args>] # starts with digit
01409   //          ::= <local-source-name> [<template-args>]
01410   //          ::= <unnamed-type-name> [<template-args>] # starts with 'U'
01411   //
01412   // One more time:
01413   //
01414   //   <type> ::= L <source-name> [<template-args>]
01415   //
01416   // Likewise with <expr-primary>:
01417   //
01418   //   <expr-primary> ::= L <type> <expr-cast-value> E
01419   //                  ::= LZ <encoding> E # cannot overlap; drop
01420   //                  ::= L <mangled_name> E # cannot overlap; drop
01421   //
01422   // By similar reasoning as shown above, the only <type>s starting with
01423   // <source-name> are "<source-name> [<template-args>]".  Inline this.
01424   //
01425   //   <expr-primary> ::= L <source-name> [<template-args>] <expr-cast-value> E
01426   //
01427   // Now inline both of these into <template-arg>:
01428   //
01429   //   <template-arg> ::= L <source-name> [<template-args>]
01430   //                  ::= L <source-name> [<template-args>] <expr-cast-value> E
01431   //
01432   // Merge them and we're done:
01433   //   <template-arg>
01434   //     ::= L <source-name> [<template-args>] [<expr-cast-value> E]
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   // Now that the overlapping cases can't reach this code, we can safely call
01445   // both of these.
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 // <unresolved-type> ::= <template-param> [<template-args>]
01460 //                   ::= <decltype>
01461 //                   ::= <substitution>
01462 static inline bool ParseUnresolvedType(State *state) {
01463   // No ComplexityGuard because we don't copy the state in this stack frame.
01464   return (ParseTemplateParam(state) && Optional(ParseTemplateArgs(state))) ||
01465          ParseDecltype(state) || ParseSubstitution(state, /*accept_std=*/false);
01466 }
01467 
01468 // <simple-id> ::= <source-name> [<template-args>]
01469 static inline bool ParseSimpleId(State *state) {
01470   // No ComplexityGuard because we don't copy the state in this stack frame.
01471 
01472   // Note: <simple-id> cannot be followed by a parameter pack; see comment in
01473   // ParseUnresolvedType.
01474   return ParseSourceName(state) && Optional(ParseTemplateArgs(state));
01475 }
01476 
01477 // <base-unresolved-name> ::= <source-name> [<template-args>]
01478 //                        ::= on <operator-name> [<template-args>]
01479 //                        ::= dn <destructor-name>
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 // <unresolved-name> ::= [gs] <base-unresolved-name>
01505 //                   ::= sr <unresolved-type> <base-unresolved-name>
01506 //                   ::= srN <unresolved-type> <unresolved-qualifier-level>+ E
01507 //                         <base-unresolved-name>
01508 //                   ::= [gs] sr <unresolved-qualifier-level>+ E
01509 //                         <base-unresolved-name>
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(/* <unresolved-qualifier-level> ::= */ 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(/* <unresolved-qualifier-level> ::= */ ParseSimpleId, state) &&
01538       ParseOneCharToken(state, 'E') && ParseBaseUnresolvedName(state)) {
01539     return true;
01540   }
01541   state->parse_state = copy;
01542 
01543   return false;
01544 }
01545 
01546 // <expression> ::= <1-ary operator-name> <expression>
01547 //              ::= <2-ary operator-name> <expression> <expression>
01548 //              ::= <3-ary operator-name> <expression> <expression> <expression>
01549 //              ::= cl <expression>+ E
01550 //              ::= cv <type> <expression>      # type (expression)
01551 //              ::= cv <type> _ <expression>* E # type (expr-list)
01552 //              ::= st <type>
01553 //              ::= <template-param>
01554 //              ::= <function-param>
01555 //              ::= <expr-primary>
01556 //              ::= dt <expression> <unresolved-name> # expr.name
01557 //              ::= pt <expression> <unresolved-name> # expr->name
01558 //              ::= sp <expression>         # argument pack expansion
01559 //              ::= sr <type> <unqualified-name> <template-args>
01560 //              ::= sr <type> <unqualified-name>
01561 // <function-param> ::= fp <(top-level) CV-qualifiers> _
01562 //                  ::= fp <(top-level) CV-qualifiers> <number> _
01563 //                  ::= fL <number> p <(top-level) CV-qualifiers> _
01564 //                  ::= fL <number> p <(top-level) CV-qualifiers> <number> _
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   // Object/function call expression.
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   // Function-param expression (level 0).
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   // Function-param expression (level 1+).
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   // Parse the conversion expressions jointly to avoid re-parsing the <type> in
01596   // their common prefix.  Parsed as:
01597   // <expression> ::= cv <type> <conversion-args>
01598   // <conversion-args> ::= _ <expression>* E
01599   //                   ::= <expression>
01600   //
01601   // Also don't try ParseOperatorName after seeing "cv", since ParseOperatorName
01602   // also needs to accept "cv <type>" in other contexts.
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     // Parse unary, binary, and ternary operator expressions jointly, taking
01617     // care not to re-parse subexpressions repeatedly. Parse like:
01618     //   <expression> ::= <operator-name> <expression>
01619     //                    [<one-to-two-expressions>]
01620     //   <one-to-two-expressions> ::= <expression> [<expression>]
01621     int arity = -1;
01622     if (ParseOperatorName(state, &arity) &&
01623         arity > 0 &&  // 0 arity => disabled.
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   // sizeof type
01633   if (ParseTwoCharToken(state, "st") && ParseType(state)) {
01634     return true;
01635   }
01636   state->parse_state = copy;
01637 
01638   // Object and pointer member access expressions.
01639   if ((ParseTwoCharToken(state, "dt") || ParseTwoCharToken(state, "pt")) &&
01640       ParseExpression(state) && ParseType(state)) {
01641     return true;
01642   }
01643   state->parse_state = copy;
01644 
01645   // Pointer-to-member access expressions.  This parses the same as a binary
01646   // operator, but it's implemented separately because "ds" shouldn't be
01647   // accepted in other contexts that parse an operator name.
01648   if (ParseTwoCharToken(state, "ds") && ParseExpression(state) &&
01649       ParseExpression(state)) {
01650     return true;
01651   }
01652   state->parse_state = copy;
01653 
01654   // Parameter pack expansion
01655   if (ParseTwoCharToken(state, "sp") && ParseExpression(state)) {
01656     return true;
01657   }
01658   state->parse_state = copy;
01659 
01660   return ParseUnresolvedName(state);
01661 }
01662 
01663 // <expr-primary> ::= L <type> <(value) number> E
01664 //                ::= L <type> <(value) float> E
01665 //                ::= L <mangled-name> E
01666 //                // A bug in g++'s C++ ABI version 2 (-fabi-version=2).
01667 //                ::= LZ <encoding> E
01668 //
01669 // Warning, subtle: the "bug" LZ production above is ambiguous with the first
01670 // production where <type> starts with <local-name>, which can lead to
01671 // exponential backtracking in two scenarios:
01672 //
01673 // - When whatever follows the E in the <local-name> in the first production is
01674 //   not a name, we backtrack the whole <encoding> and re-parse the whole thing.
01675 //
01676 // - When whatever follows the <local-name> in the first production is not a
01677 //   number and this <expr-primary> may be followed by a name, we backtrack the
01678 //   <name> and re-parse it.
01679 //
01680 // Moreover this ambiguity isn't always resolved -- for example, the following
01681 // has two different parses:
01682 //
01683 //   _ZaaILZ4aoeuE1x1EvE
01684 //   => operator&&<aoeu, x, E, void>
01685 //   => operator&&<(aoeu::x)(1), void>
01686 //
01687 // To resolve this, we just do what GCC's demangler does, and refuse to parse
01688 // casts to <local-name> types.
01689 static bool ParseExprPrimary(State *state) {
01690   ComplexityGuard guard(state);
01691   if (guard.IsTooComplex()) return false;
01692   ParseState copy = state->parse_state;
01693 
01694   // The "LZ" special case: if we see LZ, we commit to accept "LZ <encoding> E"
01695   // or fail, no backtracking.
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   // The merged cast production.
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 // <number> or <float>, followed by 'E', as described above ParseExprPrimary.
01722 static bool ParseExprCastValue(State *state) {
01723   ComplexityGuard guard(state);
01724   if (guard.IsTooComplex()) return false;
01725   // We have to be able to backtrack after accepting a number because we could
01726   // have e.g. "7fffE", which will accept "7" as a number but then fail to find
01727   // the 'E'.
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 // <local-name> ::= Z <(function) encoding> E <(entity) name> [<discriminator>]
01743 //              ::= Z <(function) encoding> E s [<discriminator>]
01744 //
01745 // Parsing a common prefix of these two productions together avoids an
01746 // exponential blowup of backtracking.  Parse like:
01747 //   <local-name> := Z <encoding> E <local-name-suffix>
01748 //   <local-name-suffix> ::= s [<discriminator>]
01749 //                       ::= <name> [<discriminator>]
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   // Since we're not going to overwrite the above "::" by re-parsing the
01761   // <encoding> (whose trailing '\0' byte was in the byte now holding the
01762   // first ':'), we have to rollback the "::" if the <name> parse failed.
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 // <discriminator> := _ <(non-negative) number>
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 // <substitution> ::= S_
01795 //                ::= S <seq-id> _
01796 //                ::= St, etc.
01797 //
01798 // "St" is special in that it's not valid as a standalone name, and it *is*
01799 // allowed to precede a name without being wrapped in "N...E".  This means that
01800 // if we accept it on its own, we can accept "St1a" and try to parse
01801 // template-args, then fail and backtrack, accept "St" on its own, then "1a" as
01802 // an unqualified name and re-parse the same template-args.  To block this
01803 // exponential backtracking, we disable it with 'accept_std=false' in
01804 // problematic contexts.
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, "?");  // We don't support substitutions.
01810     return true;
01811   }
01812 
01813   ParseState copy = state->parse_state;
01814   if (ParseOneCharToken(state, 'S') && ParseSeqId(state) &&
01815       ParseOneCharToken(state, '_')) {
01816     MaybeAppend(state, "?");  // We don't support substitutions.
01817     return true;
01818   }
01819   state->parse_state = copy;
01820 
01821   // Expand abbreviations like "St" => "std".
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 // Parse <mangled-name>, optionally followed by either a function-clone suffix
01842 // or version suffix.  Returns true only if all of "mangled_cur" was consumed.
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       // Drop trailing function clone suffix, if any.
01849       if (IsFunctionCloneSuffix(RemainingInput(state))) {
01850         return true;
01851       }
01852       // Append trailing version suffix if any.
01853       // ex. _Z3foo@@GLIBCXX_3.4
01854       if (RemainingInput(state)[0] == '@') {
01855         MaybeAppend(state, RemainingInput(state));
01856         return true;
01857       }
01858       return false;  // Unconsumed suffix.
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 // The demangler entry point.
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 }  // namespace debugging_internal
01877 }  // namespace absl


abseil_cpp
Author(s):
autogenerated on Wed Jun 19 2019 19:42:14