blob: 18a90b4a95f6fa01c66cd03dbf2ce1d9033822ff [file] [log] [blame]
Christopher Ferris9323b722017-03-03 17:43:14 -08001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <assert.h>
18
19#include <cctype>
20#include <stack>
21#include <string>
22#include <vector>
23
24#include "Demangler.h"
25
26constexpr const char* Demangler::kTypes[];
27constexpr const char* Demangler::kDTypes[];
28constexpr const char* Demangler::kSTypes[];
29
30void Demangler::Save(const std::string& str, bool is_name) {
31 saves_.push_back(str);
32 last_save_name_ = is_name;
33}
34
35std::string Demangler::GetArgumentsString() {
36 size_t num_args = cur_state_.args.size();
37 std::string arg_str;
38 if (num_args > 0) {
39 arg_str = cur_state_.args[0];
40 for (size_t i = 1; i < num_args; i++) {
41 arg_str += ", " + cur_state_.args[i];
42 }
43 }
44 return arg_str;
45}
46
47const char* Demangler::AppendOperatorString(const char* name) {
48 const char* oper = nullptr;
49 switch (*name) {
50 case 'a':
51 name++;
52 switch (*name) {
53 case 'a':
54 oper = "operator&&";
55 break;
56 case 'd':
57 case 'n':
58 oper = "operator&";
59 break;
60 case 'N':
61 oper = "operator&=";
62 break;
63 case 'S':
64 oper = "operator=";
65 break;
66 }
67 break;
68 case 'c':
69 name++;
70 switch (*name) {
71 case 'l':
72 oper = "operator()";
73 break;
74 case 'm':
75 oper = "operator,";
76 break;
77 case 'o':
78 oper = "operator~";
79 break;
80 }
81 break;
82 case 'd':
83 name++;
84 switch (*name) {
85 case 'a':
86 oper = "operator delete[]";
87 break;
88 case 'e':
89 oper = "operator*";
90 break;
91 case 'l':
92 oper = "operator delete";
93 break;
94 case 'v':
95 oper = "operator/";
96 break;
97 case 'V':
98 oper = "operator/=";
99 break;
100 }
101 break;
102 case 'e':
103 name++;
104 switch (*name) {
105 case 'o':
106 oper = "operator^";
107 break;
108 case 'O':
109 oper = "operator^=";
110 break;
111 case 'q':
112 oper = "operator==";
113 break;
114 }
115 break;
116 case 'g':
117 name++;
118 switch (*name) {
119 case 'e':
120 oper = "operator>=";
121 break;
122 case 't':
123 oper = "operator>";
124 break;
125 }
126 break;
127 case 'i':
128 name++;
129 switch (*name) {
130 case 'x':
131 oper = "operator[]";
132 break;
133 }
134 break;
135 case 'l':
136 name++;
137 switch (*name) {
138 case 'e':
139 oper = "operator<=";
140 break;
141 case 's':
142 oper = "operator<<";
143 break;
144 case 'S':
145 oper = "operator<<=";
146 break;
147 case 't':
148 oper = "operator<";
149 break;
150 }
151 break;
152 case 'm':
153 name++;
154 switch (*name) {
155 case 'i':
156 oper = "operator-";
157 break;
158 case 'I':
159 oper = "operator-=";
160 break;
161 case 'l':
162 oper = "operator*";
163 break;
164 case 'L':
165 oper = "operator*=";
166 break;
167 case 'm':
168 oper = "operator--";
169 break;
170 }
171 break;
172 case 'n':
173 name++;
174 switch (*name) {
175 case 'a':
176 oper = "operator new[]";
177 break;
178 case 'e':
179 oper = "operator!=";
180 break;
181 case 'g':
182 oper = "operator-";
183 break;
184 case 't':
185 oper = "operator!";
186 break;
187 case 'w':
188 oper = "operator new";
189 break;
190 }
191 break;
192 case 'o':
193 name++;
194 switch (*name) {
195 case 'o':
196 oper = "operator||";
197 break;
198 case 'r':
199 oper = "operator|";
200 break;
201 case 'R':
202 oper = "operator|=";
203 break;
204 }
205 break;
206 case 'p':
207 name++;
208 switch (*name) {
209 case 'm':
210 oper = "operator->*";
211 break;
212 case 'l':
213 oper = "operator+";
214 break;
215 case 'L':
216 oper = "operator+=";
217 break;
218 case 'p':
219 oper = "operator++";
220 break;
221 case 's':
222 oper = "operator+";
223 break;
224 case 't':
225 oper = "operator->";
226 break;
227 }
228 break;
229 case 'q':
230 name++;
231 switch (*name) {
232 case 'u':
233 oper = "operator?";
234 break;
235 }
236 break;
237 case 'r':
238 name++;
239 switch (*name) {
240 case 'm':
241 oper = "operator%";
242 break;
243 case 'M':
244 oper = "operator%=";
245 break;
246 case 's':
247 oper = "operator>>";
248 break;
249 case 'S':
250 oper = "operator>>=";
251 break;
252 }
253 break;
254 }
255 if (oper == nullptr) {
256 return nullptr;
257 }
258 AppendCurrent(oper);
259 cur_state_.last_save = oper;
260 return name + 1;
261}
262
263const char* Demangler::GetStringFromLength(const char* name, std::string* str) {
264 assert(std::isdigit(*name));
265
266 size_t length = *name - '0';
267 name++;
268 while (*name != '\0' && std::isdigit(*name)) {
269 length = length * 10 + *name - '0';
270 name++;
271 }
272
273 std::string read_str;
274 while (*name != '\0' && length != 0) {
275 read_str += *name;
276 name++;
277 length--;
278 }
279 if (length != 0) {
280 return nullptr;
281 }
282 // Special replacement of _GLOBAL__N_1 to (anonymous namespace).
283 if (read_str == "_GLOBAL__N_1") {
284 *str += "(anonymous namespace)";
285 } else {
286 *str += read_str;
287 }
288 return name;
289}
290
291void Demangler::AppendCurrent(const std::string& str) {
292 if (!cur_state_.str.empty()) {
293 cur_state_.str += "::";
294 }
295 cur_state_.str += str;
296}
297
298void Demangler::AppendCurrent(const char* str) {
299 if (!cur_state_.str.empty()) {
300 cur_state_.str += "::";
301 }
302 cur_state_.str += str;
303}
304
305const char* Demangler::ParseS(const char* name) {
306 if (std::islower(*name)) {
307 const char* type = kSTypes[*name - 'a'];
308 if (type == nullptr) {
309 return nullptr;
310 }
311 AppendCurrent(type);
312 return name + 1;
313 }
314
315 if (saves_.empty()) {
316 return nullptr;
317 }
318
319 if (*name == '_') {
320 last_save_name_ = false;
321 AppendCurrent(saves_[0]);
322 return name + 1;
323 }
324
325 bool isdigit = std::isdigit(*name);
326 if (!isdigit && !std::isupper(*name)) {
327 return nullptr;
328 }
329
330 size_t index;
331 if (isdigit) {
332 index = *name - '0' + 1;
333 } else {
334 index = *name - 'A' + 11;
335 }
336 name++;
337 if (*name != '_') {
338 return nullptr;
339 }
340
341 if (index >= saves_.size()) {
342 return nullptr;
343 }
344
345 last_save_name_ = false;
346 AppendCurrent(saves_[index]);
347 return name + 1;
348}
349
Christopher Ferris584333e2017-10-27 12:29:02 -0700350const char* Demangler::ParseT(const char* name) {
351 if (template_saves_.empty()) {
352 return nullptr;
353 }
354
355 if (*name == '_') {
356 last_save_name_ = false;
357 AppendCurrent(template_saves_[0]);
358 return name + 1;
359 }
360
361 // Need to get the total number.
362 char* end;
363 unsigned long int index = strtoul(name, &end, 10) + 1;
364 if (name == end || *end != '_') {
365 return nullptr;
366 }
367
368 if (index >= template_saves_.size()) {
369 return nullptr;
370 }
371
372 last_save_name_ = false;
373 AppendCurrent(template_saves_[index]);
374 return end + 1;
375}
376
Christopher Ferris9323b722017-03-03 17:43:14 -0800377const char* Demangler::ParseFunctionName(const char* name) {
378 if (*name == 'E') {
379 if (parse_funcs_.empty()) {
380 return nullptr;
381 }
382 parse_func_ = parse_funcs_.back();
383 parse_funcs_.pop_back();
384
385 // Remove the last saved part so that the full function name is not saved.
386 // But only if the last save was not something like a substitution.
387 if (!saves_.empty() && last_save_name_) {
388 saves_.pop_back();
389 }
390
391 function_name_ = cur_state_.str;
392 while (!cur_state_.suffixes.empty()) {
393 function_suffix_ += cur_state_.suffixes.back();
394 cur_state_.suffixes.pop_back();
395 }
396 cur_state_.Clear();
397
398 return name + 1;
399 }
400
Christopher Ferris584333e2017-10-27 12:29:02 -0700401 if (*name == 'I') {
402 state_stack_.push(cur_state_);
403 cur_state_.Clear();
404
405 parse_funcs_.push_back(parse_func_);
406 parse_func_ = &Demangler::ParseFunctionNameTemplate;
407 return name + 1;
408 }
409
Christopher Ferris9323b722017-03-03 17:43:14 -0800410 return ParseComplexString(name);
411}
412
Christopher Ferris584333e2017-10-27 12:29:02 -0700413const char* Demangler::ParseFunctionNameTemplate(const char* name) {
414 if (*name == 'E' && name[1] == 'E') {
415 // Only consider this a template with saves if it is right before
416 // the end of the name.
417 template_found_ = true;
418 template_saves_ = cur_state_.args;
419 }
420 return ParseTemplateArgumentsComplex(name);
421}
422
Christopher Ferris9323b722017-03-03 17:43:14 -0800423const char* Demangler::ParseComplexArgument(const char* name) {
424 if (*name == 'E') {
425 if (parse_funcs_.empty()) {
426 return nullptr;
427 }
428 parse_func_ = parse_funcs_.back();
429 parse_funcs_.pop_back();
430
431 AppendArgument(cur_state_.str);
432 cur_state_.str.clear();
433
434 return name + 1;
435 }
436
437 return ParseComplexString(name);
438}
439
440void Demangler::FinalizeTemplate() {
441 std::string arg_str(GetArgumentsString());
442 cur_state_ = state_stack_.top();
443 state_stack_.pop();
444 cur_state_.str += '<' + arg_str + '>';
445}
446
447const char* Demangler::ParseComplexString(const char* name) {
448 if (*name == 'S') {
449 name++;
450 if (*name == 't') {
451 AppendCurrent("std");
452 return name + 1;
453 }
454 return ParseS(name);
455 }
456 if (*name == 'L') {
457 name++;
458 if (!std::isdigit(*name)) {
459 return nullptr;
460 }
461 }
462 if (std::isdigit(*name)) {
463 std::string str;
464 name = GetStringFromLength(name, &str);
465 if (name == nullptr) {
466 return name;
467 }
468 AppendCurrent(str);
469 Save(cur_state_.str, true);
470 cur_state_.last_save = std::move(str);
471 return name;
472 }
473 if (*name == 'D') {
474 name++;
475 if (saves_.empty() || (*name != '0' && *name != '1' && *name != '2'
476 && *name != '5')) {
477 return nullptr;
478 }
479 last_save_name_ = false;
480 AppendCurrent("~" + cur_state_.last_save);
481 return name + 1;
482 }
483 if (*name == 'C') {
484 name++;
485 if (saves_.empty() || (*name != '1' && *name != '2' && *name != '3'
486 && *name != '5')) {
487 return nullptr;
488 }
489 last_save_name_ = false;
490 AppendCurrent(cur_state_.last_save);
491 return name + 1;
492 }
493 if (*name == 'K') {
494 cur_state_.suffixes.push_back(" const");
495 return name + 1;
496 }
497 if (*name == 'V') {
498 cur_state_.suffixes.push_back(" volatile");
499 return name + 1;
500 }
501 if (*name == 'I') {
502 // Save the current argument state.
503 state_stack_.push(cur_state_);
504 cur_state_.Clear();
505
506 parse_funcs_.push_back(parse_func_);
507 parse_func_ = &Demangler::ParseTemplateArgumentsComplex;
508 return name + 1;
509 }
510 name = AppendOperatorString(name);
511 if (name != nullptr) {
512 Save(cur_state_.str, true);
513 }
514 return name;
515}
516
517void Demangler::AppendArgument(const std::string& str) {
518 std::string arg(str);
519 while (!cur_state_.suffixes.empty()) {
520 arg += cur_state_.suffixes.back();
521 cur_state_.suffixes.pop_back();
522 Save(arg, false);
523 }
524 cur_state_.args.push_back(arg);
525}
526
527const char* Demangler::ParseFunctionArgument(const char* name) {
528 if (*name == 'E') {
529 // The first argument is the function modifier.
530 // The second argument is the function type.
531 // The third argument is the return type of the function.
532 // The rest of the arguments are the function arguments.
533 size_t num_args = cur_state_.args.size();
534 if (num_args < 4) {
535 return nullptr;
536 }
537 std::string function_modifier = cur_state_.args[0];
538 std::string function_type = cur_state_.args[1];
539
540 std::string str = cur_state_.args[2] + ' ';
541 if (!cur_state_.args[1].empty()) {
542 str += '(' + cur_state_.args[1] + ')';
543 }
544
545 if (num_args == 4 && cur_state_.args[3] == "void") {
546 str += "()";
547 } else {
548 str += '(' + cur_state_.args[3];
549 for (size_t i = 4; i < num_args; i++) {
550 str += ", " + cur_state_.args[i];
551 }
552 str += ')';
553 }
554 str += cur_state_.args[0];
555
556 cur_state_ = state_stack_.top();
557 state_stack_.pop();
558 cur_state_.args.emplace_back(std::move(str));
559
560 parse_func_ = parse_funcs_.back();
561 parse_funcs_.pop_back();
562 return name + 1;
563 }
564 return ParseArguments(name);
565}
566
567const char* Demangler::ParseArguments(const char* name) {
568 switch (*name) {
569 case 'P':
570 cur_state_.suffixes.push_back("*");
571 return name + 1;
572
573 case 'R':
574 // This should always be okay because the string is guaranteed to have
575 // at least two characters before this. A mangled string always starts
576 // with _Z.
577 if (name[-1] != 'R') {
578 // Multiple 'R's in a row only add a single &.
579 cur_state_.suffixes.push_back("&");
580 }
581 return name + 1;
582
583 case 'K':
584 case 'V': {
585 const char* suffix;
586 if (*name == 'K') {
587 suffix = " const";
588 } else {
589 suffix = " volatile";
590 }
Christopher Ferris15d2e422017-05-31 14:40:15 -0700591 if (!cur_state_.suffixes.empty() && (name[-1] == 'K' || name[-1] == 'V')) {
Christopher Ferris9323b722017-03-03 17:43:14 -0800592 // Special case, const/volatile apply as a single entity.
Christopher Ferris9323b722017-03-03 17:43:14 -0800593 size_t index = cur_state_.suffixes.size();
594 cur_state_.suffixes[index-1].insert(0, suffix);
595 } else {
596 cur_state_.suffixes.push_back(suffix);
597 }
598 return name + 1;
599 }
600
601 case 'F': {
602 std::string function_modifier;
603 std::string function_type;
604 if (!cur_state_.suffixes.empty()) {
605 // If the first element starts with a ' ', then this modifies the
606 // function itself.
607 if (cur_state_.suffixes.back()[0] == ' ') {
608 function_modifier = cur_state_.suffixes.back();
609 cur_state_.suffixes.pop_back();
610 }
611 while (!cur_state_.suffixes.empty()) {
612 function_type += cur_state_.suffixes.back();
613 cur_state_.suffixes.pop_back();
614 }
615 }
616
617 state_stack_.push(cur_state_);
618
619 cur_state_.Clear();
620
621 // The function parameter has this format:
622 // First argument is the function modifier.
623 // Second argument is the function type.
624 // Third argument will be the return function type but has not
625 // been parsed yet.
626 // Any other parameters are the arguments to the function. There
627 // must be at least one or this isn't valid.
628 cur_state_.args.push_back(function_modifier);
629 cur_state_.args.push_back(function_type);
630
631 parse_funcs_.push_back(parse_func_);
632 parse_func_ = &Demangler::ParseFunctionArgument;
633 return name + 1;
634 }
635
636 case 'N':
637 parse_funcs_.push_back(parse_func_);
638 parse_func_ = &Demangler::ParseComplexArgument;
639 return name + 1;
640
641 case 'S':
642 name++;
643 if (*name == 't') {
644 cur_state_.str = "std::";
645 return name + 1;
646 }
647 name = ParseS(name);
648 if (name == nullptr) {
649 return nullptr;
650 }
651 AppendArgument(cur_state_.str);
652 cur_state_.str.clear();
653 return name;
654
655 case 'D':
656 name++;
657 if (*name >= 'a' && *name <= 'z') {
658 const char* arg = Demangler::kDTypes[*name - 'a'];
659 if (arg == nullptr) {
660 return nullptr;
661 }
662 AppendArgument(arg);
663 return name + 1;
664 }
665 return nullptr;
666
667 case 'I':
668 // Save the current argument state.
669 state_stack_.push(cur_state_);
670 cur_state_.Clear();
671
672 parse_funcs_.push_back(parse_func_);
673 parse_func_ = &Demangler::ParseTemplateArguments;
674 return name + 1;
675
676 case 'v':
677 AppendArgument("void");
678 return name + 1;
679
680 default:
681 if (*name >= 'a' && *name <= 'z') {
682 const char* arg = Demangler::kTypes[*name - 'a'];
683 if (arg == nullptr) {
684 return nullptr;
685 }
686 AppendArgument(arg);
687 return name + 1;
688 } else if (std::isdigit(*name)) {
689 std::string arg = cur_state_.str;
690 name = GetStringFromLength(name, &arg);
691 if (name == nullptr) {
692 return nullptr;
693 }
694 Save(arg, true);
695 if (*name == 'I') {
696 // There is one case where this argument is not complete, and that's
697 // where this is a template argument.
698 cur_state_.str = arg;
699 } else {
700 AppendArgument(arg);
701 cur_state_.str.clear();
702 }
703 return name;
704 }
705 }
706 return nullptr;
707}
708
Christopher Ferris05232752017-10-11 15:22:29 -0700709const char* Demangler::ParseTemplateLiteral(const char* name) {
710 if (*name == 'E') {
711 parse_func_ = parse_funcs_.back();
712 parse_funcs_.pop_back();
713 return name + 1;
714 }
715 // Only understand boolean values with 0 or 1.
716 if (*name == 'b') {
717 name++;
718 if (*name == '0') {
719 AppendArgument("false");
720 cur_state_.str.clear();
721 } else if (*name == '1') {
722 AppendArgument("true");
723 cur_state_.str.clear();
724 } else {
725 return nullptr;
726 }
727 return name + 1;
728 }
729 return nullptr;
730}
731
Christopher Ferris9323b722017-03-03 17:43:14 -0800732const char* Demangler::ParseTemplateArgumentsComplex(const char* name) {
733 if (*name == 'E') {
734 if (parse_funcs_.empty()) {
735 return nullptr;
736 }
737 parse_func_ = parse_funcs_.back();
738 parse_funcs_.pop_back();
Christopher Ferris584333e2017-10-27 12:29:02 -0700739
Christopher Ferris9323b722017-03-03 17:43:14 -0800740 FinalizeTemplate();
741 Save(cur_state_.str, false);
742 return name + 1;
Christopher Ferris05232752017-10-11 15:22:29 -0700743 } else if (*name == 'L') {
744 // Literal value for a template.
745 parse_funcs_.push_back(parse_func_);
746 parse_func_ = &Demangler::ParseTemplateLiteral;
747 return name + 1;
Christopher Ferris9323b722017-03-03 17:43:14 -0800748 }
Christopher Ferris584333e2017-10-27 12:29:02 -0700749
Christopher Ferris9323b722017-03-03 17:43:14 -0800750 return ParseArguments(name);
751}
752
753const char* Demangler::ParseTemplateArguments(const char* name) {
754 if (*name == 'E') {
755 if (parse_funcs_.empty()) {
756 return nullptr;
757 }
758 parse_func_ = parse_funcs_.back();
759 parse_funcs_.pop_back();
760 FinalizeTemplate();
761 AppendArgument(cur_state_.str);
762 cur_state_.str.clear();
763 return name + 1;
Christopher Ferris584333e2017-10-27 12:29:02 -0700764 } else if (*name == 'L') {
765 // Literal value for a template.
766 parse_funcs_.push_back(parse_func_);
767 parse_func_ = &Demangler::ParseTemplateLiteral;
768 return name + 1;
Christopher Ferris9323b722017-03-03 17:43:14 -0800769 }
Christopher Ferris584333e2017-10-27 12:29:02 -0700770
Christopher Ferris9323b722017-03-03 17:43:14 -0800771 return ParseArguments(name);
772}
773
Christopher Ferris584333e2017-10-27 12:29:02 -0700774const char* Demangler::ParseFunctionTemplateArguments(const char* name) {
775 if (*name == 'E') {
776 parse_func_ = parse_funcs_.back();
777 parse_funcs_.pop_back();
778
779 function_name_ += '<' + GetArgumentsString() + '>';
780 template_found_ = true;
781 template_saves_ = cur_state_.args;
782 cur_state_.Clear();
783 return name + 1;
784 }
785 return ParseTemplateArgumentsComplex(name);
786}
787
Christopher Ferris9323b722017-03-03 17:43:14 -0800788const char* Demangler::FindFunctionName(const char* name) {
789 if (*name == 'N') {
Christopher Ferris584333e2017-10-27 12:29:02 -0700790 parse_funcs_.push_back(&Demangler::ParseArgumentsAtTopLevel);
Christopher Ferris9323b722017-03-03 17:43:14 -0800791 parse_func_ = &Demangler::ParseFunctionName;
792 return name + 1;
793 }
794
795 if (std::isdigit(*name)) {
796 name = GetStringFromLength(name, &function_name_);
Christopher Ferris4504bba2017-06-01 17:37:09 -0700797 } else if (*name == 'L' && std::isdigit(name[1])) {
798 name = GetStringFromLength(name + 1, &function_name_);
Christopher Ferris9323b722017-03-03 17:43:14 -0800799 } else {
800 name = AppendOperatorString(name);
801 function_name_ = cur_state_.str;
802 }
Christopher Ferris9323b722017-03-03 17:43:14 -0800803 cur_state_.Clear();
Christopher Ferris584333e2017-10-27 12:29:02 -0700804
805 // Check for a template argument, which will still be part of the function
806 // name.
807 if (name != nullptr && *name == 'I') {
808 parse_funcs_.push_back(&Demangler::ParseArgumentsAtTopLevel);
809 parse_func_ = &Demangler::ParseFunctionTemplateArguments;
810 return name + 1;
811 }
812 parse_func_ = &Demangler::ParseArgumentsAtTopLevel;
Christopher Ferris9323b722017-03-03 17:43:14 -0800813 return name;
814}
815
Christopher Ferris584333e2017-10-27 12:29:02 -0700816const char* Demangler::ParseArgumentsAtTopLevel(const char* name) {
817 // At the top level is the only place where T is allowed.
818 if (*name == 'T') {
819 name++;
820 name = ParseT(name);
821 if (name == nullptr) {
822 return nullptr;
823 }
824 AppendArgument(cur_state_.str);
825 cur_state_.str.clear();
826 return name;
827 }
828
829 return Demangler::ParseArguments(name);
830}
831
Christopher Ferris9323b722017-03-03 17:43:14 -0800832std::string Demangler::Parse(const char* name, size_t max_length) {
833 if (name[0] == '\0' || name[0] != '_' || name[1] == '\0' || name[1] != 'Z') {
834 // Name is not mangled.
835 return name;
836 }
837
838 Clear();
839
840 parse_func_ = &Demangler::FindFunctionName;
841 parse_funcs_.push_back(&Demangler::Fail);
842 const char* cur_name = name + 2;
843 while (cur_name != nullptr && *cur_name != '\0'
844 && static_cast<size_t>(cur_name - name) < max_length) {
845 cur_name = (this->*parse_func_)(cur_name);
846 }
Christopher Ferris15d2e422017-05-31 14:40:15 -0700847 if (cur_name == nullptr || *cur_name != '\0' || function_name_.empty() ||
848 !cur_state_.suffixes.empty()) {
Christopher Ferris9323b722017-03-03 17:43:14 -0800849 return name;
850 }
851
Christopher Ferris584333e2017-10-27 12:29:02 -0700852 std::string return_type;
853 if (template_found_) {
854 // Only a single argument with a template is not allowed.
855 if (cur_state_.args.size() == 1) {
856 return name;
857 }
858
859 // If there are at least two arguments, this template has a return type.
860 if (cur_state_.args.size() > 1) {
861 // The first argument will be the return value.
862 return_type = cur_state_.args[0] + ' ';
863 cur_state_.args.erase(cur_state_.args.begin());
864 }
865 }
866
Christopher Ferris9323b722017-03-03 17:43:14 -0800867 std::string arg_str;
868 if (cur_state_.args.size() == 1 && cur_state_.args[0] == "void") {
869 // If the only argument is void, then don't print any args.
870 arg_str = "()";
871 } else {
872 arg_str = GetArgumentsString();
873 if (!arg_str.empty()) {
874 arg_str = '(' + arg_str + ')';
875 }
876 }
Christopher Ferris584333e2017-10-27 12:29:02 -0700877 return return_type + function_name_ + arg_str + function_suffix_;
Christopher Ferris9323b722017-03-03 17:43:14 -0800878}
879
880std::string demangle(const char* name) {
881 Demangler demangler;
882 return demangler.Parse(name);
883}