• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
26 constexpr const char* Demangler::kTypes[];
27 constexpr const char* Demangler::kDTypes[];
28 constexpr const char* Demangler::kSTypes[];
29 
Save(const std::string & str,bool is_name)30 void Demangler::Save(const std::string& str, bool is_name) {
31   saves_.push_back(str);
32   last_save_name_ = is_name;
33 }
34 
GetArgumentsString()35 std::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 
AppendOperatorString(const char * name)47 const 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 
GetStringFromLength(const char * name,std::string * str)263 const 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 
AppendCurrent(const std::string & str)291 void Demangler::AppendCurrent(const std::string& str) {
292   if (!cur_state_.str.empty()) {
293     cur_state_.str += "::";
294   }
295   cur_state_.str += str;
296 }
297 
AppendCurrent(const char * str)298 void Demangler::AppendCurrent(const char* str) {
299   if (!cur_state_.str.empty()) {
300     cur_state_.str += "::";
301   }
302   cur_state_.str += str;
303 }
304 
ParseS(const char * name)305 const 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 
ParseT(const char * name)350 const 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 
ParseFunctionName(const char * name)377 const 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 
401   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 
410   return ParseComplexString(name);
411 }
412 
ParseFunctionNameTemplate(const char * name)413 const 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 
ParseComplexArgument(const char * name)423 const 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 
FinalizeTemplate()440 void 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 
ParseComplexString(const char * name)447 const 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 
AppendArgument(const std::string & str)517 void 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 
ParseFunctionArgument(const char * name)527 const 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 
ParseArguments(const char * name)567 const 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 'O':
584     cur_state_.suffixes.push_back("&&");
585     return name + 1;
586 
587   case 'K':
588   case 'V': {
589     const char* suffix;
590     if (*name == 'K') {
591       suffix = " const";
592     } else {
593       suffix = " volatile";
594     }
595     if (!cur_state_.suffixes.empty() && (name[-1] == 'K' || name[-1] == 'V')) {
596       // Special case, const/volatile apply as a single entity.
597       size_t index = cur_state_.suffixes.size();
598       cur_state_.suffixes[index-1].insert(0, suffix);
599     } else {
600       cur_state_.suffixes.push_back(suffix);
601     }
602     return name + 1;
603   }
604 
605   case 'F': {
606     std::string function_modifier;
607     std::string function_type;
608     if (!cur_state_.suffixes.empty()) {
609       // If the first element starts with a ' ', then this modifies the
610       // function itself.
611       if (cur_state_.suffixes.back()[0] == ' ') {
612         function_modifier = cur_state_.suffixes.back();
613         cur_state_.suffixes.pop_back();
614       }
615       while (!cur_state_.suffixes.empty()) {
616         function_type += cur_state_.suffixes.back();
617         cur_state_.suffixes.pop_back();
618       }
619     }
620 
621     state_stack_.push(cur_state_);
622 
623     cur_state_.Clear();
624 
625     // The function parameter has this format:
626     //   First argument is the function modifier.
627     //   Second argument is the function type.
628     //   Third argument will be the return function type but has not
629     //     been parsed yet.
630     //   Any other parameters are the arguments to the function. There
631     //     must be at least one or this isn't valid.
632     cur_state_.args.push_back(function_modifier);
633     cur_state_.args.push_back(function_type);
634 
635     parse_funcs_.push_back(parse_func_);
636     parse_func_ = &Demangler::ParseFunctionArgument;
637     return name + 1;
638   }
639 
640   case 'N':
641     parse_funcs_.push_back(parse_func_);
642     parse_func_ = &Demangler::ParseComplexArgument;
643     return name + 1;
644 
645   case 'S':
646     name++;
647     if (*name == 't') {
648       cur_state_.str = "std::";
649       return name + 1;
650     }
651     name = ParseS(name);
652     if (name == nullptr) {
653       return nullptr;
654     }
655     AppendArgument(cur_state_.str);
656     cur_state_.str.clear();
657     return name;
658 
659   case 'D':
660     name++;
661     if (*name >= 'a' && *name <= 'z') {
662       const char* arg = Demangler::kDTypes[*name - 'a'];
663       if (arg == nullptr) {
664         return nullptr;
665       }
666       AppendArgument(arg);
667       return name + 1;
668     }
669     return nullptr;
670 
671   case 'I':
672     // Save the current argument state.
673     state_stack_.push(cur_state_);
674     cur_state_.Clear();
675 
676     parse_funcs_.push_back(parse_func_);
677     parse_func_ = &Demangler::ParseTemplateArguments;
678     return name + 1;
679 
680   case 'v':
681     AppendArgument("void");
682     return name + 1;
683 
684   default:
685     if (*name >= 'a' && *name <= 'z') {
686       const char* arg = Demangler::kTypes[*name - 'a'];
687       if (arg == nullptr) {
688         return nullptr;
689       }
690       AppendArgument(arg);
691       return name + 1;
692     } else if (std::isdigit(*name)) {
693       std::string arg = cur_state_.str;
694       name = GetStringFromLength(name, &arg);
695       if (name == nullptr) {
696         return nullptr;
697       }
698       Save(arg, true);
699       if (*name == 'I') {
700         // There is one case where this argument is not complete, and that's
701         // where this is a template argument.
702         cur_state_.str = arg;
703       } else {
704         AppendArgument(arg);
705         cur_state_.str.clear();
706       }
707       return name;
708     } else if (strcmp(name, ".cfi") == 0) {
709       function_suffix_ += " [clone .cfi]";
710       return name + 4;
711     }
712   }
713   return nullptr;
714 }
715 
ParseTemplateLiteral(const char * name)716 const char* Demangler::ParseTemplateLiteral(const char* name) {
717   if (*name == 'E') {
718     parse_func_ = parse_funcs_.back();
719     parse_funcs_.pop_back();
720     return name + 1;
721   }
722   // Only understand boolean values with 0 or 1.
723   if (*name == 'b') {
724     name++;
725     if (*name == '0') {
726       AppendArgument("false");
727       cur_state_.str.clear();
728     } else if (*name == '1') {
729       AppendArgument("true");
730       cur_state_.str.clear();
731     } else {
732       return nullptr;
733     }
734     return name + 1;
735   }
736   return nullptr;
737 }
738 
ParseTemplateArgumentsComplex(const char * name)739 const char* Demangler::ParseTemplateArgumentsComplex(const char* name) {
740   if (*name == 'E') {
741     if (parse_funcs_.empty()) {
742       return nullptr;
743     }
744     parse_func_ = parse_funcs_.back();
745     parse_funcs_.pop_back();
746 
747     FinalizeTemplate();
748     Save(cur_state_.str, false);
749     return name + 1;
750   } else if (*name == 'L') {
751     // Literal value for a template.
752     parse_funcs_.push_back(parse_func_);
753     parse_func_ = &Demangler::ParseTemplateLiteral;
754     return name + 1;
755   }
756 
757   return ParseArguments(name);
758 }
759 
ParseTemplateArguments(const char * name)760 const char* Demangler::ParseTemplateArguments(const char* name) {
761   if (*name == 'E') {
762     if (parse_funcs_.empty()) {
763       return nullptr;
764     }
765     parse_func_ = parse_funcs_.back();
766     parse_funcs_.pop_back();
767     FinalizeTemplate();
768     AppendArgument(cur_state_.str);
769     cur_state_.str.clear();
770     return name + 1;
771   } else if (*name == 'L') {
772     // Literal value for a template.
773     parse_funcs_.push_back(parse_func_);
774     parse_func_ = &Demangler::ParseTemplateLiteral;
775     return name + 1;
776   }
777 
778   return ParseArguments(name);
779 }
780 
ParseFunctionTemplateArguments(const char * name)781 const char* Demangler::ParseFunctionTemplateArguments(const char* name) {
782   if (*name == 'E') {
783     parse_func_ = parse_funcs_.back();
784     parse_funcs_.pop_back();
785 
786     function_name_ += '<' + GetArgumentsString() + '>';
787     template_found_ = true;
788     template_saves_ = cur_state_.args;
789     cur_state_.Clear();
790     return name + 1;
791   }
792   return ParseTemplateArgumentsComplex(name);
793 }
794 
FindFunctionName(const char * name)795 const char* Demangler::FindFunctionName(const char* name) {
796   if (*name == 'T') {
797     // non-virtual thunk, verify that it matches one of these patterns:
798     //   Thn[0-9]+_
799     //   Th[0-9]+_
800     //   Thn_
801     //   Th_
802     name++;
803     if (*name != 'h') {
804       return nullptr;
805     }
806     name++;
807     if (*name == 'n') {
808       name++;
809     }
810     while (std::isdigit(*name)) {
811       name++;
812     }
813     if (*name != '_') {
814       return nullptr;
815     }
816     function_name_ = "non-virtual thunk to ";
817     return name + 1;
818   }
819 
820   if (*name == 'N') {
821     parse_funcs_.push_back(&Demangler::ParseArgumentsAtTopLevel);
822     parse_func_ = &Demangler::ParseFunctionName;
823     return name + 1;
824   }
825 
826   if (*name == 'S') {
827     name++;
828     if (*name == 't') {
829       function_name_ = "std::";
830       name++;
831     } else {
832       return nullptr;
833     }
834   }
835 
836   if (std::isdigit(*name)) {
837     name = GetStringFromLength(name, &function_name_);
838   } else if (*name == 'L' && std::isdigit(name[1])) {
839     name = GetStringFromLength(name + 1, &function_name_);
840   } else {
841     name = AppendOperatorString(name);
842     function_name_ = cur_state_.str;
843   }
844   cur_state_.Clear();
845 
846   // Check for a template argument, which will still be part of the function
847   // name.
848   if (name != nullptr && *name == 'I') {
849     parse_funcs_.push_back(&Demangler::ParseArgumentsAtTopLevel);
850     parse_func_ = &Demangler::ParseFunctionTemplateArguments;
851     return name + 1;
852   }
853   parse_func_ = &Demangler::ParseArgumentsAtTopLevel;
854   return name;
855 }
856 
ParseArgumentsAtTopLevel(const char * name)857 const char* Demangler::ParseArgumentsAtTopLevel(const char* name) {
858   // At the top level is the only place where T is allowed.
859   if (*name == 'T') {
860     name++;
861     name = ParseT(name);
862     if (name == nullptr) {
863       return nullptr;
864     }
865     AppendArgument(cur_state_.str);
866     cur_state_.str.clear();
867     return name;
868   }
869 
870   return Demangler::ParseArguments(name);
871 }
872 
Parse(const char * name,size_t max_length)873 std::string Demangler::Parse(const char* name, size_t max_length) {
874   if (name[0] == '\0' || name[0] != '_' || name[1] == '\0' || name[1] != 'Z') {
875     // Name is not mangled.
876     return name;
877   }
878 
879   Clear();
880 
881   parse_func_ = &Demangler::FindFunctionName;
882   parse_funcs_.push_back(&Demangler::Fail);
883   const char* cur_name = name + 2;
884   while (cur_name != nullptr && *cur_name != '\0'
885       && static_cast<size_t>(cur_name - name) < max_length) {
886     cur_name = (this->*parse_func_)(cur_name);
887   }
888   if (cur_name == nullptr || *cur_name != '\0' || function_name_.empty() ||
889       !cur_state_.suffixes.empty()) {
890     return name;
891   }
892 
893   std::string return_type;
894   if (template_found_) {
895     // Only a single argument with a template is not allowed.
896     if (cur_state_.args.size() == 1) {
897       return name;
898     }
899 
900     // If there are at least two arguments, this template has a return type.
901     if (cur_state_.args.size() > 1) {
902       // The first argument will be the return value.
903       return_type = cur_state_.args[0] + ' ';
904       cur_state_.args.erase(cur_state_.args.begin());
905     }
906   }
907 
908   std::string arg_str;
909   if (cur_state_.args.size() == 1 && cur_state_.args[0] == "void") {
910     // If the only argument is void, then don't print any args.
911     arg_str = "()";
912   } else {
913     arg_str = GetArgumentsString();
914     if (!arg_str.empty()) {
915       arg_str = '(' + arg_str + ')';
916     }
917   }
918   return return_type + function_name_ + arg_str + function_suffix_;
919 }
920 
demangle(const char * name)921 std::string demangle(const char* name) {
922   Demangler demangler;
923   return demangler.Parse(name);
924 }
925