1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
14 // * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 // Author: Satoru Takabayashi
32 // For reference check out:
33 // http://www.codesourcery.com/public/cxx-abi/abi.html#mangling
35 // Note that we only have partial C++0x support yet.
37 #include <stdio.h> // for NULL
40 _START_GOOGLE_NAMESPACE_
44 const char *real_name
;
47 // List of operators from Itanium C++ ABI.
48 static const AbbrevPair kOperatorList
[] = {
101 // List of builtin types from Itanium C++ ABI.
102 static const AbbrevPair kBuiltinTypeList
[] = {
107 { "a", "signed char" },
108 { "h", "unsigned char" },
110 { "t", "unsigned short" },
112 { "j", "unsigned int" },
114 { "m", "unsigned long" },
115 { "x", "long long" },
116 { "y", "unsigned long long" },
118 { "o", "unsigned __int128" },
121 { "e", "long double" },
122 { "g", "__float128" },
127 // List of substitutions Itanium C++ ABI.
128 static const AbbrevPair kSubstitutionList
[] = {
130 { "Sa", "allocator" },
131 { "Sb", "basic_string" },
132 // std::basic_string<char, std::char_traits<char>,std::allocator<char> >
134 // std::basic_istream<char, std::char_traits<char> >
136 // std::basic_ostream<char, std::char_traits<char> >
138 // std::basic_iostream<char, std::char_traits<char> >
139 { "Sd", "iostream" },
143 // State needed for demangling.
145 const char *mangled_cur
; // Cursor of mangled name.
146 char *out_cur
; // Cursor of output string.
147 const char *out_begin
; // Beginning of output string.
148 const char *out_end
; // End of output string.
149 const char *prev_name
; // For constructors/destructors.
150 int prev_name_length
; // For constructors/destructors.
151 short nest_level
; // For nested names.
152 bool append
; // Append flag.
153 bool overflowed
; // True if output gets overflowed.
156 // We don't use strlen() in libc since it's not guaranteed to be async
158 static size_t StrLen(const char *str
) {
160 while (*str
!= '\0') {
167 // Returns true if "str" has at least "n" characters remaining.
168 static bool AtLeastNumCharsRemaining(const char *str
, int n
) {
169 for (int i
= 0; i
< n
; ++i
) {
170 if (str
[i
] == '\0') {
177 // Returns true if "str" has "prefix" as a prefix.
178 static bool StrPrefix(const char *str
, const char *prefix
) {
180 while (str
[i
] != '\0' && prefix
[i
] != '\0' &&
181 str
[i
] == prefix
[i
]) {
184 return prefix
[i
] == '\0'; // Consumed everything in "prefix".
187 static void InitState(State
*state
, const char *mangled
,
188 char *out
, int out_size
) {
189 state
->mangled_cur
= mangled
;
190 state
->out_cur
= out
;
191 state
->out_begin
= out
;
192 state
->out_end
= out
+ out_size
;
193 state
->prev_name
= NULL
;
194 state
->prev_name_length
= -1;
195 state
->nest_level
= -1;
196 state
->append
= true;
197 state
->overflowed
= false;
200 // Returns true and advances "mangled_cur" if we find "one_char_token"
201 // at "mangled_cur" position. It is assumed that "one_char_token" does
203 static bool ParseOneCharToken(State
*state
, const char one_char_token
) {
204 if (state
->mangled_cur
[0] == one_char_token
) {
205 ++state
->mangled_cur
;
211 // Returns true and advances "mangled_cur" if we find "two_char_token"
212 // at "mangled_cur" position. It is assumed that "two_char_token" does
214 static bool ParseTwoCharToken(State
*state
, const char *two_char_token
) {
215 if (state
->mangled_cur
[0] == two_char_token
[0] &&
216 state
->mangled_cur
[1] == two_char_token
[1]) {
217 state
->mangled_cur
+= 2;
223 // Returns true and advances "mangled_cur" if we find any character in
224 // "char_class" at "mangled_cur" position.
225 static bool ParseCharClass(State
*state
, const char *char_class
) {
226 const char *p
= char_class
;
227 for (; *p
!= '\0'; ++p
) {
228 if (state
->mangled_cur
[0] == *p
) {
229 ++state
->mangled_cur
;
236 // This function is used for handling an optional non-terminal.
237 static bool Optional(bool) {
241 // This function is used for handling <non-terminal>+ syntax.
242 typedef bool (*ParseFunc
)(State
*);
243 static bool OneOrMore(ParseFunc parse_func
, State
*state
) {
244 if (parse_func(state
)) {
245 while (parse_func(state
)) {
252 // This function is used for handling <non-terminal>* syntax. The function
253 // always returns true and must be followed by a termination token or a
254 // terminating sequence not handled by parse_func (e.g.
255 // ParseOneCharToken(state, 'E')).
256 static bool ZeroOrMore(ParseFunc parse_func
, State
*state
) {
257 while (parse_func(state
)) {
262 // Append "str" at "out_cur". If there is an overflow, "overflowed"
263 // is set to true for later use. The output string is ensured to
264 // always terminate with '\0' as long as there is no overflow.
265 static void Append(State
*state
, const char * const str
, const int length
) {
267 for (i
= 0; i
< length
; ++i
) {
268 if (state
->out_cur
+ 1 < state
->out_end
) { // +1 for '\0'
269 *state
->out_cur
= str
[i
];
272 state
->overflowed
= true;
276 if (!state
->overflowed
) {
277 *state
->out_cur
= '\0'; // Terminate it with '\0'
281 // We don't use equivalents in libc to avoid locale issues.
282 static bool IsLower(char c
) {
283 return c
>= 'a' && c
<= 'z';
286 static bool IsAlpha(char c
) {
287 return (c
>= 'a' && c
<= 'z') || (c
>= 'A' && c
<= 'Z');
290 static bool IsDigit(char c
) {
291 return c
>= '0' && c
<= '9';
294 // Returns true if "str" is a function clone suffix. These suffixes are used
295 // by GCC 4.5.x and later versions to indicate functions which have been
296 // cloned during optimization. We treat any sequence (.<alpha>+.<digit>+)+ as
297 // a function clone suffix.
298 static bool IsFunctionCloneSuffix(const char *str
) {
300 while (str
[i
] != '\0') {
301 // Consume a single .<alpha>+.<digit>+ sequence.
302 if (str
[i
] != '.' || !IsAlpha(str
[i
+ 1])) {
306 while (IsAlpha(str
[i
])) {
309 if (str
[i
] != '.' || !IsDigit(str
[i
+ 1])) {
313 while (IsDigit(str
[i
])) {
317 return true; // Consumed everything in "str".
320 // Append "str" with some tweaks, iff "append" state is true.
321 // Returns true so that it can be placed in "if" conditions.
322 static void MaybeAppendWithLength(State
*state
, const char * const str
,
324 if (state
->append
&& length
> 0) {
325 // Append a space if the output buffer ends with '<' and "str"
326 // starts with '<' to avoid <<<.
327 if (str
[0] == '<' && state
->out_begin
< state
->out_cur
&&
328 state
->out_cur
[-1] == '<') {
329 Append(state
, " ", 1);
331 // Remember the last identifier name for ctors/dtors.
332 if (IsAlpha(str
[0]) || str
[0] == '_') {
333 state
->prev_name
= state
->out_cur
;
334 state
->prev_name_length
= length
;
336 Append(state
, str
, length
);
340 // A convenient wrapper arount MaybeAppendWithLength().
341 static bool MaybeAppend(State
*state
, const char * const str
) {
343 int length
= StrLen(str
);
344 MaybeAppendWithLength(state
, str
, length
);
349 // This function is used for handling nested names.
350 static bool EnterNestedName(State
*state
) {
351 state
->nest_level
= 0;
355 // This function is used for handling nested names.
356 static bool LeaveNestedName(State
*state
, short prev_value
) {
357 state
->nest_level
= prev_value
;
361 // Disable the append mode not to print function parameters, etc.
362 static bool DisableAppend(State
*state
) {
363 state
->append
= false;
367 // Restore the append mode to the previous state.
368 static bool RestoreAppend(State
*state
, bool prev_value
) {
369 state
->append
= prev_value
;
373 // Increase the nest level for nested names.
374 static void MaybeIncreaseNestLevel(State
*state
) {
375 if (state
->nest_level
> -1) {
380 // Appends :: for nested names if necessary.
381 static void MaybeAppendSeparator(State
*state
) {
382 if (state
->nest_level
>= 1) {
383 MaybeAppend(state
, "::");
387 // Cancel the last separator if necessary.
388 static void MaybeCancelLastSeparator(State
*state
) {
389 if (state
->nest_level
>= 1 && state
->append
&&
390 state
->out_begin
<= state
->out_cur
- 2) {
392 *state
->out_cur
= '\0';
396 // Returns true if the identifier of the given length pointed to by
397 // "mangled_cur" is anonymous namespace.
398 static bool IdentifierIsAnonymousNamespace(State
*state
, int length
) {
399 static const char anon_prefix
[] = "_GLOBAL__N_";
400 return (length
> (int)sizeof(anon_prefix
) - 1 && // Should be longer.
401 StrPrefix(state
->mangled_cur
, anon_prefix
));
404 // Forward declarations of our parsing functions.
405 static bool ParseMangledName(State
*state
);
406 static bool ParseEncoding(State
*state
);
407 static bool ParseName(State
*state
);
408 static bool ParseUnscopedName(State
*state
);
409 static bool ParseUnscopedTemplateName(State
*state
);
410 static bool ParseNestedName(State
*state
);
411 static bool ParsePrefix(State
*state
);
412 static bool ParseUnqualifiedName(State
*state
);
413 static bool ParseSourceName(State
*state
);
414 static bool ParseLocalSourceName(State
*state
);
415 static bool ParseNumber(State
*state
, int *number_out
);
416 static bool ParseFloatNumber(State
*state
);
417 static bool ParseSeqId(State
*state
);
418 static bool ParseIdentifier(State
*state
, int length
);
419 static bool ParseOperatorName(State
*state
);
420 static bool ParseSpecialName(State
*state
);
421 static bool ParseCallOffset(State
*state
);
422 static bool ParseNVOffset(State
*state
);
423 static bool ParseVOffset(State
*state
);
424 static bool ParseCtorDtorName(State
*state
);
425 static bool ParseType(State
*state
);
426 static bool ParseCVQualifiers(State
*state
);
427 static bool ParseBuiltinType(State
*state
);
428 static bool ParseFunctionType(State
*state
);
429 static bool ParseBareFunctionType(State
*state
);
430 static bool ParseClassEnumType(State
*state
);
431 static bool ParseArrayType(State
*state
);
432 static bool ParsePointerToMemberType(State
*state
);
433 static bool ParseTemplateParam(State
*state
);
434 static bool ParseTemplateTemplateParam(State
*state
);
435 static bool ParseTemplateArgs(State
*state
);
436 static bool ParseTemplateArg(State
*state
);
437 static bool ParseExpression(State
*state
);
438 static bool ParseExprPrimary(State
*state
);
439 static bool ParseLocalName(State
*state
);
440 static bool ParseDiscriminator(State
*state
);
441 static bool ParseSubstitution(State
*state
);
443 // Implementation note: the following code is a straightforward
444 // translation of the Itanium C++ ABI defined in BNF with a couple of
447 // - Support GNU extensions not defined in the Itanium C++ ABI
448 // - <prefix> and <template-prefix> are combined to avoid infinite loop
449 // - Reorder patterns to shorten the code
450 // - Reorder patterns to give greedier functions precedence
451 // We'll mark "Less greedy than" for these cases in the code
453 // Each parsing function changes the state and returns true on
454 // success. Otherwise, don't change the state and returns false. To
455 // ensure that the state isn't changed in the latter case, we save the
456 // original state before we call more than one parsing functions
457 // consecutively with &&, and restore the state if unsuccessful. See
458 // ParseEncoding() as an example of this convention. We follow the
459 // convention throughout the code.
461 // Originally we tried to do demangling without following the full ABI
462 // syntax but it turned out we needed to follow the full syntax to
463 // parse complicated cases like nested template arguments. Note that
464 // implementing a full-fledged demangler isn't trivial (libiberty's
465 // cp-demangle.c has +4300 lines).
467 // Note that (foo) in <(foo) ...> is a modifier to be ignored.
471 // <http://www.codesourcery.com/cxx-abi/abi.html#mangling>
473 // <mangled-name> ::= _Z <encoding>
474 static bool ParseMangledName(State
*state
) {
475 return ParseTwoCharToken(state
, "_Z") && ParseEncoding(state
);
478 // <encoding> ::= <(function) name> <bare-function-type>
480 // ::= <special-name>
481 static bool ParseEncoding(State
*state
) {
483 if (ParseName(state
) && ParseBareFunctionType(state
)) {
488 if (ParseName(state
) || ParseSpecialName(state
)) {
494 // <name> ::= <nested-name>
495 // ::= <unscoped-template-name> <template-args>
496 // ::= <unscoped-name>
498 static bool ParseName(State
*state
) {
499 if (ParseNestedName(state
) || ParseLocalName(state
)) {
504 if (ParseUnscopedTemplateName(state
) &&
505 ParseTemplateArgs(state
)) {
510 // Less greedy than <unscoped-template-name> <template-args>.
511 if (ParseUnscopedName(state
)) {
517 // <unscoped-name> ::= <unqualified-name>
518 // ::= St <unqualified-name>
519 static bool ParseUnscopedName(State
*state
) {
520 if (ParseUnqualifiedName(state
)) {
525 if (ParseTwoCharToken(state
, "St") &&
526 MaybeAppend(state
, "std::") &&
527 ParseUnqualifiedName(state
)) {
534 // <unscoped-template-name> ::= <unscoped-name>
535 // ::= <substitution>
536 static bool ParseUnscopedTemplateName(State
*state
) {
537 return ParseUnscopedName(state
) || ParseSubstitution(state
);
540 // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E
541 // ::= N [<CV-qualifiers>] <template-prefix> <template-args> E
542 static bool ParseNestedName(State
*state
) {
544 if (ParseOneCharToken(state
, 'N') &&
545 EnterNestedName(state
) &&
546 Optional(ParseCVQualifiers(state
)) &&
547 ParsePrefix(state
) &&
548 LeaveNestedName(state
, copy
.nest_level
) &&
549 ParseOneCharToken(state
, 'E')) {
556 // This part is tricky. If we literally translate them to code, we'll
557 // end up infinite loop. Hence we merge them to avoid the case.
559 // <prefix> ::= <prefix> <unqualified-name>
560 // ::= <template-prefix> <template-args>
561 // ::= <template-param>
562 // ::= <substitution>
564 // <template-prefix> ::= <prefix> <(template) unqualified-name>
565 // ::= <template-param>
566 // ::= <substitution>
567 static bool ParsePrefix(State
*state
) {
568 bool has_something
= false;
570 MaybeAppendSeparator(state
);
571 if (ParseTemplateParam(state
) ||
572 ParseSubstitution(state
) ||
573 ParseUnscopedName(state
)) {
574 has_something
= true;
575 MaybeIncreaseNestLevel(state
);
578 MaybeCancelLastSeparator(state
);
579 if (has_something
&& ParseTemplateArgs(state
)) {
580 return ParsePrefix(state
);
588 // <unqualified-name> ::= <operator-name>
589 // ::= <ctor-dtor-name>
591 // ::= <local-source-name>
592 static bool ParseUnqualifiedName(State
*state
) {
593 return (ParseOperatorName(state
) ||
594 ParseCtorDtorName(state
) ||
595 ParseSourceName(state
) ||
596 ParseLocalSourceName(state
));
599 // <source-name> ::= <positive length number> <identifier>
600 static bool ParseSourceName(State
*state
) {
603 if (ParseNumber(state
, &length
) && ParseIdentifier(state
, length
)) {
610 // <local-source-name> ::= L <source-name> [<discriminator>]
613 // http://gcc.gnu.org/bugzilla/show_bug.cgi?id=31775
614 // http://gcc.gnu.org/viewcvs?view=rev&revision=124467
615 static bool ParseLocalSourceName(State
*state
) {
617 if (ParseOneCharToken(state
, 'L') && ParseSourceName(state
) &&
618 Optional(ParseDiscriminator(state
))) {
625 // <number> ::= [n] <non-negative decimal integer>
626 // If "number_out" is non-null, then *number_out is set to the value of the
627 // parsed number on success.
628 static bool ParseNumber(State
*state
, int *number_out
) {
630 if (ParseOneCharToken(state
, 'n')) {
633 const char *p
= state
->mangled_cur
;
635 for (;*p
!= '\0'; ++p
) {
637 number
= number
* 10 + (*p
- '0');
642 if (p
!= state
->mangled_cur
) { // Conversion succeeded.
643 state
->mangled_cur
= p
;
644 if (number_out
!= NULL
) {
645 *number_out
= number
* sign
;
652 // Floating-point literals are encoded using a fixed-length lowercase
653 // hexadecimal string.
654 static bool ParseFloatNumber(State
*state
) {
655 const char *p
= state
->mangled_cur
;
656 for (;*p
!= '\0'; ++p
) {
657 if (!IsDigit(*p
) && !(*p
>= 'a' && *p
<= 'f')) {
661 if (p
!= state
->mangled_cur
) { // Conversion succeeded.
662 state
->mangled_cur
= p
;
668 // The <seq-id> is a sequence number in base 36,
669 // using digits and upper case letters
670 static bool ParseSeqId(State
*state
) {
671 const char *p
= state
->mangled_cur
;
672 for (;*p
!= '\0'; ++p
) {
673 if (!IsDigit(*p
) && !(*p
>= 'A' && *p
<= 'Z')) {
677 if (p
!= state
->mangled_cur
) { // Conversion succeeded.
678 state
->mangled_cur
= p
;
684 // <identifier> ::= <unqualified source code identifier> (of given length)
685 static bool ParseIdentifier(State
*state
, int length
) {
687 !AtLeastNumCharsRemaining(state
->mangled_cur
, length
)) {
690 if (IdentifierIsAnonymousNamespace(state
, length
)) {
691 MaybeAppend(state
, "(anonymous namespace)");
693 MaybeAppendWithLength(state
, state
->mangled_cur
, length
);
695 state
->mangled_cur
+= length
;
699 // <operator-name> ::= nw, and other two letters cases
700 // ::= cv <type> # (cast)
701 // ::= v <digit> <source-name> # vendor extended operator
702 static bool ParseOperatorName(State
*state
) {
703 if (!AtLeastNumCharsRemaining(state
->mangled_cur
, 2)) {
706 // First check with "cv" (cast) case.
708 if (ParseTwoCharToken(state
, "cv") &&
709 MaybeAppend(state
, "operator ") &&
710 EnterNestedName(state
) &&
712 LeaveNestedName(state
, copy
.nest_level
)) {
717 // Then vendor extended operators.
718 if (ParseOneCharToken(state
, 'v') && ParseCharClass(state
, "0123456789") &&
719 ParseSourceName(state
)) {
724 // Other operator names should start with a lower alphabet followed
725 // by a lower/upper alphabet.
726 if (!(IsLower(state
->mangled_cur
[0]) &&
727 IsAlpha(state
->mangled_cur
[1]))) {
730 // We may want to perform a binary search if we really need speed.
732 for (p
= kOperatorList
; p
->abbrev
!= NULL
; ++p
) {
733 if (state
->mangled_cur
[0] == p
->abbrev
[0] &&
734 state
->mangled_cur
[1] == p
->abbrev
[1]) {
735 MaybeAppend(state
, "operator");
736 if (IsLower(*p
->real_name
)) { // new, delete, etc.
737 MaybeAppend(state
, " ");
739 MaybeAppend(state
, p
->real_name
);
740 state
->mangled_cur
+= 2;
747 // <special-name> ::= TV <type>
751 // ::= Tc <call-offset> <call-offset> <(base) encoding>
752 // ::= GV <(object) name>
753 // ::= T <call-offset> <(base) encoding>
755 // ::= TC <type> <(offset) number> _ <(base) type>
760 // ::= Th <call-offset> <(base) encoding>
761 // ::= Tv <call-offset> <(base) encoding>
763 // Note: we don't care much about them since they don't appear in
764 // stack traces. The are special data.
765 static bool ParseSpecialName(State
*state
) {
767 if (ParseOneCharToken(state
, 'T') &&
768 ParseCharClass(state
, "VTIS") &&
774 if (ParseTwoCharToken(state
, "Tc") && ParseCallOffset(state
) &&
775 ParseCallOffset(state
) && ParseEncoding(state
)) {
780 if (ParseTwoCharToken(state
, "GV") &&
786 if (ParseOneCharToken(state
, 'T') && ParseCallOffset(state
) &&
787 ParseEncoding(state
)) {
793 if (ParseTwoCharToken(state
, "TC") && ParseType(state
) &&
794 ParseNumber(state
, NULL
) && ParseOneCharToken(state
, '_') &&
795 DisableAppend(state
) &&
797 RestoreAppend(state
, copy
.append
);
802 if (ParseOneCharToken(state
, 'T') && ParseCharClass(state
, "FJ") &&
808 if (ParseTwoCharToken(state
, "GR") && ParseName(state
)) {
813 if (ParseTwoCharToken(state
, "GA") && ParseEncoding(state
)) {
818 if (ParseOneCharToken(state
, 'T') && ParseCharClass(state
, "hv") &&
819 ParseCallOffset(state
) && ParseEncoding(state
)) {
826 // <call-offset> ::= h <nv-offset> _
827 // ::= v <v-offset> _
828 static bool ParseCallOffset(State
*state
) {
830 if (ParseOneCharToken(state
, 'h') &&
831 ParseNVOffset(state
) && ParseOneCharToken(state
, '_')) {
836 if (ParseOneCharToken(state
, 'v') &&
837 ParseVOffset(state
) && ParseOneCharToken(state
, '_')) {
845 // <nv-offset> ::= <(offset) number>
846 static bool ParseNVOffset(State
*state
) {
847 return ParseNumber(state
, NULL
);
850 // <v-offset> ::= <(offset) number> _ <(virtual offset) number>
851 static bool ParseVOffset(State
*state
) {
853 if (ParseNumber(state
, NULL
) && ParseOneCharToken(state
, '_') &&
854 ParseNumber(state
, NULL
)) {
861 // <ctor-dtor-name> ::= C1 | C2 | C3
863 static bool ParseCtorDtorName(State
*state
) {
865 if (ParseOneCharToken(state
, 'C') &&
866 ParseCharClass(state
, "123")) {
867 const char * const prev_name
= state
->prev_name
;
868 const int prev_name_length
= state
->prev_name_length
;
869 MaybeAppendWithLength(state
, prev_name
, prev_name_length
);
874 if (ParseOneCharToken(state
, 'D') &&
875 ParseCharClass(state
, "012")) {
876 const char * const prev_name
= state
->prev_name
;
877 const int prev_name_length
= state
->prev_name_length
;
878 MaybeAppend(state
, "~");
879 MaybeAppendWithLength(state
, prev_name
, prev_name_length
);
886 // <type> ::= <CV-qualifiers> <type>
887 // ::= P <type> # pointer-to
888 // ::= R <type> # reference-to
889 // ::= O <type> # rvalue reference-to (C++0x)
890 // ::= C <type> # complex pair (C 2000)
891 // ::= G <type> # imaginary (C 2000)
892 // ::= U <source-name> <type> # vendor extended type qualifier
893 // ::= <builtin-type>
894 // ::= <function-type>
895 // ::= <class-enum-type>
897 // ::= <pointer-to-member-type>
898 // ::= <template-template-param> <template-args>
899 // ::= <template-param>
900 // ::= <substitution>
901 // ::= Dp <type> # pack expansion of (C++0x)
902 // ::= Dt <expression> E # decltype of an id-expression or class
903 // # member access (C++0x)
904 // ::= DT <expression> E # decltype of an expression (C++0x)
906 static bool ParseType(State
*state
) {
907 // We should check CV-qualifers, and PRGC things first.
909 if (ParseCVQualifiers(state
) && ParseType(state
)) {
914 if (ParseCharClass(state
, "OPRCG") && ParseType(state
)) {
919 if (ParseTwoCharToken(state
, "Dp") && ParseType(state
)) {
924 if (ParseOneCharToken(state
, 'D') && ParseCharClass(state
, "tT") &&
925 ParseExpression(state
) && ParseOneCharToken(state
, 'E')) {
930 if (ParseOneCharToken(state
, 'U') && ParseSourceName(state
) &&
936 if (ParseBuiltinType(state
) ||
937 ParseFunctionType(state
) ||
938 ParseClassEnumType(state
) ||
939 ParseArrayType(state
) ||
940 ParsePointerToMemberType(state
) ||
941 ParseSubstitution(state
)) {
945 if (ParseTemplateTemplateParam(state
) &&
946 ParseTemplateArgs(state
)) {
951 // Less greedy than <template-template-param> <template-args>.
952 if (ParseTemplateParam(state
)) {
959 // <CV-qualifiers> ::= [r] [V] [K]
960 // We don't allow empty <CV-qualifiers> to avoid infinite loop in
962 static bool ParseCVQualifiers(State
*state
) {
963 int num_cv_qualifiers
= 0;
964 num_cv_qualifiers
+= ParseOneCharToken(state
, 'r');
965 num_cv_qualifiers
+= ParseOneCharToken(state
, 'V');
966 num_cv_qualifiers
+= ParseOneCharToken(state
, 'K');
967 return num_cv_qualifiers
> 0;
970 // <builtin-type> ::= v, etc.
971 // ::= u <source-name>
972 static bool ParseBuiltinType(State
*state
) {
974 for (p
= kBuiltinTypeList
; p
->abbrev
!= NULL
; ++p
) {
975 if (state
->mangled_cur
[0] == p
->abbrev
[0]) {
976 MaybeAppend(state
, p
->real_name
);
977 ++state
->mangled_cur
;
983 if (ParseOneCharToken(state
, 'u') && ParseSourceName(state
)) {
990 // <function-type> ::= F [Y] <bare-function-type> E
991 static bool ParseFunctionType(State
*state
) {
993 if (ParseOneCharToken(state
, 'F') &&
994 Optional(ParseOneCharToken(state
, 'Y')) &&
995 ParseBareFunctionType(state
) && ParseOneCharToken(state
, 'E')) {
1002 // <bare-function-type> ::= <(signature) type>+
1003 static bool ParseBareFunctionType(State
*state
) {
1004 State copy
= *state
;
1005 DisableAppend(state
);
1006 if (OneOrMore(ParseType
, state
)) {
1007 RestoreAppend(state
, copy
.append
);
1008 MaybeAppend(state
, "()");
1015 // <class-enum-type> ::= <name>
1016 static bool ParseClassEnumType(State
*state
) {
1017 return ParseName(state
);
1020 // <array-type> ::= A <(positive dimension) number> _ <(element) type>
1021 // ::= A [<(dimension) expression>] _ <(element) type>
1022 static bool ParseArrayType(State
*state
) {
1023 State copy
= *state
;
1024 if (ParseOneCharToken(state
, 'A') && ParseNumber(state
, NULL
) &&
1025 ParseOneCharToken(state
, '_') && ParseType(state
)) {
1030 if (ParseOneCharToken(state
, 'A') && Optional(ParseExpression(state
)) &&
1031 ParseOneCharToken(state
, '_') && ParseType(state
)) {
1038 // <pointer-to-member-type> ::= M <(class) type> <(member) type>
1039 static bool ParsePointerToMemberType(State
*state
) {
1040 State copy
= *state
;
1041 if (ParseOneCharToken(state
, 'M') && ParseType(state
) &&
1049 // <template-param> ::= T_
1050 // ::= T <parameter-2 non-negative number> _
1051 static bool ParseTemplateParam(State
*state
) {
1052 if (ParseTwoCharToken(state
, "T_")) {
1053 MaybeAppend(state
, "?"); // We don't support template substitutions.
1057 State copy
= *state
;
1058 if (ParseOneCharToken(state
, 'T') && ParseNumber(state
, NULL
) &&
1059 ParseOneCharToken(state
, '_')) {
1060 MaybeAppend(state
, "?"); // We don't support template substitutions.
1068 // <template-template-param> ::= <template-param>
1069 // ::= <substitution>
1070 static bool ParseTemplateTemplateParam(State
*state
) {
1071 return (ParseTemplateParam(state
) ||
1072 ParseSubstitution(state
));
1075 // <template-args> ::= I <template-arg>+ E
1076 static bool ParseTemplateArgs(State
*state
) {
1077 State copy
= *state
;
1078 DisableAppend(state
);
1079 if (ParseOneCharToken(state
, 'I') &&
1080 OneOrMore(ParseTemplateArg
, state
) &&
1081 ParseOneCharToken(state
, 'E')) {
1082 RestoreAppend(state
, copy
.append
);
1083 MaybeAppend(state
, "<>");
1090 // <template-arg> ::= <type>
1091 // ::= <expr-primary>
1092 // ::= I <template-arg>* E # argument pack
1093 // ::= X <expression> E
1094 static bool ParseTemplateArg(State
*state
) {
1095 State copy
= *state
;
1096 if (ParseOneCharToken(state
, 'I') &&
1097 ZeroOrMore(ParseTemplateArg
, state
) &&
1098 ParseOneCharToken(state
, 'E')) {
1103 if (ParseType(state
) ||
1104 ParseExprPrimary(state
)) {
1109 if (ParseOneCharToken(state
, 'X') && ParseExpression(state
) &&
1110 ParseOneCharToken(state
, 'E')) {
1117 // <expression> ::= <template-param>
1118 // ::= <expr-primary>
1119 // ::= <unary operator-name> <expression>
1120 // ::= <binary operator-name> <expression> <expression>
1121 // ::= <trinary operator-name> <expression> <expression>
1124 // ::= sr <type> <unqualified-name> <template-args>
1125 // ::= sr <type> <unqualified-name>
1126 static bool ParseExpression(State
*state
) {
1127 if (ParseTemplateParam(state
) || ParseExprPrimary(state
)) {
1131 State copy
= *state
;
1132 if (ParseOperatorName(state
) &&
1133 ParseExpression(state
) &&
1134 ParseExpression(state
) &&
1135 ParseExpression(state
)) {
1140 if (ParseOperatorName(state
) &&
1141 ParseExpression(state
) &&
1142 ParseExpression(state
)) {
1147 if (ParseOperatorName(state
) &&
1148 ParseExpression(state
)) {
1153 if (ParseTwoCharToken(state
, "st") && ParseType(state
)) {
1158 if (ParseTwoCharToken(state
, "sr") && ParseType(state
) &&
1159 ParseUnqualifiedName(state
) &&
1160 ParseTemplateArgs(state
)) {
1165 if (ParseTwoCharToken(state
, "sr") && ParseType(state
) &&
1166 ParseUnqualifiedName(state
)) {
1173 // <expr-primary> ::= L <type> <(value) number> E
1174 // ::= L <type> <(value) float> E
1175 // ::= L <mangled-name> E
1176 // // A bug in g++'s C++ ABI version 2 (-fabi-version=2).
1177 // ::= LZ <encoding> E
1178 static bool ParseExprPrimary(State
*state
) {
1179 State copy
= *state
;
1180 if (ParseOneCharToken(state
, 'L') && ParseType(state
) &&
1181 ParseNumber(state
, NULL
) &&
1182 ParseOneCharToken(state
, 'E')) {
1187 if (ParseOneCharToken(state
, 'L') && ParseType(state
) &&
1188 ParseFloatNumber(state
) &&
1189 ParseOneCharToken(state
, 'E')) {
1194 if (ParseOneCharToken(state
, 'L') && ParseMangledName(state
) &&
1195 ParseOneCharToken(state
, 'E')) {
1200 if (ParseTwoCharToken(state
, "LZ") && ParseEncoding(state
) &&
1201 ParseOneCharToken(state
, 'E')) {
1209 // <local-name> := Z <(function) encoding> E <(entity) name>
1210 // [<discriminator>]
1211 // := Z <(function) encoding> E s [<discriminator>]
1212 static bool ParseLocalName(State
*state
) {
1213 State copy
= *state
;
1214 if (ParseOneCharToken(state
, 'Z') && ParseEncoding(state
) &&
1215 ParseOneCharToken(state
, 'E') && MaybeAppend(state
, "::") &&
1216 ParseName(state
) && Optional(ParseDiscriminator(state
))) {
1221 if (ParseOneCharToken(state
, 'Z') && ParseEncoding(state
) &&
1222 ParseTwoCharToken(state
, "Es") && Optional(ParseDiscriminator(state
))) {
1229 // <discriminator> := _ <(non-negative) number>
1230 static bool ParseDiscriminator(State
*state
) {
1231 State copy
= *state
;
1232 if (ParseOneCharToken(state
, '_') && ParseNumber(state
, NULL
)) {
1239 // <substitution> ::= S_
1242 static bool ParseSubstitution(State
*state
) {
1243 if (ParseTwoCharToken(state
, "S_")) {
1244 MaybeAppend(state
, "?"); // We don't support substitutions.
1248 State copy
= *state
;
1249 if (ParseOneCharToken(state
, 'S') && ParseSeqId(state
) &&
1250 ParseOneCharToken(state
, '_')) {
1251 MaybeAppend(state
, "?"); // We don't support substitutions.
1256 // Expand abbreviations like "St" => "std".
1257 if (ParseOneCharToken(state
, 'S')) {
1258 const AbbrevPair
*p
;
1259 for (p
= kSubstitutionList
; p
->abbrev
!= NULL
; ++p
) {
1260 if (state
->mangled_cur
[0] == p
->abbrev
[1]) {
1261 MaybeAppend(state
, "std");
1262 if (p
->real_name
[0] != '\0') {
1263 MaybeAppend(state
, "::");
1264 MaybeAppend(state
, p
->real_name
);
1266 ++state
->mangled_cur
;
1275 // Parse <mangled-name>, optionally followed by either a function-clone suffix
1276 // or version suffix. Returns true only if all of "mangled_cur" was consumed.
1277 static bool ParseTopLevelMangledName(State
*state
) {
1278 if (ParseMangledName(state
)) {
1279 if (state
->mangled_cur
[0] != '\0') {
1280 // Drop trailing function clone suffix, if any.
1281 if (IsFunctionCloneSuffix(state
->mangled_cur
)) {
1284 // Append trailing version suffix if any.
1285 // ex. _Z3foo@@GLIBCXX_3.4
1286 if (state
->mangled_cur
[0] == '@') {
1287 MaybeAppend(state
, state
->mangled_cur
);
1290 return false; // Unconsumed suffix.
1297 // The demangler entry point.
1298 bool Demangle(const char *mangled
, char *out
, int out_size
) {
1300 InitState(&state
, mangled
, out
, out_size
);
1301 return ParseTopLevelMangledName(&state
) && !state
.overflowed
;
1304 _END_GOOGLE_NAMESPACE_