1 // Copyright 2006 Google Inc. All Rights Reserved.
2 // Author: Satoru Takabayashi
4 #include <stdio.h> // for NULL
7 _START_GOOGLE_NAMESPACE_
11 const char *real_name;
14 // List of operators from Itanium C++ ABI.
15 static const AbbrevPair kOperatorList[] = {
68 // List of builtin types from Itanium C++ ABI.
69 static const AbbrevPair kBuiltinTypeList[] = {
74 { "a", "signed char" },
75 { "h", "unsigned char" },
77 { "t", "unsigned short" },
79 { "j", "unsigned int" },
81 { "m", "unsigned long" },
83 { "y", "unsigned long long" },
85 { "o", "unsigned __int128" },
88 { "e", "long double" },
89 { "g", "__float128" },
94 // List of substitutions Itanium C++ ABI.
95 static const AbbrevPair kSubstitutionList[] = {
97 { "Sa", "allocator" },
98 { "Sb", "basic_string" },
99 // std::basic_string<char, std::char_traits<char>,std::allocator<char> >
101 // std::basic_istream<char, std::char_traits<char> >
103 // std::basic_ostream<char, std::char_traits<char> >
105 // std::basic_iostream<char, std::char_traits<char> >
106 { "Sd", "iostream" },
110 // State needed for demangling.
112 const char *mangled_cur; // Cursor of mangled name.
113 const char *mangled_end; // End of mangled name.
114 char *out_cur; // Cursor of output string.
115 const char *out_begin; // Beginning of output string.
116 const char *out_end; // End of output string.
117 const char *prev_name; // For constructors/destructors.
118 int prev_name_length; // For constructors/destructors.
119 int nest_level; // For nested names.
120 int number; // Remember the previous number.
121 bool append; // Append flag.
122 bool overflowed; // True if output gets overflowed.
125 // We don't use strlen() in libc since it's not guaranteed to be async
127 static size_t StrLen(const char *str) {
129 while (*str != '\0') {
136 // Returns true if "str" has "prefix" as a prefix.
137 static bool StrPrefix(const char *str, const char *prefix) {
139 while (str[i] != '\0' && prefix[i] != '\0' &&
140 str[i] == prefix[i]) {
143 return prefix[i] == '\0'; // Consumed everything in "prefix".
146 static void InitState(State *state, const char *mangled,
147 char *out, int out_size) {
148 state->mangled_cur = mangled;
149 state->mangled_end = mangled + StrLen(mangled);
150 state->out_cur = out;
151 state->out_begin = out;
152 state->out_end = out + out_size;
153 state->prev_name = NULL;
154 state->prev_name_length = -1;
155 state->nest_level = -1;
157 state->append = true;
158 state->overflowed = false;
161 // Calculates the remaining length of the mangled name.
162 static int RemainingLength(State *state) {
163 return state->mangled_end - state->mangled_cur;
166 // Returns true and advances "mangled_cur" if we find "c" at
167 // "mangled_cur" position.
168 static bool ParseChar(State *state, const char c) {
169 if (RemainingLength(state) >= 1 && *state->mangled_cur == c) {
170 ++state->mangled_cur;
176 // Returns true and advances "mangled_cur" if we find "two_chars" at
177 // "mangled_cur" position.
178 static bool ParseTwoChar(State *state, const char *two_chars) {
179 if (RemainingLength(state) >= 2 &&
180 state->mangled_cur[0] == two_chars[0] &&
181 state->mangled_cur[1] == two_chars[1]) {
182 state->mangled_cur += 2;
188 // Returns true and advances "mangled_cur" if we find any character in
189 // "char_class" at "mangled_cur" position.
190 static bool ParseCharClass(State *state, const char *char_class) {
191 if (state->mangled_cur == state->mangled_end) {
194 const char *p = char_class;
195 for (; *p != '\0'; ++p) {
196 if (*state->mangled_cur == *p) {
197 state->mangled_cur += 1;
204 // This function is used for handling an optional non-terminal.
205 static bool Optional(bool status) {
209 // This function is used for handling <non-terminal>+ syntax.
210 typedef bool (*ParseFunc)(State *);
211 static bool OneOrMore(ParseFunc parse_func, State *state) {
212 if (parse_func(state)) {
213 while (parse_func(state)) {
220 // Append "str" at "out_cur". If there is an overflow, "overflowed"
221 // is set to true for later use. The output string is ensured to
222 // always terminate with '\0' as long as there is no overflow.
223 static void Append(State *state, const char * const str, const int length) {
225 for (i = 0; i < length; ++i) {
226 if (state->out_cur + 1 < state->out_end) { // +1 for '\0'
227 *state->out_cur = str[i];
230 state->overflowed = true;
234 if (!state->overflowed) {
235 *state->out_cur = '\0'; // Terminate it with '\0'
239 // We don't use equivalents in libc to avoid locale issues.
240 static bool IsLower(char c) {
241 return c >= 'a' && c <= 'z';
244 static bool IsAlpha(char c) {
245 return ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));
248 // Append "str" with some tweaks, iff "append" state is true.
249 // Returns true so that it can be placed in "if" conditions.
250 static void MaybeAppendWithLength(State *state, const char * const str,
252 if (state->append && length > 0) {
253 // Append a space if the output buffer ends with '<' and "str"
254 // starts with '<' to avoid <<<.
255 if (str[0] == '<' && state->out_begin < state->out_cur &&
256 state->out_cur[-1] == '<') {
257 Append(state, " ", 1);
259 // Remember the last identifier name for ctors/dtors.
260 if (IsAlpha(str[0]) || str[0] == '_') {
261 state->prev_name = state->out_cur;
262 state->prev_name_length = length;
264 Append(state, str, length);
268 // A convenient wrapper arount MaybeAppendWithLength().
269 static bool MaybeAppend(State *state, const char * const str) {
271 int length = StrLen(str);
272 MaybeAppendWithLength(state, str, length);
277 // This function is used for handling nested names.
278 static bool EnterNestedName(State *state) {
279 state->nest_level = 0;
283 // This function is used for handling nested names.
284 static bool LeaveNestedName(State *state, int prev_value) {
285 state->nest_level = prev_value;
289 // Disable the append mode not to print function parameters, etc.
290 static bool DisableAppend(State *state) {
291 state->append = false;
295 // Restore the append mode to the previous state.
296 static bool RestoreAppend(State *state, bool prev_value) {
297 state->append = prev_value;
301 // Increase the nest level for nested names.
302 static void MaybeIncreaseNestLevel(State *state) {
303 if (state->nest_level > -1) {
308 // Appends :: for nested names if necessary.
309 static void MaybeAppendSeparator(State *state) {
310 if (state->nest_level >= 1) {
311 MaybeAppend(state, "::");
315 // Cancel the last separator if necessary.
316 static void MaybeCancelLastSeparator(State *state) {
317 if (state->nest_level >= 1 && state->append &&
318 state->out_begin <= state->out_cur - 2) {
320 *state->out_cur = '\0';
324 // Returns true if identifier pointed by "mangled_cur" is anonymous
326 static bool IdentifierIsAnonymousNamespace(State *state) {
327 const char anon_prefix[] = "_GLOBAL__N_";
328 return (state->number > sizeof(anon_prefix) - 1 && // Should be longer.
329 StrPrefix(state->mangled_cur, anon_prefix));
332 // Forward declarations of our parsing functions.
333 static bool ParseMangledName(State *state);
334 static bool ParseEncoding(State *state);
335 static bool ParseName(State *state);
336 static bool ParseUnscopedName(State *state);
337 static bool ParseUnscopedTemplateName(State *state);
338 static bool ParseNestedName(State *state);
339 static bool ParsePrefix(State *state);
340 static bool ParseUnqualifiedName(State *state);
341 static bool ParseSourceName(State *state);
342 static bool ParseLocalSourceName(State *state);
343 static bool ParseNumber(State *state);
344 static bool ParseFloatNumber(State *state);
345 static bool ParseSeqId(State *state);
346 static bool ParseIdentifier(State *state);
347 static bool ParseOperatorName(State *state);
348 static bool ParseSpecialName(State *state);
349 static bool ParseCallOffset(State *state);
350 static bool ParseNVOffset(State *state);
351 static bool ParseVOffset(State *state);
352 static bool ParseCtorDtorName(State *state);
353 static bool ParseType(State *state);
354 static bool ParseCVQualifiers(State *state);
355 static bool ParseBuiltinType(State *state);
356 static bool ParseFunctionType(State *state);
357 static bool ParseBareFunctionType(State *state);
358 static bool ParseClassEnumType(State *state);
359 static bool ParseArrayType(State *state);
360 static bool ParsePointerToMemberType(State *state);
361 static bool ParseTemplateParam(State *state);
362 static bool ParseTemplateTemplateParam(State *state);
363 static bool ParseTemplateArgs(State *state);
364 static bool ParseTemplateArg(State *state);
365 static bool ParseExpression(State *state);
366 static bool ParseExprPrimary(State *state);
367 static bool ParseLocalName(State *state);
368 static bool ParseDiscriminator(State *state);
369 static bool ParseSubstitution(State *state);
371 // Implementation note: the following code is a straightforward
372 // translation of the Itanium C++ ABI defined in BNF with a couple of
375 // - Support GNU extensions not defined in the Itanium C++ ABI
376 // - <prefix> and <template-prefix> are combined to avoid infinite loop
377 // - Reorder patterns to shorten the code
378 // - Reorder patterns to give greedier functions precedence
379 // We'll mark "Less greedy than" for these cases in the code
381 // Each parsing function changes the state and returns true on
382 // success. Otherwise, don't change the state and returns false. To
383 // ensure that the state isn't changed in the latter case, we save the
384 // original state before we call more than one parsing functions
385 // consecutively with &&, and restore the state if unsuccessful. See
386 // ParseEncoding() as an example of this convention. We follow the
387 // convention throughout the code.
389 // Originally we tried to do demangling without following the full ABI
390 // syntax but it turned out we needed to follow the full syntax to
391 // parse complicated cases like nested template arguments. Note that
392 // implementing a full-fledged demangler isn't trivial (libiberty's
393 // cp-demangle.c has +4300 lines).
395 // Note that (foo) in <(foo) ...> is a modifier to be ignored.
399 // <http://www.codesourcery.com/cxx-abi/abi.html#mangling>
401 // <mangled-name> ::= _Z <encoding>
402 static bool ParseMangledName(State *state) {
403 if (ParseTwoChar(state, "_Z") && ParseEncoding(state)) {
404 // Append trailing version suffix if any.
405 // ex. _Z3foo@@GLIBCXX_3.4
406 if (state->mangled_cur < state->mangled_end &&
407 state->mangled_cur[0] == '@') {
408 MaybeAppend(state, state->mangled_cur);
409 state->mangled_cur = state->mangled_end;
416 // <encoding> ::= <(function) name> <bare-function-type>
418 // ::= <special-name>
419 static bool ParseEncoding(State *state) {
421 if (ParseName(state) && ParseBareFunctionType(state)) {
426 if (ParseName(state) || ParseSpecialName(state)) {
432 // <name> ::= <nested-name>
433 // ::= <unscoped-template-name> <template-args>
434 // ::= <unscoped-name>
436 static bool ParseName(State *state) {
437 if (ParseNestedName(state) || ParseLocalName(state)) {
442 if (ParseUnscopedTemplateName(state) &&
443 ParseTemplateArgs(state)) {
448 // Less greedy than <unscoped-template-name> <template-args>.
449 if (ParseUnscopedName(state)) {
455 // <unscoped-name> ::= <unqualified-name>
456 // ::= St <unqualified-name>
457 static bool ParseUnscopedName(State *state) {
458 if (ParseUnqualifiedName(state)) {
463 if (ParseTwoChar(state, "St") &&
464 MaybeAppend(state, "std::") &&
465 ParseUnqualifiedName(state)) {
472 // <unscoped-template-name> ::= <unscoped-name>
473 // ::= <substitution>
474 static bool ParseUnscopedTemplateName(State *state) {
475 return ParseUnscopedName(state) || ParseSubstitution(state);
478 // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
479 // ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
480 static bool ParseNestedName(State *state) {
482 if (ParseChar(state, 'N') &&
483 EnterNestedName(state) &&
484 Optional(ParseCVQualifiers(state)) &&
485 ParsePrefix(state) &&
486 LeaveNestedName(state, copy.nest_level) &&
487 ParseChar(state, 'E')) {
494 // This part is tricky. If we literally translate them to code, we'll
495 // end up infinite loop. Hence we merge them to avoid the case.
497 // <prefix> ::= <prefix> <unqualified-name>
498 // ::= <template-prefix> <template-args>
499 // ::= <template-param>
500 // ::= <substitution>
502 // <template-prefix> ::= <prefix> <(template) unqualified-name>
503 // ::= <template-param>
504 // ::= <substitution>
505 static bool ParsePrefix(State *state) {
506 bool has_something = false;
508 MaybeAppendSeparator(state);
509 if (ParseTemplateParam(state) ||
510 ParseSubstitution(state) ||
511 ParseUnscopedName(state)) {
512 has_something = true;
513 MaybeIncreaseNestLevel(state);
516 MaybeCancelLastSeparator(state);
517 if (has_something && ParseTemplateArgs(state)) {
518 return ParsePrefix(state);
526 // <unqualified-name> ::= <operator-name>
527 // ::= <ctor-dtor-name>
529 // ::= <local-source-name>
530 static bool ParseUnqualifiedName(State *state) {
531 return (ParseOperatorName(state) ||
532 ParseCtorDtorName(state) ||
533 ParseSourceName(state) ||
534 ParseLocalSourceName(state));
537 // <source-name> ::= <positive length number> <identifier>
538 static bool ParseSourceName(State *state) {
540 if (ParseNumber(state) && ParseIdentifier(state)) {
547 // <local-source-name> ::= L <source-name> [<discriminator>]
550 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
551 // http://gcc.gnu.org/viewcvs?view=rev&revision=124467
552 static bool ParseLocalSourceName(State *state) {
554 if (ParseChar(state, 'L') && ParseSourceName(state) &&
555 Optional(ParseDiscriminator(state))) {
562 // <number> ::= [n] <non-negative decimal integer>
563 static bool ParseNumber(State *state) {
565 if (ParseChar(state, 'n')) {
568 const char *p = state->mangled_cur;
570 for (;p < state->mangled_end; ++p) {
571 if ((*p >= '0' && *p <= '9')) {
572 number = number * 10 + (*p - '0');
577 if (p != state->mangled_cur) { // Conversion succeeded.
578 state->mangled_cur = p;
579 state->number = number * sign;
585 // Floating-point literals are encoded using a fixed-length lowercase
586 // hexadecimal string.
587 static bool ParseFloatNumber(State *state) {
588 const char *p = state->mangled_cur;
590 for (;p < state->mangled_end; ++p) {
591 if ((*p >= '0' && *p <= '9')) {
592 number = number * 16 + (*p - '0');
593 } else if (*p >= 'a' && *p <= 'f') {
594 number = number * 16 + (*p - 'a' + 10);
599 if (p != state->mangled_cur) { // Conversion succeeded.
600 state->mangled_cur = p;
601 state->number = number;
607 // The <seq-id> is a sequence number in base 36,
608 // using digits and upper case letters
609 static bool ParseSeqId(State *state) {
610 const char *p = state->mangled_cur;
612 for (;p < state->mangled_end; ++p) {
613 if ((*p >= '0' && *p <= '9')) {
614 number = number * 36 + (*p - '0');
615 } else if (*p >= 'A' && *p <= 'Z') {
616 number = number * 36 + (*p - 'A' + 10);
621 if (p != state->mangled_cur) { // Conversion succeeded.
622 state->mangled_cur = p;
623 state->number = number;
629 // <identifier> ::= <unqualified source code identifier>
630 static bool ParseIdentifier(State *state) {
631 if (state->number == -1 ||
632 RemainingLength(state) < state->number) {
635 if (IdentifierIsAnonymousNamespace(state)) {
636 MaybeAppend(state, "(anonymous namespace)");
638 MaybeAppendWithLength(state, state->mangled_cur, state->number);
640 state->mangled_cur += state->number;
641 state->number = -1; // Reset the number.
645 // <operator-name> ::= nw, and other two letters cases
646 // ::= cv <type> # (cast)
647 // ::= v <digit> <source-name> # vendor extended operator
648 static bool ParseOperatorName(State *state) {
649 if (RemainingLength(state) < 2) {
652 // First check with "cv" (cast) case.
654 if (ParseTwoChar(state, "cv") &&
655 MaybeAppend(state, "operator ") &&
656 EnterNestedName(state) &&
658 LeaveNestedName(state, copy.nest_level)) {
663 // Then vendor extended operators.
664 if (ParseChar(state, 'v') && ParseCharClass(state, "0123456789") &&
665 ParseSourceName(state)) {
670 // Other operator names should start with a lower alphabet followed
671 // by a lower/upper alphabet.
672 if (!(IsLower(state->mangled_cur[0]) &&
673 IsAlpha(state->mangled_cur[1]))) {
676 // We may want to perform a binary search if we really need speed.
678 for (p = kOperatorList; p->abbrev != NULL; ++p) {
679 if (state->mangled_cur[0] == p->abbrev[0] &&
680 state->mangled_cur[1] == p->abbrev[1]) {
681 MaybeAppend(state, "operator");
682 if (IsLower(*p->real_name)) { // new, delete, etc.
683 MaybeAppend(state, " ");
685 MaybeAppend(state, p->real_name);
686 state->mangled_cur += 2;
693 // <special-name> ::= TV <type>
697 // ::= Tc <call-offset> <call-offset> <(base) encoding>
698 // ::= GV <(object) name>
699 // ::= T <call-offset> <(base) encoding>
701 // ::= TC <type> <(offset) number> _ <(base) type>
706 // ::= Th <call-offset> <(base) encoding>
707 // ::= Tv <call-offset> <(base) encoding>
709 // Note: we don't care much about them since they don't appear in
710 // stack traces. The are special data.
711 static bool ParseSpecialName(State *state) {
713 if (ParseChar(state, 'T') &&
714 ParseCharClass(state, "VTIS") &&
720 if (ParseTwoChar(state, "Tc") && ParseCallOffset(state) &&
721 ParseCallOffset(state) && ParseEncoding(state)) {
726 if (ParseTwoChar(state, "GV") &&
732 if (ParseChar(state, 'T') && ParseCallOffset(state) &&
733 ParseEncoding(state)) {
739 if (ParseTwoChar(state, "TC") && ParseType(state) &&
740 ParseNumber(state) && ParseChar(state, '_') &&
741 DisableAppend(state) &&
743 RestoreAppend(state, copy.append);
748 if (ParseChar(state, 'T') && ParseCharClass(state, "FJ") &&
754 if (ParseTwoChar(state, "GR") && ParseName(state)) {
759 if (ParseTwoChar(state, "GA") && ParseEncoding(state)) {
764 if (ParseChar(state, 'T') && ParseCharClass(state, "hv") &&
765 ParseCallOffset(state) && ParseEncoding(state)) {
772 // <call-offset> ::= h <nv-offset> _
773 // ::= v <v-offset> _
774 static bool ParseCallOffset(State *state) {
776 if (ParseChar(state, 'h') &&
777 ParseNVOffset(state) && ParseChar(state, '_')) {
782 if (ParseChar(state, 'v') &&
783 ParseVOffset(state) && ParseChar(state, '_')) {
791 // <nv-offset> ::= <(offset) number>
792 static bool ParseNVOffset(State *state) {
793 return ParseNumber(state);
796 // <v-offset> ::= <(offset) number> _ <(virtual offset) number>
797 static bool ParseVOffset(State *state) {
799 if (ParseNumber(state) && ParseChar(state, '_') &&
800 ParseNumber(state)) {
807 // <ctor-dtor-name> ::= C1 | C2 | C3
809 static bool ParseCtorDtorName(State *state) {
811 if (ParseChar(state, 'C') &&
812 ParseCharClass(state, "123")) {
813 const char * const prev_name = state->prev_name;
814 const int prev_name_length = state->prev_name_length;
815 MaybeAppendWithLength(state, prev_name, prev_name_length);
820 if (ParseChar(state, 'D') &&
821 ParseCharClass(state, "012")) {
822 const char * const prev_name = state->prev_name;
823 const int prev_name_length = state->prev_name_length;
824 MaybeAppend(state, "~");
825 MaybeAppendWithLength(state, prev_name, prev_name_length);
832 // <type> ::= <CV-qualifiers> <type>
837 // ::= U <source-name> <type>
838 // ::= <builtin-type>
839 // ::= <function-type>
840 // ::= <class-enum-type>
842 // ::= <pointer-to-member-type>
843 // ::= <template-template-param> <template-args>
844 // ::= <template-param>
845 // ::= <substitution>
846 static bool ParseType(State *state) {
847 // We should check CV-qualifers, and PRGC things first.
849 if (ParseCVQualifiers(state) && ParseType(state)) {
854 if (ParseCharClass(state, "PRCG") && ParseType(state)) {
859 if (ParseChar(state, 'U') && ParseSourceName(state) &&
865 if (ParseBuiltinType(state) ||
866 ParseFunctionType(state) ||
867 ParseClassEnumType(state) ||
868 ParseArrayType(state) ||
869 ParsePointerToMemberType(state) ||
870 ParseSubstitution(state)) {
874 if (ParseTemplateTemplateParam(state) &&
875 ParseTemplateArgs(state)) {
880 // Less greedy than <template-template-param> <template-args>.
881 if (ParseTemplateParam(state)) {
888 // <CV-qualifiers> ::= [r] [V] [K]
889 // We don't allow empty <CV-qualifiers> to avoid infinite loop in
891 static bool ParseCVQualifiers(State *state) {
892 int num_cv_qualifiers = 0;
893 num_cv_qualifiers += ParseChar(state, 'r');
894 num_cv_qualifiers += ParseChar(state, 'V');
895 num_cv_qualifiers += ParseChar(state, 'K');
896 return num_cv_qualifiers > 0;
899 // <builtin-type> ::= v, etc.
900 // ::= u <source-name>
901 static bool ParseBuiltinType(State *state) {
903 for (p = kBuiltinTypeList; p->abbrev != NULL; ++p) {
904 if (state->mangled_cur[0] == p->abbrev[0]) {
905 MaybeAppend(state, p->real_name);
906 ++state->mangled_cur;
912 if (ParseChar(state, 'u') && ParseSourceName(state)) {
919 // <function-type> ::= F [Y] <bare-function-type> E
920 static bool ParseFunctionType(State *state) {
922 if (ParseChar(state, 'F') && Optional(ParseChar(state, 'Y')) &&
923 ParseBareFunctionType(state) && ParseChar(state, 'E')) {
930 // <bare-function-type> ::= <(signature) type>+
931 static bool ParseBareFunctionType(State *state) {
933 DisableAppend(state);
934 if (OneOrMore(ParseType, state)) {
935 RestoreAppend(state, copy.append);
936 MaybeAppend(state, "()");
943 // <class-enum-type> ::= <name>
944 static bool ParseClassEnumType(State *state) {
945 return ParseName(state);
948 // <array-type> ::= A <(positive dimension) number> _ <(element) type>
949 // ::= A [<(dimension) expression>] _ <(element) type>
950 static bool ParseArrayType(State *state) {
952 if (ParseChar(state, 'A') && ParseNumber(state) &&
953 ParseChar(state, '_') && ParseType(state)) {
958 if (ParseChar(state, 'A') && Optional(ParseExpression(state)) &&
959 ParseChar(state, '_') && ParseType(state)) {
966 // <pointer-to-member-type> ::= M <(class) type> <(member) type>
967 static bool ParsePointerToMemberType(State *state) {
969 if (ParseChar(state, 'M') && ParseType(state) &&
977 // <template-param> ::= T_
978 // ::= T <parameter-2 non-negative number> _
979 static bool ParseTemplateParam(State *state) {
980 if (ParseTwoChar(state, "T_")) {
981 MaybeAppend(state, "?"); // We don't support template substitutions.
986 if (ParseChar(state, 'T') && ParseNumber(state) &&
987 ParseChar(state, '_')) {
988 MaybeAppend(state, "?"); // We don't support template substitutions.
996 // <template-template-param> ::= <template-param>
997 // ::= <substitution>
998 static bool ParseTemplateTemplateParam(State *state) {
999 return (ParseTemplateParam(state) ||
1000 ParseSubstitution(state));
1003 // <template-args> ::= I <template-arg>+ E
1004 static bool ParseTemplateArgs(State *state) {
1005 State copy = *state;
1006 DisableAppend(state);
1007 if (ParseChar(state, 'I') &&
1008 OneOrMore(ParseTemplateArg, state) &&
1009 ParseChar(state, 'E')) {
1010 RestoreAppend(state, copy.append);
1011 MaybeAppend(state, "<>");
1018 // <template-arg> ::= <type>
1019 // ::= <expr-primary>
1020 // ::= X <expression> E
1021 static bool ParseTemplateArg(State *state) {
1022 if (ParseType(state) ||
1023 ParseExprPrimary(state)) {
1027 State copy = *state;
1028 if (ParseChar(state, 'X') && ParseExpression(state) &&
1029 ParseChar(state, 'E')) {
1036 // <expression> ::= <template-param>
1037 // ::= <expr-primary>
1038 // ::= <unary operator-name> <expression>
1039 // ::= <binary operator-name> <expression> <expression>
1040 // ::= <trinary operator-name> <expression> <expression>
1043 // ::= sr <type> <unqualified-name> <template-args>
1044 // ::= sr <type> <unqualified-name>
1045 static bool ParseExpression(State *state) {
1046 if (ParseTemplateParam(state) || ParseExprPrimary(state)) {
1050 State copy = *state;
1051 if (ParseOperatorName(state) &&
1052 ParseExpression(state) &&
1053 ParseExpression(state) &&
1054 ParseExpression(state)) {
1059 if (ParseOperatorName(state) &&
1060 ParseExpression(state) &&
1061 ParseExpression(state)) {
1066 if (ParseOperatorName(state) &&
1067 ParseExpression(state)) {
1072 if (ParseTwoChar(state, "st") && ParseType(state)) {
1077 if (ParseTwoChar(state, "sr") && ParseType(state) &&
1078 ParseUnqualifiedName(state) &&
1079 ParseTemplateArgs(state)) {
1084 if (ParseTwoChar(state, "sr") && ParseType(state) &&
1085 ParseUnqualifiedName(state)) {
1092 // <expr-primary> ::= L <type> <(value) number> E
1093 // ::= L <type> <(value) float> E
1094 // ::= L <mangled-name> E
1095 // // A bug in g++'s C++ ABI version 2 (-fabi-version=2).
1096 // ::= LZ <encoding> E
1097 static bool ParseExprPrimary(State *state) {
1098 State copy = *state;
1099 if (ParseChar(state, 'L') && ParseType(state) &&
1100 ParseNumber(state) &&
1101 ParseChar(state, 'E')) {
1106 if (ParseChar(state, 'L') && ParseType(state) &&
1107 ParseFloatNumber(state) &&
1108 ParseChar(state, 'E')) {
1113 if (ParseChar(state, 'L') && ParseMangledName(state) &&
1114 ParseChar(state, 'E')) {
1119 if (ParseTwoChar(state, "LZ") && ParseEncoding(state) &&
1120 ParseChar(state, 'E')) {
1128 // <local-name> := Z <(function) encoding> E <(entity) name>
1129 // [<discriminator>]
1130 // := Z <(function) encoding> E s [<discriminator>]
1131 static bool ParseLocalName(State *state) {
1132 State copy = *state;
1133 if (ParseChar(state, 'Z') && ParseEncoding(state) &&
1134 ParseChar(state, 'E') && MaybeAppend(state, "::") &&
1135 ParseName(state) && Optional(ParseDiscriminator(state))) {
1140 if (ParseChar(state, 'Z') && ParseEncoding(state) &&
1141 ParseTwoChar(state, "Es") && Optional(ParseDiscriminator(state))) {
1148 // <discriminator> := _ <(non-negative) number>
1149 static bool ParseDiscriminator(State *state) {
1150 State copy = *state;
1151 if (ParseChar(state, '_') && ParseNumber(state)) {
1158 // <substitution> ::= S_
1161 static bool ParseSubstitution(State *state) {
1162 if (ParseTwoChar(state, "S_")) {
1163 MaybeAppend(state, "?"); // We don't support substitutions.
1167 State copy = *state;
1168 if (ParseChar(state, 'S') && ParseSeqId(state) &&
1169 ParseChar(state, '_')) {
1170 MaybeAppend(state, "?"); // We don't support substitutions.
1175 // Expand abbreviations like "St" => "std".
1176 if (ParseChar(state, 'S')) {
1177 const AbbrevPair *p;
1178 for (p = kSubstitutionList; p->abbrev != NULL; ++p) {
1179 if (state->mangled_cur[0] == p->abbrev[1]) {
1180 MaybeAppend(state, "std");
1181 if (p->real_name[0] != '\0') {
1182 MaybeAppend(state, "::");
1183 MaybeAppend(state, p->real_name);
1185 state->mangled_cur += 1;
1194 // The demangler entry point.
1195 bool Demangle(const char *mangled, char *out, int out_size) {
1197 InitState(&state, mangled, out, out_size);
1198 return (ParseMangledName(&state) &&
1199 state.overflowed == false &&
1200 RemainingLength(&state) == 0);
1203 _END_GOOGLE_NAMESPACE_