1 /* 2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <ctype.h> 7 #include <stdarg.h> 8 #include <stdio.h> 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include <new> 13 14 #include <TypeConstants.h> 15 16 #include <debug_heap.h> 17 18 #include "demangle.h" 19 20 21 // C++ ABI: http://www.codesourcery.com/public/cxx-abi/abi.html 22 23 24 //#define TRACE_GCC3_DEMANGLER 25 #ifdef TRACE_GCC3_DEMANGLER 26 # define TRACE(x...) PRINT(x) 27 # define DEBUG_SCOPE(name) DebugScope debug(name, fInput.String()) 28 #else 29 # define TRACE(x...) ; 30 # define DEBUG_SCOPE(name) do {} while (false) 31 #endif 32 33 #ifdef _KERNEL_MODE 34 # define PRINT(format...) kprintf(format) 35 # define VPRINT(format, args) PRINT("%s", format) 36 // no vkprintf() 37 # define NEW(constructor) new(kdebug_alloc) constructor 38 # define DELETE(object) DebugAlloc::destroy(object) 39 #else 40 # define PRINT(format...) printf(format) 41 # define VPRINT(format, args) vprintf(format, args) 42 # define NEW(constructor) new(std::nothrow) constructor 43 # define DELETE(object) delete object 44 #endif 45 46 47 typedef long number_type; 48 49 enum { 50 ERROR_OK = 0, 51 ERROR_NOT_MANGLED, 52 ERROR_UNSUPPORTED, 53 ERROR_INVALID, 54 ERROR_BUFFER_TOO_SMALL, 55 ERROR_NO_MEMORY, 56 ERROR_INTERNAL, 57 ERROR_INVALID_PARAMETER_INDEX 58 }; 59 60 // object classification 61 enum object_type { 62 OBJECT_TYPE_UNKNOWN, 63 OBJECT_TYPE_DATA, 64 OBJECT_TYPE_FUNCTION, 65 OBJECT_TYPE_METHOD_CLASS, 66 OBJECT_TYPE_METHOD_OBJECT, 67 OBJECT_TYPE_METHOD_UNKNOWN 68 }; 69 70 // prefix classification 71 enum prefix_type { 72 PREFIX_NONE, 73 PREFIX_NAMESPACE, 74 PREFIX_CLASS, 75 PREFIX_UNKNOWN 76 }; 77 78 // type classification 79 enum type_type { 80 TYPE_ELLIPSIS, 81 TYPE_VOID, 82 TYPE_WCHAR_T, 83 TYPE_BOOL, 84 TYPE_CHAR, 85 TYPE_SIGNED_CHAR, 86 TYPE_UNSIGNED_CHAR, 87 TYPE_SHORT, 88 TYPE_UNSIGNED_SHORT, 89 TYPE_INT, 90 TYPE_UNSIGNED_INT, 91 TYPE_LONG, 92 TYPE_UNSIGNED_LONG, 93 TYPE_LONG_LONG, 94 TYPE_UNSIGNED_LONG_LONG, 95 TYPE_INT128, 96 TYPE_UNSIGNED_INT128, 97 TYPE_FLOAT, 98 TYPE_DOUBLE, 99 TYPE_LONG_DOUBLE, 100 TYPE_FLOAT128, 101 TYPE_DFLOAT16, 102 TYPE_DFLOAT32, 103 TYPE_DFLOAT64, 104 TYPE_DFLOAT128, 105 TYPE_CHAR16_T, 106 TYPE_CHAR32_T, 107 108 TYPE_UNKNOWN, 109 TYPE_CONST_CHAR_POINTER, 110 TYPE_POINTER, 111 TYPE_REFERENCE 112 }; 113 114 const char* const kTypeNames[] = { 115 "...", 116 "void", 117 "wchar_t", 118 "bool", 119 "char", 120 "signed char", 121 "unsigned char", 122 "short", 123 "unsigned short", 124 "int", 125 "unsigned int", 126 "long", 127 "unsigned long", 128 "long long", 129 "unsigned long long", 130 "__int128", 131 "unsigned __int128", 132 "float", 133 "double", 134 "long double", 135 "__float128", 136 "__dfloat16", // TODO: Official names for the __dfloat*! 137 "__dfloat32", 138 "__dfloat64", 139 "__dfloat64", 140 "char16_t", 141 "char32_t", 142 143 "?", 144 "char const*", 145 "void*", 146 "void&" 147 }; 148 149 150 // CV qualifier flags 151 enum { 152 CV_QUALIFIER_RESTRICT = 0x1, 153 CV_QUALIFIER_VOLATILE = 0x2, 154 CV_QUALIFIER_CONST = 0x4 155 }; 156 157 enum type_modifier { 158 TYPE_QUALIFIER_POINTER = 0, 159 TYPE_QUALIFIER_REFERENCE, 160 TYPE_QUALIFIER_RVALUE_REFERENCE, 161 TYPE_QUALIFIER_COMPLEX, 162 TYPE_QUALIFIER_IMAGINARY 163 }; 164 165 static const char* const kTypeModifierSuffixes[] = { 166 "*", 167 "&", 168 "&&", 169 " complex", 170 " imaginary" 171 }; 172 173 struct operator_info { 174 const char* mangled_name; 175 const char* name; 176 int argument_count; 177 int flags; 178 }; 179 180 // operator flags 181 enum { 182 OPERATOR_TYPE_PARAM = 0x01, 183 OPERATOR_IS_MEMBER = 0x02 184 }; 185 186 187 static const operator_info kOperatorInfos[] = { 188 { "nw", "new", -1, OPERATOR_IS_MEMBER }, 189 { "na", "new[]", -1, OPERATOR_IS_MEMBER }, 190 { "dl", "delete", -1, OPERATOR_IS_MEMBER }, 191 { "da", "delete[]", -1, OPERATOR_IS_MEMBER }, 192 { "ps", "+", 1, 0 }, // unary 193 { "ng", "-", 1, 0 }, // unary 194 { "ad", "&", 1, 0 }, // unary 195 { "de", "*", 1, 0 }, // unary 196 { "co", "~", 1, 0 }, 197 { "pl", "+", 2, 0 }, 198 { "mi", "-", 2, 0 }, 199 { "ml", "*", 2, 0 }, 200 { "dv", "/", 2, 0 }, 201 { "rm", "%", 2, 0 }, 202 { "an", "&", 2, 0 }, 203 { "or", "|", 2, 0 }, 204 { "eo", "^", 2, 0 }, 205 { "aS", "=", 2, 0 }, 206 { "pL", "+=", 2, 0 }, 207 { "mI", "-=", 2, 0 }, 208 { "mL", "*=", 2, 0 }, 209 { "dV", "/=", 2, 0 }, 210 { "rM", "%=", 2, 0 }, 211 { "aN", "&=", 2, 0 }, 212 { "oR", "|=", 2, 0 }, 213 { "eO", "^=", 2, 0 }, 214 { "ls", "<<", 2, 0 }, 215 { "rs", ">>", 2, 0 }, 216 { "lS", "<<=", 2, 0 }, 217 { "rS", ">>=", 2, 0 }, 218 { "eq", "==", 2, 0 }, 219 { "ne", "!=", 2, 0 }, 220 { "lt", "<", 2, 0 }, 221 { "gt", ">", 2, 0 }, 222 { "le", "<=", 2, 0 }, 223 { "ge", ">=", 2, 0 }, 224 { "nt", "!", 1, 0 }, 225 { "aa", "&&", 2, 0 }, 226 { "oo", "||", 2, 0 }, 227 { "pp", "++", 1, 0 }, 228 { "mm", "--", 1, 0 }, 229 { "cm", ",", -1, 0 }, 230 { "pm", "->*", 2, 0 }, 231 { "pt", "->", 2, 0 }, 232 { "cl", "()", -1, 0 }, 233 { "ix", "[]", -1, 0 }, 234 { "qu", "?", 3, 0 }, 235 { "st", "sizeof", 1, OPERATOR_TYPE_PARAM }, // type 236 { "sz", "sizeof", 1, 0 }, // expression 237 { "at", "alignof", 1, OPERATOR_TYPE_PARAM }, // type 238 { "az", "alignof", 1, 0 }, // expression 239 {} 240 }; 241 242 243 #ifdef TRACE_GCC3_DEMANGLER 244 245 struct DebugScope { 246 DebugScope(const char* functionName, const char* remainingString = NULL) 247 : 248 fParent(sGlobalScope), 249 fFunctionName(functionName), 250 fLevel(fParent != NULL ? fParent->fLevel + 1 : 0) 251 { 252 sGlobalScope = this; 253 if (remainingString != NULL) { 254 PRINT("%*s%s(): \"%s\"\n", fLevel * 2, "", fFunctionName, 255 remainingString); 256 } else 257 PRINT("%*s%s()\n", fLevel * 2, "", fFunctionName); 258 } 259 260 ~DebugScope() 261 { 262 sGlobalScope = fParent; 263 PRINT("%*s%s() done\n", fLevel * 2, "", fFunctionName); 264 } 265 266 static void Print(const char* format,...) 267 { 268 int level = sGlobalScope != NULL ? sGlobalScope->fLevel : 0; 269 270 va_list args; 271 va_start(args, format); 272 PRINT("%*s", (level + 1) * 2, ""); 273 VPRINT(format, args); 274 va_end(args); 275 } 276 277 private: 278 DebugScope* fParent; 279 const char* fFunctionName; 280 int fLevel; 281 282 static DebugScope* sGlobalScope; 283 }; 284 285 DebugScope* DebugScope::sGlobalScope = NULL; 286 287 #endif // TRACE_GCC3_DEMANGLER 288 289 290 class Input { 291 public: 292 Input() 293 : 294 fString(NULL), 295 fLength(0) 296 { 297 } 298 299 void SetTo(const char* string, size_t length) 300 { 301 fString = string; 302 fLength = length; 303 } 304 305 const char* String() const 306 { 307 return fString; 308 } 309 310 int CharsRemaining() const 311 { 312 return fLength; 313 } 314 315 void Skip(size_t count) 316 { 317 if (count > fLength) { 318 PRINT("Input::Skip(): fOffset > fLength\n"); 319 return; 320 } 321 322 fString += count; 323 fLength -= count; 324 } 325 326 bool HasPrefix(char prefix) const 327 { 328 return fLength > 0 && fString[0] == prefix; 329 } 330 331 bool HasPrefix(const char* prefix) const 332 { 333 size_t prefixLen = strlen(prefix); 334 return prefixLen <= fLength 335 && strncmp(fString, prefix, strlen(prefix)) == 0; 336 } 337 338 bool SkipPrefix(char prefix) 339 { 340 if (!HasPrefix(prefix)) 341 return false; 342 343 fString++; 344 fLength--; 345 return true; 346 } 347 348 bool SkipPrefix(const char* prefix) 349 { 350 size_t prefixLen = strlen(prefix); 351 if (prefixLen <= fLength && strncmp(fString, prefix, prefixLen) != 0) 352 return false; 353 354 fString += prefixLen; 355 fLength -= prefixLen; 356 return true; 357 } 358 359 char operator[](size_t index) const 360 { 361 if (index >= fLength) { 362 PRINT("Input::operator[](): fOffset + index >= fLength\n"); 363 return '\0'; 364 } 365 366 return fString[index]; 367 } 368 369 private: 370 const char* fString; 371 size_t fLength; 372 }; 373 374 375 class NameBuffer { 376 public: 377 NameBuffer(char* buffer, size_t size) 378 : 379 fBuffer(buffer), 380 fSize(size), 381 fLength(0), 382 fOverflow(false) 383 { 384 } 385 386 bool IsEmpty() const 387 { 388 return fLength == 0; 389 } 390 391 char LastChar() const 392 { 393 return fLength > 0 ? fBuffer[fLength - 1] : '\0'; 394 } 395 396 bool HadOverflow() const 397 { 398 return fOverflow; 399 } 400 401 char* Terminate() 402 { 403 fBuffer[fLength] = '\0'; 404 return fBuffer; 405 } 406 407 bool Append(const char* string, size_t length) 408 { 409 if (fLength + length >= fSize) { 410 fOverflow = true; 411 return false; 412 } 413 414 memcpy(fBuffer + fLength, string, length); 415 fLength += length; 416 return true; 417 } 418 419 bool Append(const char* string) 420 { 421 return Append(string, strlen(string)); 422 } 423 424 private: 425 char* fBuffer; 426 size_t fSize; 427 size_t fLength; 428 bool fOverflow; 429 }; 430 431 432 struct TypeInfo { 433 type_type type; 434 int cvQualifiers; 435 436 TypeInfo() 437 : 438 type(TYPE_UNKNOWN), 439 cvQualifiers(0) 440 { 441 } 442 443 TypeInfo(type_type type) 444 : 445 type(type), 446 cvQualifiers(0) 447 { 448 } 449 450 TypeInfo(const TypeInfo& other, int cvQualifiers = 0) 451 : 452 type(other.type), 453 cvQualifiers(other.cvQualifiers | cvQualifiers) 454 { 455 } 456 457 TypeInfo& operator=(const TypeInfo& other) 458 { 459 type = other.type; 460 cvQualifiers = other.cvQualifiers; 461 return *this; 462 } 463 }; 464 465 466 struct DemanglingParameters { 467 bool objectNameOnly; 468 469 DemanglingParameters(bool objectNameOnly) 470 : 471 objectNameOnly(objectNameOnly) 472 { 473 } 474 }; 475 476 477 struct DemanglingInfo : DemanglingParameters { 478 object_type objectType; 479 480 DemanglingInfo(bool objectNameOnly) 481 : 482 DemanglingParameters(objectNameOnly), 483 objectType(OBJECT_TYPE_UNKNOWN) 484 { 485 } 486 }; 487 488 489 struct ParameterInfo { 490 TypeInfo type; 491 492 ParameterInfo() 493 { 494 } 495 }; 496 497 498 class Node; 499 500 struct NameDecorationInfo { 501 const Node* firstDecorator; 502 const Node* closestCVDecoratorList; 503 504 NameDecorationInfo(const Node* decorator) 505 : 506 firstDecorator(decorator), 507 closestCVDecoratorList(NULL) 508 { 509 } 510 }; 511 512 struct CVQualifierInfo { 513 const Node* firstCVQualifier; 514 const Node* firstNonCVQualifier; 515 516 CVQualifierInfo() 517 : 518 firstCVQualifier(NULL), 519 firstNonCVQualifier(NULL) 520 { 521 } 522 }; 523 524 525 class Node { 526 public: 527 Node() 528 : 529 fNextAllocated(NULL), 530 fParent(NULL), 531 fNext(NULL), 532 fNextReferenceable(NULL), 533 fReferenceable(true) 534 { 535 } 536 537 virtual ~Node() 538 { 539 } 540 541 Node* NextAllocated() const { return fNextAllocated; } 542 void SetNextAllocated(Node* node) { fNextAllocated = node; } 543 544 Node* Parent() const { return fParent; } 545 virtual void SetParent(Node* node) { fParent = node; } 546 547 Node* Next() const { return fNext; } 548 void SetNext(Node* node) { fNext = node; } 549 550 bool IsReferenceable() const { return fReferenceable; } 551 void SetReferenceable(bool flag) { fReferenceable = flag; } 552 553 Node* NextReferenceable() const { return fNextReferenceable; } 554 void SetNextReferenceable(Node* node) { fNextReferenceable = node; } 555 556 virtual bool GetName(NameBuffer& buffer) const = 0; 557 558 virtual bool GetDecoratedName(NameBuffer& buffer, 559 NameDecorationInfo& decorationInfo) const 560 { 561 if (!GetName(buffer)) 562 return false; 563 564 return decorationInfo.firstDecorator == NULL 565 || decorationInfo.firstDecorator->AddDecoration(buffer, NULL); 566 } 567 568 virtual bool AddDecoration(NameBuffer& buffer, 569 const Node* stopDecorator) const 570 { 571 return true; 572 } 573 574 virtual void GetCVQualifierInfo(CVQualifierInfo& info) const 575 { 576 info.firstNonCVQualifier = this; 577 } 578 579 virtual Node* GetUnqualifiedNode(Node* beforeNode) 580 { 581 return this; 582 } 583 584 virtual bool IsTemplatized() const 585 { 586 return false; 587 } 588 589 virtual Node* TemplateParameterAt(int index) const 590 { 591 return NULL; 592 } 593 594 virtual bool IsNoReturnValueFunction() const 595 { 596 return false; 597 } 598 599 virtual bool IsTypeName(const char* name, size_t length) const 600 { 601 return false; 602 } 603 604 virtual object_type ObjectType() const 605 { 606 return OBJECT_TYPE_UNKNOWN; 607 } 608 609 virtual prefix_type PrefixType() const 610 { 611 return PREFIX_NONE; 612 } 613 614 virtual TypeInfo Type() const 615 { 616 return TypeInfo(); 617 } 618 619 private: 620 Node* fNextAllocated; 621 Node* fParent; 622 Node* fNext; 623 Node* fNextReferenceable; 624 bool fReferenceable; 625 }; 626 627 628 class NamedTypeNode : public Node { 629 public: 630 NamedTypeNode(Node* name) 631 : 632 fName(name) 633 { 634 if (fName != NULL) 635 fName->SetParent(this); 636 } 637 638 virtual bool GetName(NameBuffer& buffer) const 639 { 640 return fName == NULL || fName->GetName(buffer); 641 } 642 643 virtual bool IsNoReturnValueFunction() const 644 { 645 return fName != NULL && fName->IsNoReturnValueFunction(); 646 } 647 648 virtual TypeInfo Type() const 649 { 650 return fName != NULL ? fName->Type() : TypeInfo(); 651 } 652 653 protected: 654 Node* fName; 655 }; 656 657 658 class SubstitutionNode : public Node { 659 public: 660 SubstitutionNode(Node* node) 661 : 662 fNode(node) 663 { 664 } 665 666 virtual bool GetName(NameBuffer& buffer) const 667 { 668 return fNode->GetName(buffer); 669 } 670 671 virtual bool GetDecoratedName(NameBuffer& buffer, 672 NameDecorationInfo& decorationInfo) const 673 { 674 return fNode->GetDecoratedName(buffer, decorationInfo); 675 } 676 677 virtual bool AddDecoration(NameBuffer& buffer, 678 const Node* stopDecorator) const 679 { 680 return fNode->AddDecoration(buffer, stopDecorator); 681 } 682 683 virtual void GetCVQualifierInfo(CVQualifierInfo& info) const 684 { 685 fNode->GetCVQualifierInfo(info); 686 } 687 688 virtual bool IsTemplatized() const 689 { 690 return fNode->IsTemplatized(); 691 } 692 693 virtual Node* TemplateParameterAt(int index) const 694 { 695 return fNode->TemplateParameterAt(index); 696 } 697 698 virtual bool IsNoReturnValueFunction() const 699 { 700 return fNode->IsNoReturnValueFunction(); 701 } 702 703 virtual bool IsTypeName(const char* name, size_t length) const 704 { 705 return fNode->IsTypeName(name, length); 706 } 707 708 virtual object_type ObjectType() const 709 { 710 return fNode->ObjectType(); 711 } 712 713 virtual prefix_type PrefixType() const 714 { 715 return fNode->PrefixType(); 716 } 717 718 virtual TypeInfo Type() const 719 { 720 return fNode->Type(); 721 } 722 723 private: 724 Node* fNode; 725 }; 726 727 728 class ArrayNode : public NamedTypeNode { 729 public: 730 ArrayNode(Node* type, int dimension) 731 : 732 NamedTypeNode(type), 733 fDimensionExpression(NULL), 734 fDimensionNumber(dimension) 735 { 736 } 737 738 ArrayNode(Node* type, Node* dimension) 739 : 740 NamedTypeNode(type), 741 fDimensionExpression(dimension), 742 fDimensionNumber(0) 743 { 744 fDimensionExpression->SetParent(this); 745 } 746 747 virtual bool GetName(NameBuffer& buffer) const 748 { 749 if (!fName->GetName(buffer)) 750 return false; 751 752 buffer.Append("[", 1); 753 754 if (fDimensionExpression != NULL) { 755 if (!fDimensionExpression->GetName(buffer)) 756 return false; 757 } else { 758 char stringBuffer[16]; 759 snprintf(stringBuffer, sizeof(stringBuffer), "%d", 760 fDimensionNumber); 761 buffer.Append(stringBuffer); 762 } 763 764 return buffer.Append("]", 1); 765 } 766 767 virtual object_type ObjectType() const 768 { 769 return OBJECT_TYPE_DATA; 770 } 771 772 virtual TypeInfo Type() const 773 { 774 // TODO: Check! 775 return TypeInfo(TYPE_POINTER); 776 } 777 778 779 private: 780 Node* fDimensionExpression; 781 int fDimensionNumber; 782 }; 783 784 785 class ObjectNode : public NamedTypeNode { 786 public: 787 ObjectNode(Node* name) 788 : 789 NamedTypeNode(name) 790 { 791 } 792 793 virtual bool GetObjectName(NameBuffer& buffer, 794 const DemanglingParameters& parameters) 795 { 796 if (parameters.objectNameOnly) 797 return fName != NULL ? fName->GetName(buffer) : true; 798 799 return GetName(buffer); 800 } 801 802 virtual object_type ObjectType() const 803 { 804 return OBJECT_TYPE_DATA; 805 } 806 807 virtual Node* ParameterAt(uint32 index) const 808 { 809 return NULL; 810 } 811 }; 812 813 814 class SimpleNameNode : public Node { 815 public: 816 SimpleNameNode(const char* name) 817 : 818 fName(name), 819 fLength(strlen(name)) 820 { 821 } 822 823 SimpleNameNode(const char* name, size_t length) 824 : 825 fName(name), 826 fLength(length) 827 { 828 } 829 830 virtual bool GetName(NameBuffer& buffer) const 831 { 832 return buffer.Append(fName, fLength); 833 } 834 835 protected: 836 const char* fName; 837 size_t fLength; 838 }; 839 840 841 class SimpleTypeNode : public SimpleNameNode { 842 public: 843 SimpleTypeNode(const char* name) 844 : 845 SimpleNameNode(name), 846 fType(TYPE_UNKNOWN) 847 { 848 } 849 850 SimpleTypeNode(type_type type) 851 : 852 SimpleNameNode(kTypeNames[type]), 853 fType(type) 854 { 855 } 856 857 virtual bool IsTypeName(const char* name, size_t length) const 858 { 859 return fLength == length && strcmp(fName, name) == 0; 860 } 861 862 virtual object_type ObjectType() const 863 { 864 return OBJECT_TYPE_DATA; 865 } 866 867 virtual TypeInfo Type() const 868 { 869 return TypeInfo(fType); 870 } 871 872 private: 873 type_type fType; 874 }; 875 876 877 class TypedNumberLiteralNode : public Node { 878 public: 879 TypedNumberLiteralNode(Node* type, const char* number, size_t length) 880 : 881 fType(type), 882 fNumber(number), 883 fLength(length) 884 { 885 fType->SetParent(this); 886 } 887 888 virtual bool GetName(NameBuffer& buffer) const 889 { 890 // If the type is bool and the number is 0 or 1, we use "false" or 891 // "true" respectively. 892 if (fType->IsTypeName("bool", 4) && fLength == 1 893 && (fNumber[0] == '0' || fNumber[0] == '1')) { 894 return buffer.Append(fNumber[0] == '0' ? "false" : "true"); 895 } 896 897 // Add the type in parentheses. The GNU demangler omits "int", so do we. 898 if (!fType->IsTypeName("int", 3)) { 899 buffer.Append("("); 900 if (!fType->GetName(buffer)) 901 return false; 902 buffer.Append(")"); 903 } 904 905 // add the number -- replace a leading 'n' by '-', if necessary 906 if (fLength > 0 && fNumber[0] == 'n') { 907 buffer.Append("-"); 908 return buffer.Append(fNumber + 1, fLength - 1); 909 } 910 911 return buffer.Append(fNumber, fLength); 912 } 913 914 virtual object_type ObjectType() const 915 { 916 return OBJECT_TYPE_DATA; 917 } 918 919 private: 920 Node* fType; 921 const char* fNumber; 922 size_t fLength; 923 }; 924 925 926 class XtructorNode : public Node { 927 public: 928 XtructorNode(bool constructor, char type) 929 : 930 fConstructor(constructor), 931 fType(type) 932 { 933 } 934 935 virtual void SetParent(Node* node) 936 { 937 fUnqualifiedNode = node->GetUnqualifiedNode(this); 938 Node::SetParent(node); 939 } 940 941 virtual bool GetName(NameBuffer& buffer) const 942 { 943 if (fUnqualifiedNode == NULL) 944 return false; 945 946 if (!fConstructor) 947 buffer.Append("~"); 948 949 return fUnqualifiedNode->GetName(buffer); 950 } 951 952 virtual bool IsNoReturnValueFunction() const 953 { 954 return true; 955 } 956 957 virtual object_type ObjectType() const 958 { 959 return OBJECT_TYPE_METHOD_CLASS; 960 } 961 962 private: 963 bool fConstructor; 964 char fType; 965 Node* fUnqualifiedNode; 966 }; 967 968 969 class SpecialNameNode : public Node { 970 public: 971 SpecialNameNode(const char* name, Node* child) 972 : 973 fName(name), 974 fChild(child) 975 { 976 fChild->SetParent(this); 977 } 978 979 virtual bool GetName(NameBuffer& buffer) const 980 { 981 return buffer.Append(fName) && fChild->GetName(buffer); 982 } 983 984 protected: 985 const char* fName; 986 Node* fChild; 987 }; 988 989 990 class DecoratingNode : public Node { 991 public: 992 DecoratingNode(Node* child) 993 : 994 fChildNode(child) 995 { 996 fChildNode->SetParent(this); 997 } 998 999 virtual bool GetName(NameBuffer& buffer) const 1000 { 1001 NameDecorationInfo decorationInfo(this); 1002 return fChildNode->GetDecoratedName(buffer, decorationInfo); 1003 } 1004 1005 virtual bool GetDecoratedName(NameBuffer& buffer, 1006 NameDecorationInfo& decorationInfo) const 1007 { 1008 decorationInfo.closestCVDecoratorList = NULL; 1009 return fChildNode->GetDecoratedName(buffer, decorationInfo); 1010 } 1011 1012 protected: 1013 Node* fChildNode; 1014 }; 1015 1016 1017 class CVQualifiersNode : public DecoratingNode { 1018 public: 1019 CVQualifiersNode(int qualifiers, Node* child) 1020 : 1021 DecoratingNode(child), 1022 fCVQualifiers(qualifiers) 1023 { 1024 } 1025 1026 virtual bool GetDecoratedName(NameBuffer& buffer, 1027 NameDecorationInfo& decorationInfo) const 1028 { 1029 if (decorationInfo.closestCVDecoratorList == NULL) 1030 decorationInfo.closestCVDecoratorList = this; 1031 return fChildNode->GetDecoratedName(buffer, decorationInfo); 1032 } 1033 1034 virtual bool AddDecoration(NameBuffer& buffer, 1035 const Node* stopDecorator) const 1036 { 1037 if (this == stopDecorator) 1038 return true; 1039 1040 if (!fChildNode->AddDecoration(buffer, stopDecorator)) 1041 return false; 1042 1043 if ((fCVQualifiers & CV_QUALIFIER_RESTRICT) != 0) 1044 buffer.Append(" restrict"); 1045 if ((fCVQualifiers & CV_QUALIFIER_VOLATILE) != 0) 1046 buffer.Append(" volatile"); 1047 if ((fCVQualifiers & CV_QUALIFIER_CONST) != 0) 1048 buffer.Append(" const"); 1049 1050 return true; 1051 } 1052 1053 virtual void GetCVQualifierInfo(CVQualifierInfo& info) const 1054 { 1055 if (info.firstCVQualifier == NULL) 1056 info.firstCVQualifier = this; 1057 fChildNode->GetCVQualifierInfo(info); 1058 } 1059 1060 virtual bool IsTemplatized() const 1061 { 1062 return fChildNode->IsTemplatized(); 1063 } 1064 1065 virtual Node* TemplateParameterAt(int index) const 1066 { 1067 return fChildNode->TemplateParameterAt(index); 1068 } 1069 1070 virtual bool IsNoReturnValueFunction() const 1071 { 1072 return fChildNode->IsNoReturnValueFunction(); 1073 } 1074 1075 virtual object_type ObjectType() const 1076 { 1077 return fChildNode->ObjectType(); 1078 } 1079 1080 virtual prefix_type PrefixType() const 1081 { 1082 return fChildNode->PrefixType(); 1083 } 1084 1085 virtual TypeInfo Type() const 1086 { 1087 return TypeInfo(fChildNode->Type(), fCVQualifiers); 1088 } 1089 1090 private: 1091 int fCVQualifiers; 1092 }; 1093 1094 1095 class TypeModifierNode : public DecoratingNode { 1096 public: 1097 TypeModifierNode(type_modifier modifier, Node* child) 1098 : 1099 DecoratingNode(child), 1100 fModifier(modifier) 1101 { 1102 } 1103 1104 virtual bool AddDecoration(NameBuffer& buffer, 1105 const Node* stopDecorator) const 1106 { 1107 if (this == stopDecorator) 1108 return true; 1109 1110 return fChildNode->AddDecoration(buffer, stopDecorator) 1111 && buffer.Append(kTypeModifierSuffixes[fModifier]); 1112 } 1113 1114 virtual object_type ObjectType() const 1115 { 1116 return OBJECT_TYPE_DATA; 1117 } 1118 1119 virtual TypeInfo Type() const 1120 { 1121 TypeInfo type = fChildNode->Type(); 1122 if (type.type == TYPE_CHAR 1123 && (type.cvQualifiers & CV_QUALIFIER_CONST) != 0) { 1124 return TypeInfo(TYPE_CONST_CHAR_POINTER); 1125 } 1126 1127 switch (fModifier) { 1128 case TYPE_QUALIFIER_POINTER: 1129 return TypeInfo(TYPE_POINTER); 1130 case TYPE_QUALIFIER_REFERENCE: 1131 return TypeInfo(TYPE_REFERENCE); 1132 default: 1133 return TypeInfo(); 1134 } 1135 } 1136 1137 private: 1138 type_modifier fModifier; 1139 }; 1140 1141 1142 class VendorTypeModifierNode : public DecoratingNode { 1143 public: 1144 VendorTypeModifierNode(Node* name, Node* child) 1145 : 1146 DecoratingNode(child), 1147 fName(name) 1148 { 1149 fName->SetParent(this); 1150 } 1151 1152 virtual bool AddDecoration(NameBuffer& buffer, 1153 const Node* stopDecorator) const 1154 { 1155 if (this == stopDecorator) 1156 return true; 1157 1158 return fChildNode->AddDecoration(buffer, stopDecorator) 1159 && buffer.Append(" ") 1160 && fName->GetName(buffer); 1161 } 1162 1163 virtual object_type ObjectType() const 1164 { 1165 return OBJECT_TYPE_DATA; 1166 } 1167 1168 private: 1169 Node* fName; 1170 }; 1171 1172 1173 class OperatorNode : public Node { 1174 public: 1175 OperatorNode(const operator_info* info) 1176 : 1177 fInfo(info) 1178 { 1179 SetReferenceable(false); 1180 } 1181 1182 virtual bool GetName(NameBuffer& buffer) const 1183 { 1184 return buffer.Append( 1185 isalpha(fInfo->name[0]) ? "operator " : "operator") 1186 && buffer.Append(fInfo->name); 1187 } 1188 1189 virtual object_type ObjectType() const 1190 { 1191 return (fInfo->flags & OPERATOR_IS_MEMBER) != 0 1192 ? OBJECT_TYPE_METHOD_CLASS : OBJECT_TYPE_UNKNOWN; 1193 } 1194 1195 private: 1196 const operator_info* fInfo; 1197 }; 1198 1199 1200 class VendorOperatorNode : public Node { 1201 public: 1202 VendorOperatorNode(Node* name) 1203 : 1204 fName(name) 1205 { 1206 fName->SetParent(this); 1207 SetReferenceable(false); 1208 } 1209 1210 virtual bool GetName(NameBuffer& buffer) const 1211 { 1212 return buffer.Append("operator ") 1213 && fName->GetName(buffer); 1214 } 1215 1216 private: 1217 Node* fName; 1218 }; 1219 1220 1221 class CastOperatorNode : public Node { 1222 public: 1223 CastOperatorNode(Node* child) 1224 : 1225 fChildNode(child) 1226 { 1227 fChildNode->SetParent(this); 1228 } 1229 1230 virtual bool GetName(NameBuffer& buffer) const 1231 { 1232 return buffer.Append("operator ") && fChildNode->GetName(buffer); 1233 } 1234 1235 virtual bool IsNoReturnValueFunction() const 1236 { 1237 return true; 1238 } 1239 1240 virtual object_type ObjectType() const 1241 { 1242 return OBJECT_TYPE_METHOD_OBJECT; 1243 } 1244 1245 private: 1246 Node* fChildNode; 1247 }; 1248 1249 1250 class PrefixedNode : public Node { 1251 public: 1252 PrefixedNode(Node* prefix, Node* node) 1253 : 1254 fPrefixNode(prefix), 1255 fNode(node) 1256 { 1257 fPrefixNode->SetParent(this); 1258 fNode->SetParent(this); 1259 } 1260 1261 virtual bool GetName(NameBuffer& buffer) const 1262 { 1263 if (!fPrefixNode->GetName(buffer)) 1264 return false; 1265 1266 buffer.Append("::"); 1267 return fNode->GetName(buffer); 1268 } 1269 1270 virtual Node* GetUnqualifiedNode(Node* beforeNode) 1271 { 1272 return beforeNode == fNode 1273 ? fPrefixNode->GetUnqualifiedNode(beforeNode) 1274 : fNode->GetUnqualifiedNode(beforeNode); 1275 } 1276 1277 virtual bool IsNoReturnValueFunction() const 1278 { 1279 return fNode->IsNoReturnValueFunction(); 1280 } 1281 1282 virtual object_type ObjectType() const 1283 { 1284 return fNode->ObjectType(); 1285 } 1286 1287 virtual prefix_type PrefixType() const 1288 { 1289 return PREFIX_UNKNOWN; 1290 } 1291 1292 private: 1293 Node* fPrefixNode; 1294 Node* fNode; 1295 }; 1296 1297 1298 typedef PrefixedNode DependentNameNode; 1299 1300 1301 class TemplateNode : public Node { 1302 public: 1303 TemplateNode(Node* base) 1304 : 1305 fBase(base), 1306 fFirstArgument(NULL), 1307 fLastArgument(NULL) 1308 { 1309 fBase->SetParent(this); 1310 } 1311 1312 void AddArgument(Node* child) 1313 { 1314 child->SetParent(this); 1315 1316 if (fLastArgument != NULL) { 1317 fLastArgument->SetNext(child); 1318 fLastArgument = child; 1319 } else { 1320 fFirstArgument = child; 1321 fLastArgument = child; 1322 } 1323 } 1324 1325 virtual bool GetName(NameBuffer& buffer) const 1326 { 1327 if (!fBase->GetName(buffer)) 1328 return false; 1329 1330 buffer.Append("<"); 1331 1332 Node* child = fFirstArgument; 1333 while (child != NULL) { 1334 if (child != fFirstArgument) 1335 buffer.Append(", "); 1336 1337 if (!child->GetName(buffer)) 1338 return false; 1339 1340 child = child->Next(); 1341 } 1342 1343 // add a space between consecutive '>' 1344 if (buffer.LastChar() == '>') 1345 buffer.Append(" "); 1346 1347 return buffer.Append(">"); 1348 } 1349 1350 virtual Node* GetUnqualifiedNode(Node* beforeNode) 1351 { 1352 return fBase != beforeNode 1353 ? fBase->GetUnqualifiedNode(beforeNode) : this; 1354 } 1355 1356 virtual bool IsTemplatized() const 1357 { 1358 return true; 1359 } 1360 1361 virtual Node* TemplateParameterAt(int index) const 1362 { 1363 Node* child = fFirstArgument; 1364 while (child != NULL) { 1365 if (index == 0) 1366 return child; 1367 index--; 1368 child = child->Next(); 1369 } 1370 1371 return NULL; 1372 } 1373 1374 virtual bool IsNoReturnValueFunction() const 1375 { 1376 return fBase->IsNoReturnValueFunction(); 1377 } 1378 1379 virtual object_type ObjectType() const 1380 { 1381 return fBase->ObjectType(); 1382 } 1383 1384 virtual prefix_type PrefixType() const 1385 { 1386 return fBase->PrefixType(); 1387 } 1388 1389 protected: 1390 Node* fBase; 1391 Node* fFirstArgument; 1392 Node* fLastArgument; 1393 }; 1394 1395 1396 class MultiSubExpressionsNode : public Node { 1397 public: 1398 MultiSubExpressionsNode() 1399 : 1400 fFirstSubExpression(NULL), 1401 fLastSubExpression(NULL) 1402 { 1403 } 1404 1405 void AddSubExpression(Node* child) 1406 { 1407 child->SetParent(this); 1408 1409 if (fLastSubExpression != NULL) { 1410 fLastSubExpression->SetNext(child); 1411 fLastSubExpression = child; 1412 } else { 1413 fFirstSubExpression = child; 1414 fLastSubExpression = child; 1415 } 1416 } 1417 1418 protected: 1419 Node* fFirstSubExpression; 1420 Node* fLastSubExpression; 1421 }; 1422 1423 1424 class CallNode : public MultiSubExpressionsNode { 1425 public: 1426 CallNode() 1427 { 1428 } 1429 1430 virtual bool GetName(NameBuffer& buffer) const 1431 { 1432 // TODO: Use the real syntax! 1433 buffer.Append("call("); 1434 1435 Node* child = fFirstSubExpression; 1436 while (child != NULL) { 1437 if (child != fFirstSubExpression) 1438 buffer.Append(", "); 1439 1440 if (!child->GetName(buffer)) 1441 return false; 1442 1443 child = child->Next(); 1444 } 1445 1446 buffer.Append(")"); 1447 1448 return true; 1449 } 1450 }; 1451 1452 1453 class OperatorExpressionNode : public MultiSubExpressionsNode { 1454 public: 1455 OperatorExpressionNode(const operator_info* info) 1456 : 1457 fInfo(info) 1458 { 1459 } 1460 1461 virtual bool GetName(NameBuffer& buffer) const 1462 { 1463 bool isIdentifier = isalpha(fInfo->name[0]) || fInfo->name[0] == '_'; 1464 1465 if (fInfo->argument_count == 1 || isIdentifier 1466 || fInfo->argument_count > 3 1467 || (fInfo->argument_count == 3 && strcmp(fInfo->name, "?") != 0)) { 1468 // prefix operator 1469 buffer.Append(fInfo->name); 1470 1471 if (isIdentifier) 1472 buffer.Append("("); 1473 1474 Node* child = fFirstSubExpression; 1475 while (child != NULL) { 1476 if (child != fFirstSubExpression) 1477 buffer.Append(", "); 1478 1479 if (!child->GetName(buffer)) 1480 return false; 1481 1482 child = child->Next(); 1483 } 1484 1485 if (isIdentifier) 1486 buffer.Append(")"); 1487 1488 return true; 1489 } 1490 1491 Node* arg1 = fFirstSubExpression; 1492 Node* arg2 = arg1->Next(); 1493 1494 buffer.Append("("); 1495 1496 if (fInfo->argument_count == 2) { 1497 // binary infix operator 1498 if (!arg1->GetName(buffer)) 1499 return false; 1500 1501 buffer.Append(" "); 1502 buffer.Append(fInfo->name); 1503 buffer.Append(" "); 1504 1505 if (!arg2->GetName(buffer)) 1506 return false; 1507 1508 return buffer.Append(")"); 1509 } 1510 1511 Node* arg3 = arg2->Next(); 1512 1513 if (fInfo->argument_count == 2) { 1514 // trinary operator "... ? ... : ..." 1515 if (!arg1->GetName(buffer)) 1516 return false; 1517 1518 buffer.Append(" ? "); 1519 1520 if (!arg2->GetName(buffer)) 1521 return false; 1522 1523 buffer.Append(" : "); 1524 1525 if (!arg3->GetName(buffer)) 1526 return false; 1527 1528 return buffer.Append(")"); 1529 } 1530 1531 return false; 1532 } 1533 1534 private: 1535 const operator_info* fInfo; 1536 }; 1537 1538 1539 class ConversionExpressionNode : public MultiSubExpressionsNode { 1540 public: 1541 ConversionExpressionNode(Node* type) 1542 : 1543 fType(type) 1544 { 1545 fType->SetParent(this); 1546 } 1547 1548 virtual bool GetName(NameBuffer& buffer) const 1549 { 1550 buffer.Append("("); 1551 1552 if (!fType->GetName(buffer)) 1553 return false; 1554 1555 buffer.Append(")("); 1556 1557 Node* child = fFirstSubExpression; 1558 while (child != NULL) { 1559 if (child != fFirstSubExpression) 1560 buffer.Append(", "); 1561 1562 if (!child->GetName(buffer)) 1563 return false; 1564 1565 child = child->Next(); 1566 } 1567 1568 return buffer.Append(")"); 1569 } 1570 1571 private: 1572 Node* fType; 1573 }; 1574 1575 1576 class PointerToMemberNode : public DecoratingNode { 1577 public: 1578 PointerToMemberNode(Node* classType, Node* memberType) 1579 : 1580 DecoratingNode(memberType), 1581 fClassType(classType) 1582 { 1583 fClassType->SetParent(this); 1584 } 1585 1586 virtual bool AddDecoration(NameBuffer& buffer, 1587 const Node* stopDecorator) const 1588 { 1589 if (this == stopDecorator) 1590 return true; 1591 1592 if (!fChildNode->AddDecoration(buffer, stopDecorator)) 1593 return false; 1594 1595 // In most cases we need a space before the name. In some it is 1596 // superfluous, though. 1597 if (!buffer.IsEmpty() && buffer.LastChar() != '(') 1598 buffer.Append(" "); 1599 1600 if (!fClassType->GetName(buffer)) 1601 return false; 1602 1603 return buffer.Append("::*"); 1604 } 1605 1606 virtual object_type ObjectType() const 1607 { 1608 return OBJECT_TYPE_DATA; 1609 } 1610 1611 virtual TypeInfo Type() const 1612 { 1613 // TODO: Method pointers aren't ordinary pointers. Though we might not 1614 // be able to determine the difference. 1615 return TypeInfo(TYPE_POINTER); 1616 } 1617 1618 1619 private: 1620 Node* fClassType; 1621 }; 1622 1623 1624 class FunctionNode : public ObjectNode { 1625 public: 1626 FunctionNode(Node* nameNode, bool hasReturnType, bool isExternC) 1627 : 1628 ObjectNode(nameNode), 1629 fFirstTypeNode(NULL), 1630 fLastTypeNode(NULL), 1631 fHasReturnType(hasReturnType), 1632 fIsExternC(isExternC) 1633 { 1634 } 1635 1636 void AddType(Node* child) 1637 { 1638 child->SetParent(this); 1639 1640 if (fLastTypeNode != NULL) { 1641 fLastTypeNode->SetNext(child); 1642 fLastTypeNode = child; 1643 } else { 1644 fFirstTypeNode = child; 1645 fLastTypeNode = child; 1646 } 1647 } 1648 1649 virtual bool GetName(NameBuffer& buffer) const 1650 { 1651 NameDecorationInfo decorationInfo(NULL); 1652 return GetDecoratedName(buffer, decorationInfo); 1653 } 1654 1655 virtual bool GetDecoratedName(NameBuffer& buffer, 1656 NameDecorationInfo& decorationInfo) const 1657 { 1658 // write 'extern "C"' 1659 // if (fIsExternC) 1660 // buffer.Append("extern \"C\""); 1661 1662 // write the return type 1663 Node* child = fFirstTypeNode; 1664 if (_HasReturnType() && child != NULL) { 1665 if (!child->GetName(buffer)) 1666 return false; 1667 child = child->Next(); 1668 1669 buffer.Append(" ", 1); 1670 } 1671 1672 // write the function name 1673 if (fName == NULL) 1674 buffer.Append("(", 1); 1675 1676 CVQualifierInfo info; 1677 if (fName != NULL) { 1678 // skip CV qualifiers on our name -- we'll add them later 1679 fName->GetCVQualifierInfo(info); 1680 if (info.firstNonCVQualifier != NULL 1681 && !info.firstNonCVQualifier->GetName(buffer)) { 1682 return false; 1683 } 1684 } 1685 1686 // add non-CV qualifier decorations 1687 if (decorationInfo.firstDecorator != NULL) { 1688 if (!decorationInfo.firstDecorator->AddDecoration(buffer, 1689 decorationInfo.closestCVDecoratorList)) { 1690 return false; 1691 } 1692 } 1693 1694 if (fName == NULL) 1695 buffer.Append(")", 1); 1696 1697 // add the parameter types 1698 buffer.Append("("); 1699 1700 // don't add a single "void" parameter 1701 if (child != NULL && child->Next() == NULL 1702 && child->IsTypeName("void", 4)) { 1703 child = NULL; 1704 } 1705 1706 Node* firstParam = child; 1707 while (child != NULL) { 1708 if (child != firstParam) 1709 buffer.Append(", "); 1710 1711 if (!child->GetName(buffer)) 1712 return false; 1713 1714 child = child->Next(); 1715 } 1716 1717 buffer.Append(")"); 1718 1719 // add CV qualifiers on our name 1720 if (info.firstCVQualifier != NULL) { 1721 if (!info.firstCVQualifier->AddDecoration(buffer, 1722 info.firstNonCVQualifier)) { 1723 return false; 1724 } 1725 } 1726 1727 // add CV qualifiers on us 1728 if (decorationInfo.closestCVDecoratorList != NULL) 1729 decorationInfo.closestCVDecoratorList->AddDecoration(buffer, NULL); 1730 1731 return true; 1732 } 1733 1734 virtual object_type ObjectType() const 1735 { 1736 // no name, no fun 1737 if (fName == NULL) 1738 return OBJECT_TYPE_FUNCTION; 1739 1740 // check our name's prefix 1741 switch (fName->PrefixType()) { 1742 case PREFIX_NONE: 1743 case PREFIX_NAMESPACE: 1744 return OBJECT_TYPE_FUNCTION; 1745 case PREFIX_CLASS: 1746 case PREFIX_UNKNOWN: 1747 break; 1748 } 1749 1750 // Our name has a prefix, but we don't know, whether it is a class or 1751 // namespace. Let's ask our name what it thinks it is. 1752 object_type type = fName->ObjectType(); 1753 switch (type) { 1754 case OBJECT_TYPE_FUNCTION: 1755 case OBJECT_TYPE_METHOD_CLASS: 1756 case OBJECT_TYPE_METHOD_OBJECT: 1757 case OBJECT_TYPE_METHOD_UNKNOWN: 1758 // That's as good as it gets. 1759 return type; 1760 case OBJECT_TYPE_UNKNOWN: 1761 case OBJECT_TYPE_DATA: 1762 default: 1763 // Obviously our name doesn't have a clue. 1764 return OBJECT_TYPE_METHOD_UNKNOWN; 1765 } 1766 } 1767 1768 virtual Node* ParameterAt(uint32 index) const 1769 { 1770 // skip return type 1771 Node* child = fFirstTypeNode; 1772 if (_HasReturnType() && child != NULL) 1773 child = child->Next(); 1774 1775 // ignore a single "void" parameter 1776 if (child != NULL && child->Next() == NULL 1777 && child->IsTypeName("void", 4)) { 1778 return NULL; 1779 } 1780 1781 // get the type at the index 1782 while (child != NULL && index > 0) { 1783 child = child->Next(); 1784 index--; 1785 } 1786 1787 return child; 1788 } 1789 1790 private: 1791 bool _HasReturnType() const 1792 { 1793 return fHasReturnType 1794 || fName == NULL 1795 || (fName->IsTemplatized() && !fName->IsNoReturnValueFunction()); 1796 } 1797 1798 private: 1799 Node* fFirstTypeNode; 1800 Node* fLastTypeNode; 1801 bool fHasReturnType; 1802 bool fIsExternC; 1803 }; 1804 1805 1806 // #pragma mark - Demangler 1807 1808 1809 class Demangler { 1810 public: 1811 Demangler(); 1812 1813 int Demangle(const char* mangledName, char* buffer, 1814 size_t size, 1815 DemanglingInfo& demanglingInfo); 1816 int GetParameterInfo(const char* mangledName, 1817 uint32 index, char* buffer, size_t size, 1818 ParameterInfo& info); 1819 1820 // actually private, but public to make gcc 2 happy 1821 inline bool _SetError(int error); 1822 inline void _AddAllocatedNode(Node* node); 1823 1824 private: 1825 template<typename NodeType> struct NodeCreator; 1826 1827 inline bool _SkipExpected(char c); 1828 inline bool _SkipExpected(const char* string); 1829 1830 void _Init(); 1831 void _Cleanup(); 1832 1833 int _Demangle(const char* mangledName, char* buffer, 1834 size_t size, 1835 DemanglingInfo& demanglingInfo); 1836 int _GetParameterInfo(const char* mangledName, 1837 uint32 index, char* buffer, size_t size, 1838 ParameterInfo& info); 1839 1840 int _Parse(const char* mangledName, 1841 const char*& versionSuffix, 1842 ObjectNode*& _node); 1843 1844 bool _ParseEncoding(ObjectNode*& _node); 1845 bool _ParseSpecialName(Node*& _node); 1846 bool _ParseCallOffset(bool& nonVirtual, 1847 number_type& offset1, number_type& offset2); 1848 bool _ParseName(Node*& _node); 1849 bool _ParseNestedName(Node*& _node); 1850 bool _ParseNestedNameInternal(Node*& _node); 1851 bool _ParseLocalName(Node*& _node); 1852 bool _ParseUnqualifiedName(Node*& _node); 1853 bool _ParseSourceName(Node*& _node); 1854 bool _ParseOperatorName(Node*& _node); 1855 bool _ParseType(Node*& _node); 1856 bool _ParseTypeInternal(Node*& _node); 1857 void _ParseCVQualifiers(int& qualifiers); 1858 bool _ParseTypeWithModifier(type_modifier modifier, 1859 int toSkip, Node*& _node); 1860 bool _TryParseBuiltinType(Node*& _node); 1861 bool _ParseFunctionType(FunctionNode*& _node);; 1862 bool _ParseArrayType(Node*& _node); 1863 bool _ParsePointerToMemberType(Node*& _node); 1864 bool _ParseTemplateParam(Node*& _node); 1865 bool _ParseSubstitution(Node*& _node); 1866 bool _ParseSubstitutionInternal(Node*& _node); 1867 bool _ParseBareFunctionType(FunctionNode* node); 1868 bool _ParseTemplateArgs(Node* node, Node*& _node); 1869 bool _ParseTemplateArg(Node*& _node); 1870 bool _ParseExpression(Node*& _node); 1871 bool _ParseExpressionPrimary(Node*& _node); 1872 bool _ParseNumber(number_type& number); 1873 1874 bool _CreateNodeAndSkip(const char* name, 1875 size_t length, int toSkip, Node*& _node); 1876 bool _CreateNodeAndSkip(const char* name, int toSkip, 1877 Node*& _node); 1878 bool _CreateTypeNodeAndSkip(type_type type, 1879 int toSkip, Node*& _node); 1880 bool _CreateTypeNodeAndSkip(const char* name, 1881 const char* prefix, 1882 const char* templateArgs, int toSkip, 1883 Node*& _node); 1884 1885 void _RegisterReferenceableNode(Node* node); 1886 bool _CreateSubstitutionNode(int index, 1887 Node*& _node); 1888 1889 private: 1890 Input fInput; 1891 int fError; 1892 Node* fAllocatedNodes; 1893 Node* fFirstReferenceableNode; 1894 Node* fLastReferenceableNode; 1895 Node* fTemplatizedNode; 1896 }; 1897 1898 1899 template<typename NodeType> 1900 struct Demangler::NodeCreator { 1901 NodeCreator(Demangler* demangler) 1902 : 1903 fDemangler(demangler) 1904 { 1905 } 1906 1907 template<typename ReturnType> 1908 inline bool operator()(ReturnType*& _node) const 1909 { 1910 _node = NEW(NodeType); 1911 if (_node == NULL) 1912 return fDemangler->_SetError(ERROR_NO_MEMORY); 1913 1914 fDemangler->_AddAllocatedNode(_node); 1915 return true; 1916 } 1917 1918 template<typename ParameterType1, typename ReturnType> 1919 inline bool operator()(ParameterType1 arg1, ReturnType*& _node) const 1920 { 1921 _node = NEW(NodeType(arg1)); 1922 if (_node == NULL) 1923 return fDemangler->_SetError(ERROR_NO_MEMORY); 1924 1925 fDemangler->_AddAllocatedNode(_node); 1926 return true; 1927 } 1928 1929 template<typename ParameterType1, typename ParameterType2, 1930 typename ReturnType> 1931 inline bool operator()(ParameterType1 arg1, ParameterType2 arg2, 1932 ReturnType*& _node) const 1933 { 1934 _node = NEW(NodeType(arg1, arg2)); 1935 if (_node == NULL) 1936 return fDemangler->_SetError(ERROR_NO_MEMORY); 1937 1938 fDemangler->_AddAllocatedNode(_node); 1939 return true; 1940 } 1941 1942 template<typename ParameterType1, typename ParameterType2, 1943 typename ParameterType3, typename ReturnType> 1944 inline bool operator()(ParameterType1 arg1, ParameterType2 arg2, 1945 ParameterType3 arg3, ReturnType*& _node) const 1946 { 1947 _node = NEW(NodeType(arg1, arg2, arg3)); 1948 if (_node == NULL) 1949 return fDemangler->_SetError(ERROR_NO_MEMORY); 1950 1951 fDemangler->_AddAllocatedNode(_node); 1952 return true; 1953 } 1954 1955 private: 1956 Demangler* fDemangler; 1957 }; 1958 1959 1960 inline bool 1961 Demangler::_SetError(int error) 1962 { 1963 if (fError == ERROR_OK) { 1964 fError = error; 1965 #ifdef TRACE_GCC3_DEMANGLER 1966 DebugScope::Print("_SetError(): %d, remaining input: \"%s\"\n", 1967 error, fInput.String()); 1968 #endif 1969 } 1970 return false; 1971 } 1972 1973 1974 inline void 1975 Demangler::_AddAllocatedNode(Node* node) 1976 { 1977 node->SetNextAllocated(fAllocatedNodes); 1978 fAllocatedNodes = node; 1979 } 1980 1981 1982 inline bool 1983 Demangler::_SkipExpected(char c) 1984 { 1985 return fInput.SkipPrefix(c) || _SetError(ERROR_INVALID); 1986 } 1987 1988 1989 inline bool 1990 Demangler::_SkipExpected(const char* string) 1991 { 1992 return fInput.SkipPrefix(string) || _SetError(ERROR_INVALID); 1993 } 1994 1995 1996 Demangler::Demangler() 1997 : 1998 fInput(), 1999 fAllocatedNodes(NULL) 2000 { 2001 } 2002 2003 2004 int 2005 Demangler::Demangle(const char* mangledName, char* buffer, size_t size, 2006 DemanglingInfo& demanglingInfo) 2007 { 2008 DEBUG_SCOPE("Demangle"); 2009 2010 _Init(); 2011 2012 int result = _Demangle(mangledName, buffer, size, demanglingInfo); 2013 2014 _Cleanup(); 2015 2016 return result; 2017 } 2018 2019 2020 int 2021 Demangler::GetParameterInfo(const char* mangledName, uint32 index, char* buffer, 2022 size_t size, ParameterInfo& info) 2023 { 2024 DEBUG_SCOPE("GetParameterInfo"); 2025 2026 _Init(); 2027 2028 int result = _GetParameterInfo(mangledName, index, buffer, size, info); 2029 2030 _Cleanup(); 2031 2032 return result; 2033 } 2034 2035 2036 void 2037 Demangler::_Init() 2038 { 2039 fError = ERROR_OK; 2040 2041 fFirstReferenceableNode = NULL; 2042 fLastReferenceableNode = NULL; 2043 fAllocatedNodes = NULL; 2044 fTemplatizedNode = NULL; 2045 } 2046 2047 2048 void 2049 Demangler::_Cleanup() 2050 { 2051 while (fAllocatedNodes != NULL) { 2052 Node* node = fAllocatedNodes; 2053 fAllocatedNodes = node->NextAllocated(); 2054 DELETE(node); 2055 } 2056 } 2057 2058 2059 int 2060 Demangler::_Demangle(const char* mangledName, char* buffer, size_t size, 2061 DemanglingInfo& demanglingInfo) 2062 { 2063 // parse the name 2064 const char* versionSuffix; 2065 ObjectNode* node; 2066 int error = _Parse(mangledName, versionSuffix, node); 2067 if (error != ERROR_OK) 2068 return error; 2069 2070 NameBuffer nameBuffer(buffer, size); 2071 bool success = node->GetObjectName(nameBuffer, demanglingInfo); 2072 2073 // If versioned, append the unmodified version string 2074 if (success && versionSuffix != NULL) 2075 nameBuffer.Append(versionSuffix); 2076 2077 if (nameBuffer.HadOverflow()) 2078 return ERROR_BUFFER_TOO_SMALL; 2079 2080 if (!success) 2081 return ERROR_INTERNAL; 2082 2083 demanglingInfo.objectType = node->ObjectType(); 2084 2085 nameBuffer.Terminate(); 2086 return ERROR_OK; 2087 } 2088 2089 2090 int 2091 Demangler::_GetParameterInfo(const char* mangledName, uint32 index, 2092 char* buffer, size_t size, ParameterInfo& info) 2093 { 2094 // parse the name 2095 const char* versionSuffix; 2096 ObjectNode* node; 2097 int error = _Parse(mangledName, versionSuffix, node); 2098 if (error != ERROR_OK) 2099 return error; 2100 2101 // get the parameter node 2102 Node* parameter = node->ParameterAt(index); 2103 if (parameter == NULL) 2104 return ERROR_INVALID_PARAMETER_INDEX; 2105 2106 // get the parameter name 2107 NameBuffer nameBuffer(buffer, size); 2108 bool success = parameter->GetName(nameBuffer); 2109 2110 if (nameBuffer.HadOverflow()) 2111 return ERROR_BUFFER_TOO_SMALL; 2112 2113 if (!success) 2114 return ERROR_INTERNAL; 2115 2116 nameBuffer.Terminate(); 2117 2118 // get the type 2119 info.type = parameter->Type(); 2120 2121 return ERROR_OK; 2122 } 2123 2124 2125 int 2126 Demangler::_Parse(const char* mangledName, const char*& versionSuffix, 2127 ObjectNode*& _node) 2128 { 2129 // To support versioned symbols, we ignore the version suffix when 2130 // demangling. 2131 versionSuffix = strchr(mangledName, '@'); 2132 fInput.SetTo(mangledName, 2133 versionSuffix != NULL 2134 ? versionSuffix - mangledName : strlen(mangledName)); 2135 2136 // <mangled-name> ::= _Z <encoding> 2137 2138 if (!fInput.SkipPrefix("_Z")) 2139 return ERROR_NOT_MANGLED; 2140 2141 if (!_ParseEncoding(_node)) 2142 return fError; 2143 2144 if (fInput.CharsRemaining() != 0) { 2145 // bogus at end of input 2146 return ERROR_INVALID; 2147 } 2148 2149 return ERROR_OK; 2150 } 2151 2152 2153 bool 2154 Demangler::_ParseEncoding(ObjectNode*& _node) 2155 { 2156 DEBUG_SCOPE("_ParseEncoding"); 2157 2158 // <encoding> ::= <function name> <bare-function-type> 2159 // ::= <data name> 2160 // ::= <special-name> 2161 2162 // NOTE: This is not in the specs: Local entities seem to be prefixed 2163 // by an 'L'. 2164 fInput.SkipPrefix('L'); 2165 2166 // parse <special-name>, if it is one 2167 Node* name; 2168 if (fInput.HasPrefix('T') || fInput.HasPrefix("GV")) { 2169 return _ParseSpecialName(name) 2170 && NodeCreator<ObjectNode>(this)(name, _node); 2171 } 2172 2173 // either <data name> or <function name> 2174 if (!_ParseName(name)) 2175 return false; 2176 2177 if (fInput.CharsRemaining() == 0 || fInput.HasPrefix('E')) { 2178 // <data name> 2179 return NodeCreator<ObjectNode>(this)(name, _node); 2180 } 2181 2182 // <function name> -- parse remaining <bare-function-type> 2183 FunctionNode* functionNode; 2184 if (!NodeCreator<FunctionNode>(this)(name, false, false, functionNode)) 2185 return false; 2186 _node = functionNode; 2187 2188 // If our name is templatized, we push it onto the templatized node 2189 // stack while parsing the function parameters. 2190 Node* previousTemplatizedNode = fTemplatizedNode; 2191 if (name->IsTemplatized()) 2192 fTemplatizedNode = name; 2193 2194 if (!_ParseBareFunctionType(functionNode)) 2195 return false; 2196 2197 fTemplatizedNode = previousTemplatizedNode; 2198 2199 return true; 2200 } 2201 2202 2203 bool 2204 Demangler::_ParseSpecialName(Node*& _node) 2205 { 2206 DEBUG_SCOPE("_ParseSpecialName"); 2207 2208 if (fInput.CharsRemaining() == 0) 2209 return _SetError(ERROR_INVALID); 2210 2211 // <special-name> ::= GV <object name> # Guard variable for one-time 2212 // # initialization 2213 // # No <type> 2214 if (!fInput.SkipPrefix('T')) { 2215 Node* name; 2216 return _SkipExpected("GV") 2217 && _ParseName(name) 2218 && NodeCreator<SpecialNameNode>(this)("guard variable for ", 2219 name, _node); 2220 } 2221 2222 // <special-name> ::= TV <type> # virtual table 2223 // ::= TT <type> # VTT structure (construction vtable 2224 // # index) 2225 // ::= TI <type> # typeinfo structure 2226 // ::= TS <type> # typeinfo name (null-terminated byte 2227 // # string) 2228 const char* prefix = NULL; 2229 switch (fInput[0]) { 2230 case 'V': 2231 prefix = "vtable for "; 2232 break; 2233 case 'T': 2234 prefix = "VTT for "; 2235 break; 2236 case 'I': 2237 prefix = "typeinfo for "; 2238 break; 2239 case 'S': 2240 prefix = "typeinfo name for "; 2241 break; 2242 } 2243 2244 if (prefix != NULL) { 2245 fInput.Skip(1); 2246 Node* type; 2247 return _ParseType(type) 2248 && NodeCreator<SpecialNameNode>(this)(prefix, type, _node); 2249 } 2250 2251 // <special-name> ::= Tc <call-offset> <call-offset> <base encoding> 2252 // # base is the nominal target function of thunk 2253 // # first call-offset is 'this' adjustment 2254 // # second call-offset is result adjustment 2255 if (fInput.SkipPrefix('c')) { 2256 bool nonVirtual; 2257 number_type offset1; 2258 number_type offset2; 2259 ObjectNode* name; 2260 return _ParseCallOffset(nonVirtual, offset1, offset2) 2261 && _ParseCallOffset(nonVirtual, offset1, offset2) 2262 && _ParseEncoding(name) 2263 && NodeCreator<SpecialNameNode>(this)( 2264 "covariant return thunk to ", name, _node); 2265 } 2266 2267 // <special-name> ::= T <call-offset> <base encoding> 2268 // # base is the nominal target function of thunk 2269 bool nonVirtual; 2270 number_type offset1; 2271 number_type offset2; 2272 ObjectNode* name; 2273 return _ParseCallOffset(nonVirtual, offset1, offset2) 2274 && _ParseEncoding(name) 2275 && NodeCreator<SpecialNameNode>(this)( 2276 nonVirtual ? "non-virtual thunk to " : "virtual thunk to ", 2277 name, _node); 2278 } 2279 2280 2281 bool 2282 Demangler::_ParseCallOffset(bool& nonVirtual, number_type& offset1, 2283 number_type& offset2) 2284 { 2285 // <call-offset> ::= h <nv-offset> _ 2286 // ::= v <v-offset> _ 2287 // <nv-offset> ::= <offset number> 2288 // # non-virtual base override 2289 // <v-offset> ::= <offset number> _ <virtual offset number> 2290 // # virtual base override, with vcall offset 2291 2292 // non-virtual 2293 if (fInput.SkipPrefix('h')) { 2294 nonVirtual = true; 2295 return _ParseNumber(offset1) && _SkipExpected('_'); 2296 } 2297 2298 // virtual 2299 nonVirtual = false; 2300 return _SkipExpected('v') 2301 && _ParseNumber(offset1) 2302 && _SkipExpected('_') 2303 && _ParseNumber(offset2) 2304 && _SkipExpected('_'); 2305 } 2306 2307 bool 2308 Demangler::_ParseName(Node*& _node) 2309 { 2310 DEBUG_SCOPE("_ParseName"); 2311 2312 if (fInput.CharsRemaining() == 0) 2313 return _SetError(ERROR_INVALID); 2314 2315 // <name> ::= <nested-name> 2316 // ::= <unscoped-name> 2317 // ::= <unscoped-template-name> <template-args> 2318 // ::= <local-name> # See Scope Encoding below 2319 // 2320 // <unscoped-name> ::= <unqualified-name> 2321 // ::= St <unqualified-name> # ::std:: 2322 // 2323 // <unscoped-template-name> ::= <unscoped-name> 2324 // ::= <substitution> 2325 2326 switch (fInput[0]) { 2327 case 'N': 2328 // <nested-name> 2329 return _ParseNestedName(_node); 2330 case 'Z': 2331 // <local-name> 2332 return _ParseLocalName(_node); 2333 case 'S': 2334 { 2335 // <substitution> 2336 if (!fInput.HasPrefix("St")) { 2337 if (!_ParseSubstitution(_node)) 2338 return false; 2339 break; 2340 } 2341 2342 // std:: namespace 2343 fInput.Skip(2); 2344 2345 Node* prefix; 2346 if (!NodeCreator<SimpleNameNode>(this)("std", prefix)) 2347 return false; 2348 2349 // <unqualified-name> 2350 Node* node; 2351 if (!_ParseUnqualifiedName(node) 2352 || !NodeCreator<PrefixedNode>(this)(prefix, node, _node)) { 2353 return false; 2354 } 2355 2356 break; 2357 } 2358 default: 2359 // <unqualified-name> 2360 if (!_ParseUnqualifiedName(_node)) 2361 return false; 2362 break; 2363 } 2364 2365 // We get here for the names that might be an <unscoped-template-name>. 2366 // Check whether <template-args> are following. 2367 if (!fInput.HasPrefix('I')) 2368 return true; 2369 2370 // <unscoped-template-name> is referenceable 2371 _RegisterReferenceableNode(_node); 2372 2373 return _ParseTemplateArgs(_node, _node); 2374 } 2375 2376 2377 bool 2378 Demangler::_ParseNestedName(Node*& _node) 2379 { 2380 DEBUG_SCOPE("_ParseNestedName"); 2381 2382 // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E 2383 // ::= N [<CV-qualifiers>] <template-prefix> 2384 // <template-args> E 2385 // 2386 // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const 2387 // 2388 // <prefix> ::= <prefix> <unqualified-name> 2389 // ::= <template-prefix> <template-args> 2390 // ::= <template-param> 2391 // ::= # empty 2392 // ::= <substitution> 2393 // 2394 // <template-prefix> ::= <prefix> <template unqualified-name> 2395 // ::= <template-param> 2396 // ::= <substitution> 2397 2398 if (!_SkipExpected('N')) 2399 return false; 2400 2401 // parse CV qualifiers 2402 int qualifiers; 2403 _ParseCVQualifiers(qualifiers); 2404 2405 // parse the main part 2406 if (!_ParseNestedNameInternal(_node)) 2407 return false; 2408 2409 // create a CV qualifiers wrapper node, if necessary 2410 if (qualifiers != 0) { 2411 return NodeCreator<CVQualifiersNode>(this)(qualifiers, _node, 2412 _node); 2413 } 2414 2415 return true; 2416 } 2417 2418 2419 bool 2420 Demangler::_ParseNestedNameInternal(Node*& _node) 2421 { 2422 DEBUG_SCOPE("_ParseNestedNameMain"); 2423 2424 if (fInput.CharsRemaining() == 0) 2425 return _SetError(ERROR_INVALID); 2426 2427 // the initial prefix might be a template param or a substitution 2428 Node* initialPrefixNode = NULL; 2429 Node* prefixNode = NULL; 2430 switch (fInput[0]) { 2431 case 'T': // <template-param> 2432 if (!_ParseTemplateParam(initialPrefixNode)) 2433 return false; 2434 2435 // a <prefix> or <template-prefix> and as such referenceable 2436 _RegisterReferenceableNode(initialPrefixNode); 2437 break; 2438 2439 case 'S': // <substitution> 2440 if (!_ParseSubstitution(initialPrefixNode)) 2441 return false; 2442 break; 2443 } 2444 2445 while (true) { 2446 bool canTerminate = false; 2447 Node* node; 2448 2449 if (initialPrefixNode != NULL) { 2450 node = initialPrefixNode; 2451 initialPrefixNode = NULL; 2452 } else { 2453 if (!_ParseUnqualifiedName(node)) 2454 return false; 2455 canTerminate = true; 2456 } 2457 2458 // join prefix and the new node 2459 if (prefixNode != NULL) { 2460 if (!NodeCreator<PrefixedNode>(this)(prefixNode, node, node)) 2461 return false; 2462 } 2463 2464 // template arguments? 2465 if (fInput.HasPrefix('I')) { 2466 // <template-prefix> is referenceable 2467 _RegisterReferenceableNode(node); 2468 2469 // parse the template arguments 2470 if (!_ParseTemplateArgs(node, node)) 2471 return false; 2472 canTerminate = true; 2473 } 2474 2475 if (fInput.CharsRemaining() == 0) 2476 return _SetError(ERROR_INVALID); 2477 2478 // end of nested name? 2479 if (fInput.SkipPrefix('E')) { 2480 // If it doesn't have template args, it must end in an 2481 // unqualified name. 2482 if (!canTerminate) 2483 return _SetError(ERROR_INVALID); 2484 2485 _node = node; 2486 return true; 2487 } 2488 2489 // The fun continues, so this is a <prefix> or <template-prefix> 2490 // and as such referenceable. 2491 prefixNode = node; 2492 _RegisterReferenceableNode(node); 2493 } 2494 } 2495 2496 2497 bool 2498 Demangler::_ParseLocalName(Node*& _node) 2499 { 2500 DEBUG_SCOPE("_ParseLocalName"); 2501 2502 // <local-name> := Z <function encoding> E <entity name> 2503 // [<discriminator>] 2504 // := Z <function encoding> E s [<discriminator>] 2505 // <discriminator> := _ <non-negative number> 2506 2507 // parse the function name 2508 ObjectNode* functionName; 2509 if (!_SkipExpected('Z') 2510 || !_ParseEncoding(functionName) 2511 || !_SkipExpected('E')) { 2512 return false; 2513 } 2514 2515 Node* entityName; 2516 if (fInput.SkipPrefix('s')) { 2517 // string literal 2518 if (!NodeCreator<SimpleNameNode>(this)("string literal", 2519 entityName)) { 2520 return false; 2521 } 2522 } else { 2523 // local type or object 2524 if (!_ParseName(entityName)) 2525 return false; 2526 } 2527 2528 // parse discriminator 2529 number_type discriminator = 0; 2530 if (fInput.SkipPrefix('_')) { 2531 if (!_ParseNumber(discriminator)) 2532 return false; 2533 if (discriminator < 0) 2534 return _SetError(ERROR_INVALID); 2535 discriminator++; 2536 } 2537 2538 return NodeCreator<PrefixedNode>(this)(functionName, entityName, _node); 2539 } 2540 2541 2542 bool 2543 Demangler::_ParseUnqualifiedName(Node*& _node) 2544 { 2545 DEBUG_SCOPE("_ParseUnqualifiedName"); 2546 2547 // <unqualified-name> ::= <operator-name> 2548 // ::= <ctor-dtor-name> 2549 // ::= <source-name> 2550 // 2551 // <source-name> ::= <positive length number> <identifier> 2552 // <number> ::= [n] <non-negative decimal integer> 2553 // <identifier> ::= <unqualified source code identifier> 2554 // 2555 // <ctor-dtor-name> ::= C1 # complete object constructor 2556 // ::= C2 # base object constructor 2557 // ::= C3 # complete object allocating constructor 2558 // ::= D0 # deleting destructor 2559 // ::= D1 # complete object destructor 2560 // ::= D2 # base object destructor 2561 2562 // we need at least 2 chars 2563 if (fInput.CharsRemaining() < 2) 2564 return _SetError(ERROR_INVALID); 2565 2566 if (isdigit(fInput[0]) || (fInput[0] == 'n' && isdigit(fInput[1]))) { 2567 // <source-name> 2568 return _ParseSourceName(_node); 2569 } 2570 2571 if (fInput[0] == 'C') { 2572 // <ctor-dtor-name> -- constructors 2573 switch (fInput[1]) { 2574 case '1': 2575 case '2': 2576 case '3': 2577 if (!NodeCreator<XtructorNode>(this)(true, fInput[1] - '1', 2578 _node)) { 2579 return false; 2580 } 2581 2582 fInput.Skip(2); 2583 return true; 2584 default: 2585 return _SetError(ERROR_INVALID); 2586 } 2587 } 2588 2589 if (fInput[0] == 'D') { 2590 // <ctor-dtor-name> -- destructors 2591 switch (fInput[1]) { 2592 case '0': 2593 case '1': 2594 case '2': 2595 if (!NodeCreator<XtructorNode>(this)(false, fInput[1] - '0', 2596 _node)) { 2597 return false; 2598 } 2599 2600 fInput.Skip(2); 2601 return true; 2602 default: 2603 return _SetError(ERROR_INVALID); 2604 } 2605 } 2606 2607 // must be an <operator-name> 2608 return _ParseOperatorName(_node); 2609 } 2610 2611 2612 bool 2613 Demangler::_ParseSourceName(Node*& _node) 2614 { 2615 DEBUG_SCOPE("_ParseSourceName"); 2616 2617 if (fInput.CharsRemaining() == 0) 2618 return _SetError(ERROR_INVALID); 2619 2620 number_type number; 2621 if (!_ParseNumber(number)) 2622 return false; 2623 2624 if (number <= 0 || number > fInput.CharsRemaining()) 2625 return _SetError(ERROR_INVALID); 2626 2627 return _CreateNodeAndSkip(fInput.String(), number, number, _node); 2628 } 2629 2630 2631 bool 2632 Demangler::_ParseOperatorName(Node*& _node) 2633 { 2634 DEBUG_SCOPE("_ParseOperatorName"); 2635 2636 if (fInput.CharsRemaining() < 2) 2637 return _SetError(ERROR_INVALID); 2638 2639 const operator_info* info = NULL; 2640 for (int i = 0; kOperatorInfos[i].name != NULL; i++) { 2641 if (fInput.SkipPrefix(kOperatorInfos[i].mangled_name)) { 2642 info = &kOperatorInfos[i]; 2643 break; 2644 } 2645 } 2646 2647 if (info != NULL) 2648 return NodeCreator<OperatorNode>(this)(info, _node); 2649 2650 // <operator-name> ::= cv <type> # (cast) 2651 if (fInput.SkipPrefix("cv")) { 2652 Node* typeNode; 2653 if (!_ParseType(typeNode)) 2654 return false; 2655 2656 return NodeCreator<CastOperatorNode>(this)(typeNode, _node); 2657 } 2658 2659 // <operator-name> ::= v <digit> <source-name> # vendor extended 2660 // operator 2661 if (fInput.SkipPrefix('v')) { 2662 if (fInput.CharsRemaining() == 0 || !isdigit(fInput[0])) 2663 return _SetError(ERROR_INVALID); 2664 fInput.Skip(1); 2665 2666 Node* name; 2667 return _ParseSourceName(name) 2668 && NodeCreator<VendorOperatorNode>(this)(name, _node); 2669 } 2670 2671 return _SetError(ERROR_INVALID); 2672 } 2673 2674 2675 bool 2676 Demangler::_ParseType(Node*& _node) 2677 { 2678 DEBUG_SCOPE("_ParseType"); 2679 2680 if (!_ParseTypeInternal(_node)) 2681 return false; 2682 2683 _RegisterReferenceableNode(_node); 2684 return true; 2685 } 2686 2687 2688 bool 2689 Demangler::_ParseTypeInternal(Node*& _node) 2690 { 2691 DEBUG_SCOPE("_ParseTypeInternal"); 2692 2693 // <type> ::= <builtin-type> 2694 // ::= <function-type> 2695 // ::= <class-enum-type> 2696 // ::= <array-type> 2697 // ::= <pointer-to-member-type> 2698 // ::= <template-param> 2699 // ::= <template-template-param> <template-args> 2700 // ::= <substitution> # See Compression below 2701 // 2702 // <template-template-param> ::= <template-param> 2703 // ::= <substitution> 2704 // 2705 // <type> ::= <CV-qualifiers> <type> 2706 // ::= P <type> # pointer-to 2707 // ::= R <type> # reference-to 2708 // ::= O <type> # rvalue reference-to (C++0x) 2709 // ::= C <type> # complex pair (C 2000) 2710 // ::= G <type> # imaginary (C 2000) 2711 // ::= U <source-name> <type> # vendor extended type qualifier 2712 // 2713 // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const 2714 // 2715 // <type> ::= Dp <type> # pack expansion of (C++0x) 2716 // ::= Dt <expression> E # decltype of an id-expression or 2717 // # class member access (C++0x) 2718 // ::= DT <expression> E # decltype of an expression (C++0x) 2719 2720 if (_TryParseBuiltinType(_node)) { 2721 _node->SetReferenceable(false); 2722 return true; 2723 } 2724 if (fError != ERROR_OK) 2725 return false; 2726 2727 if (fInput.CharsRemaining() == 0) 2728 return _SetError(ERROR_INVALID); 2729 2730 switch (fInput[0]) { 2731 // function type 2732 case 'F': 2733 { 2734 FunctionNode* functionNode; 2735 if (!_ParseFunctionType(functionNode)) 2736 return false; 2737 _node = functionNode; 2738 return true; 2739 } 2740 2741 // array type 2742 case 'A': 2743 return _ParseArrayType(_node); 2744 2745 // pointer to member type 2746 case 'M': 2747 return _ParsePointerToMemberType(_node); 2748 2749 // template param 2750 case 'T': 2751 if (!_ParseTemplateParam(_node)) 2752 return false; 2753 break; 2754 2755 // CV qualifiers 2756 case 'r': 2757 case 'V': 2758 case 'K': 2759 { 2760 // parse CV qualifiers 2761 int qualifiers; 2762 _ParseCVQualifiers(qualifiers); 2763 2764 // parse the type 2765 if (!_ParseType(_node)) 2766 return false; 2767 2768 // create the wrapper node 2769 return NodeCreator<CVQualifiersNode>(this)(qualifiers, _node, 2770 _node); 2771 } 2772 2773 // pointer, reference, etc. 2774 case 'P': 2775 return _ParseTypeWithModifier(TYPE_QUALIFIER_POINTER, 1, _node); 2776 case 'R': 2777 return _ParseTypeWithModifier(TYPE_QUALIFIER_REFERENCE, 1, 2778 _node); 2779 case 'O': 2780 return _ParseTypeWithModifier( 2781 TYPE_QUALIFIER_RVALUE_REFERENCE, 1, _node); 2782 case 'C': 2783 return _ParseTypeWithModifier(TYPE_QUALIFIER_COMPLEX, 1, _node); 2784 case 'G': 2785 return _ParseTypeWithModifier(TYPE_QUALIFIER_IMAGINARY, 1, 2786 _node); 2787 2788 // pack and decltype 2789 case 'D': 2790 #if 0 2791 if (fInput.CharsRemaining() < 2) 2792 return _SetError(ERROR_INVALID); 2793 2794 switch(fInput[1]) { 2795 case 'p': 2796 fInput.Skip(2); 2797 return _ParseType(_node); 2798 case 't': 2799 case 'T': 2800 { 2801 fInput.Skip(2); 2802 Node* nameNode; 2803 if (!_ParseExpression(nameNode)) 2804 return false; 2805 if (!fInput.SkipPrefix('E')) 2806 return ERROR_INVALID; 2807 } 2808 } 2809 #endif 2810 // NOTE: Unsupported by the GNU demangler. 2811 return _SetError(ERROR_UNSUPPORTED); 2812 2813 // vendor extended type qualifier 2814 case 'U': 2815 fInput.Skip(1); 2816 Node* name; 2817 Node* type; 2818 return _ParseSourceName(name) && _ParseType(type) 2819 && NodeCreator<VendorTypeModifierNode>(this)(name, type, 2820 _node); 2821 2822 // substitution 2823 case 'S': 2824 if (!fInput.HasPrefix("St")) { 2825 if (!_ParseSubstitution(_node)) 2826 return false; 2827 break; 2828 } 2829 2830 // "St" -- the "std" namespace. The grammar is ambiguous here, 2831 // since we could parse that as <substitution> or as 2832 // <class-enum-type>. We assume the latter and fall through. 2833 2834 default: 2835 { 2836 // <class-enum-type> ::= <name> 2837 Node* nameNode; 2838 return _ParseName(nameNode) 2839 && NodeCreator<NamedTypeNode>(this)(nameNode, _node); 2840 } 2841 } 2842 2843 // We get here for the types that might be a <template-template-param>. 2844 // Check whether <template-args> are following. 2845 if (!fInput.HasPrefix('I')) 2846 return true; 2847 2848 // <template-template-param> is referenceable 2849 _RegisterReferenceableNode(_node); 2850 2851 return _ParseTemplateArgs(_node, _node); 2852 } 2853 2854 2855 void 2856 Demangler::_ParseCVQualifiers(int& qualifiers) 2857 { 2858 qualifiers = 0; 2859 2860 if (fInput.SkipPrefix('r')) 2861 qualifiers |= CV_QUALIFIER_RESTRICT; 2862 if (fInput.SkipPrefix('V')) 2863 qualifiers |= CV_QUALIFIER_VOLATILE; 2864 if (fInput.SkipPrefix('K')) 2865 qualifiers |= CV_QUALIFIER_CONST; 2866 } 2867 2868 2869 bool 2870 Demangler::_ParseTypeWithModifier(type_modifier modifier, int toSkip, 2871 Node*& _node) 2872 { 2873 if (toSkip > 0) 2874 fInput.Skip(toSkip); 2875 2876 Node* node; 2877 if (!_ParseType(node)) 2878 return false; 2879 2880 return NodeCreator<TypeModifierNode>(this)(modifier, node, _node); 2881 } 2882 2883 2884 bool 2885 Demangler::_TryParseBuiltinType(Node*& _node) 2886 { 2887 DEBUG_SCOPE("_TryParseBuiltinType"); 2888 2889 // <builtin-type> ::= v # void 2890 // ::= w # wchar_t 2891 // ::= b # bool 2892 // ::= c # char 2893 // ::= a # signed char 2894 // ::= h # unsigned char 2895 // ::= s # short 2896 // ::= t # unsigned short 2897 // ::= i # int 2898 // ::= j # unsigned int 2899 // ::= l # long 2900 // ::= m # unsigned long 2901 // ::= x # long long, __int64 2902 // ::= y # unsigned long long, __int64 2903 // ::= n # __int128 2904 // ::= o # unsigned __int128 2905 // ::= f # float 2906 // ::= d # double 2907 // ::= e # long double, __float80 2908 // ::= g # __float128 2909 // ::= z # ellipsis 2910 // ::= Dd # IEEE 754r decimal floating point (64 bits) 2911 // ::= De # IEEE 754r decimal floating point (128 bits) 2912 // ::= Df # IEEE 754r decimal floating point (32 bits) 2913 // ::= Dh # IEEE 754r half-precision floating point 2914 // # (16 bits) 2915 // ::= Di # char32_t 2916 // ::= Ds # char16_t 2917 // ::= u <source-name> # vendor extended type 2918 2919 if (fInput.CharsRemaining() == 0) 2920 return false; 2921 2922 switch (fInput[0]) { 2923 case 'v': 2924 return _CreateTypeNodeAndSkip(TYPE_VOID, 1, _node); 2925 case 'w': 2926 return _CreateTypeNodeAndSkip(TYPE_WCHAR_T, 1, _node); 2927 case 'b': 2928 return _CreateTypeNodeAndSkip(TYPE_BOOL, 1, _node); 2929 case 'c': 2930 return _CreateTypeNodeAndSkip(TYPE_CHAR, 1, _node); 2931 case 'a': 2932 return _CreateTypeNodeAndSkip(TYPE_SIGNED_CHAR, 1, _node); 2933 case 'h': 2934 return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_CHAR, 1, _node); 2935 case 's': 2936 return _CreateTypeNodeAndSkip(TYPE_SHORT, 1, _node); 2937 case 't': 2938 return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_SHORT, 1, 2939 _node); 2940 case 'i': 2941 return _CreateTypeNodeAndSkip(TYPE_INT, 1, _node); 2942 case 'j': 2943 return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_INT, 1, _node); 2944 case 'l': 2945 return _CreateTypeNodeAndSkip(TYPE_LONG, 1, _node); 2946 case 'm': 2947 return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_LONG, 1, _node); 2948 case 'x': 2949 return _CreateTypeNodeAndSkip(TYPE_LONG_LONG, 1, _node); 2950 case 'y': 2951 return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_LONG_LONG, 1, _node); 2952 case 'n': 2953 return _CreateTypeNodeAndSkip(TYPE_INT128, 1, _node); 2954 case 'o': 2955 return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_INT128, 1, _node); 2956 case 'f': 2957 return _CreateTypeNodeAndSkip(TYPE_FLOAT, 1, _node); 2958 case 'd': 2959 return _CreateTypeNodeAndSkip(TYPE_DOUBLE, 1, _node); 2960 case 'e': 2961 return _CreateTypeNodeAndSkip(TYPE_LONG_DOUBLE, 1, _node); 2962 case 'g': 2963 return _CreateTypeNodeAndSkip(TYPE_FLOAT128, 1, _node); 2964 case 'z': 2965 return _CreateTypeNodeAndSkip(TYPE_ELLIPSIS, 1, _node); 2966 2967 case 'D': 2968 if (fInput.CharsRemaining() < 2) 2969 return false; 2970 2971 // TODO: Official names for the __dfloat*! 2972 switch (fInput[1]) { 2973 case 'd': 2974 return _CreateTypeNodeAndSkip(TYPE_DFLOAT64, 2, _node); 2975 case 'e': 2976 return _CreateTypeNodeAndSkip(TYPE_DFLOAT128, 2, _node); 2977 case 'f': 2978 return _CreateTypeNodeAndSkip(TYPE_DFLOAT32, 2, _node); 2979 case 'h': 2980 return _CreateTypeNodeAndSkip(TYPE_DFLOAT16, 2, _node); 2981 case 'i': 2982 return _CreateTypeNodeAndSkip(TYPE_CHAR16_T, 2, _node); 2983 case 's': 2984 return _CreateTypeNodeAndSkip(TYPE_CHAR32_T, 2, _node); 2985 default: 2986 return false; 2987 } 2988 2989 case 'u': 2990 { 2991 fInput.Skip(1); 2992 Node* nameNode; 2993 return _ParseSourceName(nameNode) 2994 && NodeCreator<NamedTypeNode>(this)(nameNode, _node); 2995 } 2996 2997 default: 2998 return false; 2999 } 3000 } 3001 3002 3003 bool 3004 Demangler::_ParseFunctionType(FunctionNode*& _node) 3005 { 3006 DEBUG_SCOPE("_ParseFunctionType"); 3007 3008 // <function-type> ::= F [Y] <bare-function-type> E 3009 3010 if (!_SkipExpected('F')) 3011 return false; 3012 3013 // is 'extern "C"'? 3014 bool isExternC = fInput.SkipPrefix('Y'); 3015 3016 // create function and parse function type 3017 if (!NodeCreator<FunctionNode>(this)((Node*)NULL, true, isExternC, 3018 _node) 3019 || !_ParseBareFunctionType(_node)) { 3020 return false; 3021 } 3022 3023 // skip terminating 'E' 3024 return _SkipExpected('E'); 3025 } 3026 3027 3028 bool 3029 Demangler::_ParseArrayType(Node*& _node) 3030 { 3031 DEBUG_SCOPE("_ParseArrayType"); 3032 3033 // <array-type> ::= A <positive dimension number> _ <element type> 3034 // ::= A [<dimension expression>] _ <element type> 3035 3036 if (fInput.CharsRemaining() < 2 || !fInput.SkipPrefix('A')) 3037 return _SetError(ERROR_INVALID); 3038 3039 number_type dimensionNumber; 3040 Node* dimensionExpression = NULL; 3041 3042 // If it looks like a number, it must be the first production, otherwise 3043 // the second one. 3044 if (isdigit(fInput[0]) 3045 || (fInput[0] == 'n' && fInput.CharsRemaining() >= 2 3046 && isdigit(fInput[1]))) { 3047 if (!_ParseNumber(dimensionNumber)) 3048 return false; 3049 } else { 3050 if (!_ParseExpression(dimensionExpression)) 3051 return false; 3052 } 3053 3054 // parse the type 3055 Node* type; 3056 if (!_SkipExpected('_') || !_ParseType(type)) 3057 return false; 3058 3059 // create the array node 3060 return dimensionExpression != NULL 3061 ? NodeCreator<ArrayNode>(this)(type, dimensionExpression, _node) 3062 : NodeCreator<ArrayNode>(this)(type, dimensionNumber, _node); 3063 } 3064 3065 3066 bool 3067 Demangler::_ParsePointerToMemberType(Node*& _node) 3068 { 3069 DEBUG_SCOPE("_ParsePointerToMemberType"); 3070 3071 // <pointer-to-member-type> ::= M <class type> <member type> 3072 Node* classType; 3073 Node* memberType; 3074 return _SkipExpected('M') 3075 && _ParseType(classType) 3076 && _ParseType(memberType) 3077 && NodeCreator<PointerToMemberNode>(this)(classType, memberType, 3078 _node); 3079 } 3080 3081 3082 bool 3083 Demangler::_ParseTemplateParam(Node*& _node) 3084 { 3085 DEBUG_SCOPE("_ParseTemplateParam"); 3086 3087 // <template-param> ::= T_ # first template parameter 3088 // ::= T <parameter-2 non-negative number> _ 3089 3090 if (!_SkipExpected('T')) 3091 return false; 3092 if (fTemplatizedNode == NULL) 3093 return _SetError(ERROR_INVALID); 3094 3095 // get the index; 3096 number_type index = 0; 3097 if (!fInput.HasPrefix('_')) { 3098 if (!_ParseNumber(index)) 3099 return false; 3100 3101 if (index < 0) 3102 return _SetError(ERROR_INVALID); 3103 index++; 3104 } 3105 3106 if (!_SkipExpected('_')) 3107 return false; 3108 3109 // get the parameter 3110 Node* parameter = fTemplatizedNode->TemplateParameterAt(index); 3111 if (parameter == NULL) 3112 return _SetError(ERROR_INVALID); 3113 3114 // create a substitution node 3115 return NodeCreator<SubstitutionNode>(this)(parameter, _node); 3116 } 3117 3118 3119 bool 3120 Demangler::_ParseSubstitution(Node*& _node) 3121 { 3122 DEBUG_SCOPE("_ParseSubstitution"); 3123 3124 if (!_ParseSubstitutionInternal(_node)) 3125 return false; 3126 3127 // substitutions are never referenceable 3128 _node->SetReferenceable(false); 3129 3130 return true; 3131 } 3132 3133 3134 bool 3135 Demangler::_ParseSubstitutionInternal(Node*& _node) 3136 { 3137 DEBUG_SCOPE("_ParseSubstitutionInternal"); 3138 3139 // <substitution> ::= S <seq-id> _ 3140 // ::= S_ 3141 // 3142 // <substitution> ::= St # ::std:: 3143 // <substitution> ::= Sa # ::std::allocator 3144 // <substitution> ::= Sb # ::std::basic_string 3145 // <substitution> ::= Ss # ::std::basic_string < char, 3146 // ::std::char_traits<char>, 3147 // ::std::allocator<char> > 3148 // <substitution> ::= Si # ::std::basic_istream<char, 3149 // std::char_traits<char> > 3150 // <substitution> ::= So # ::std::basic_ostream<char, 3151 // std::char_traits<char> > 3152 // <substitution> ::= Sd # ::std::basic_iostream<char, 3153 // std::char_traits<char> > 3154 3155 if (fInput.CharsRemaining() < 2 || !fInput.SkipPrefix('S')) 3156 return _SetError(ERROR_INVALID); 3157 3158 switch (fInput[0]) { 3159 case 't': 3160 return _CreateNodeAndSkip("std", 1, _node); 3161 case 'a': 3162 return _CreateTypeNodeAndSkip("allocator", "std", NULL, 1, 3163 _node); 3164 case 'b': 3165 return _CreateTypeNodeAndSkip("basic_string", "std", NULL, 1, 3166 _node); 3167 case 's': 3168 return _CreateTypeNodeAndSkip("basic_string", "std", 3169 "char, std::char_traits<char>, std::allocator<char>", 1, 3170 _node); 3171 case 'i': 3172 return _CreateTypeNodeAndSkip("basic_istream", "std", 3173 "char, std::char_traits<char>", 1, _node); 3174 case 'o': 3175 return _CreateTypeNodeAndSkip("basic_ostream", "std", 3176 "char, std::char_traits<char>", 1, _node); 3177 case 'd': 3178 return _CreateTypeNodeAndSkip("basic_iostream", "std", 3179 "char, std::char_traits<char>", 1, _node); 3180 case '_': 3181 fInput.Skip(1); 3182 return _CreateSubstitutionNode(0, _node); 3183 } 3184 3185 // parse <seq-id> 3186 int seqID = 0; 3187 int count = fInput.CharsRemaining(); 3188 int i = 0; 3189 for (; i < count && fInput[i] != '_'; i++) { 3190 char c = fInput[i]; 3191 if (isdigit(c)) 3192 seqID = seqID * 36 + (c - '0'); 3193 else if (c >= 'A' && c <= 'Z') 3194 seqID = seqID * 36 + 10 + (c - 'A'); 3195 else 3196 return _SetError(ERROR_INVALID); 3197 } 3198 3199 if (i == count) 3200 return _SetError(ERROR_INVALID); 3201 3202 // skip digits and '_' 3203 fInput.Skip(i + 1); 3204 3205 return _CreateSubstitutionNode(seqID + 1, _node); 3206 } 3207 3208 3209 bool 3210 Demangler::_ParseBareFunctionType(FunctionNode* node) 3211 { 3212 DEBUG_SCOPE("_ParseBareFunctionType"); 3213 3214 // <bare-function-type> ::= <signature type>+ 3215 // # types are possible return type, then parameter types 3216 3217 if (fInput.CharsRemaining() == 0) 3218 return _SetError(ERROR_INVALID); 3219 3220 do { 3221 Node* typeNode; 3222 if (!_ParseType(typeNode)) 3223 return false; 3224 3225 node->AddType(typeNode); 3226 } while (fInput.CharsRemaining() > 0 && fInput[0] != 'E'); 3227 // 'E' delimits <function-type> 3228 3229 return true; 3230 } 3231 3232 3233 bool 3234 Demangler::_ParseTemplateArgs(Node* node, Node*& _node) 3235 { 3236 DEBUG_SCOPE("_ParseTemplateArgs"); 3237 3238 // <template-args> ::= I <template-arg>+ E 3239 3240 if (!_SkipExpected('I')) 3241 return false; 3242 3243 // we need at least one <template-arg> 3244 if (fInput.CharsRemaining() == 0 || fInput[0] == 'E') 3245 return _SetError(ERROR_INVALID); 3246 3247 // create the node 3248 TemplateNode* templateNode; 3249 if (!NodeCreator<TemplateNode>(this)(node, templateNode)) 3250 return false; 3251 _node = templateNode; 3252 3253 // parse the args 3254 while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') { 3255 Node* arg; 3256 if (!_ParseTemplateArg(arg)) 3257 return false; 3258 templateNode->AddArgument(arg); 3259 } 3260 3261 // skip the trailing 'E' 3262 return _SkipExpected('E'); 3263 } 3264 3265 3266 bool 3267 Demangler::_ParseTemplateArg(Node*& _node) 3268 { 3269 DEBUG_SCOPE("_ParseTemplateArg"); 3270 3271 // <template-arg> ::= <type> # type or template 3272 // ::= X <expression> E # expression 3273 // ::= <expr-primary> # simple expressions 3274 // ::= I <template-arg>* E # argument pack 3275 // ::= sp <expression> # pack expansion of (C++0x) 3276 3277 if (fInput.CharsRemaining() == 0) 3278 return _SetError(ERROR_INVALID); 3279 3280 switch (fInput[0]) { 3281 case 'X': // X <expression> E 3282 fInput.Skip(1); 3283 return _ParseExpression(_node) && _SkipExpected('E'); 3284 3285 case 'L': // <expr-primary> 3286 return _ParseExpressionPrimary(_node); 3287 3288 case 'I': // I <template-arg>* E 3289 { 3290 #if 0 3291 fInput.Skip(1); 3292 3293 while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') { 3294 Node* arg; 3295 if (!_ParseTemplateArg(arg)) 3296 return false; 3297 } 3298 3299 if (!fInput.SkipPrefix('E')) 3300 return _SetError(ERROR_INVALID); 3301 return true; 3302 #endif 3303 // NOTE: Unsupported by the GNU demangler. 3304 return _SetError(ERROR_UNSUPPORTED); 3305 } 3306 3307 case 's': 3308 if (fInput.SkipPrefix("sp")) { 3309 // sp <expression> 3310 #if 0 3311 return _ParseExpression(_node); 3312 #endif 3313 // NOTE: Unsupported by the GNU demangler. 3314 return _SetError(ERROR_UNSUPPORTED); 3315 } 3316 3317 // fall through... 3318 3319 default: // <type> 3320 return _ParseType(_node); 3321 } 3322 } 3323 3324 3325 bool 3326 Demangler::_ParseExpression(Node*& _node) 3327 { 3328 DEBUG_SCOPE("_ParseExpression"); 3329 3330 // <expression> ::= <unary operator-name> <expression> 3331 // ::= <binary operator-name> <expression> <expression> 3332 // ::= <trinary operator-name> <expression> <expression> 3333 // <expression> 3334 // ::= cl <expression>* E # call 3335 // ::= cv <type> expression # conversion with one 3336 // argument 3337 // ::= cv <type> _ <expression>* E # conversion with a 3338 // different number of 3339 // arguments 3340 // ::= st <type> # sizeof (a type) 3341 // ::= at <type> # alignof (a type) 3342 // ::= <template-param> 3343 // ::= <function-param> 3344 // ::= sr <type> <unqualified-name> 3345 // # dependent name 3346 // ::= sr <type> <unqualified-name> <template-args> 3347 // # dependent template-id 3348 // ::= sZ <template-param> 3349 // # size of a parameter pack 3350 // ::= <expr-primary> 3351 // 3352 // <expr-primary> ::= L <type> <value number> E # integer literal 3353 // ::= L <type <value float> E # floating literal 3354 // ::= L <mangled-name> E # external name 3355 3356 if (fInput.CharsRemaining() == 0) 3357 return _SetError(ERROR_INVALID); 3358 3359 switch (fInput[0]) { 3360 case 'L': 3361 return _ParseExpressionPrimary(_node); 3362 case 'T': 3363 return _ParseTemplateParam(_node); 3364 // NOTE: <function-param> is not defined in the specs! 3365 } 3366 3367 // must be an operator 3368 if (fInput.CharsRemaining() < 2) 3369 return _SetError(ERROR_INVALID); 3370 3371 // some operators need special handling 3372 3373 if (fInput.SkipPrefix("cl")) { 3374 // cl <expression>* E # call 3375 CallNode* callNode; 3376 if (!NodeCreator<CallNode>(this)(callNode)) 3377 return false; 3378 3379 while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') { 3380 Node* subExpression; 3381 if (!_ParseExpression(subExpression)) 3382 return false; 3383 callNode->AddSubExpression(subExpression); 3384 } 3385 3386 _node = callNode; 3387 return _SkipExpected('E'); 3388 } 3389 3390 if (fInput.SkipPrefix("cv")) { 3391 // cv <type> expression # conversion with one argument 3392 // cv <type> _ <expression>* E # conversion with a different number 3393 // of arguments 3394 3395 // parse the type 3396 Node* type; 3397 if (!_ParseType(type)) 3398 return false; 3399 3400 // create a conversion expression node 3401 ConversionExpressionNode* expression; 3402 if (!NodeCreator<ConversionExpressionNode>(this)(type, expression)) 3403 return false; 3404 _node = expression; 3405 3406 if (fInput.SkipPrefix('_')) { 3407 // multi argument conversion 3408 while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') { 3409 Node* subExpression; 3410 if (!_ParseExpression(subExpression)) 3411 return false; 3412 expression->AddSubExpression(subExpression); 3413 } 3414 3415 return _SkipExpected('E'); 3416 } 3417 3418 // single argument conversion 3419 Node* subExpression; 3420 if (!_ParseExpression(subExpression)) 3421 return false; 3422 expression->AddSubExpression(subExpression); 3423 3424 return true; 3425 } 3426 3427 if (fInput.SkipPrefix("sr")) { 3428 // sr <type> <unqualified-name> 3429 // sr <type> <unqualified-name> <template-args> 3430 3431 // parse type and unqualified name and create the node 3432 Node* type; 3433 Node* name; 3434 if (!_ParseType(type) || !_ParseUnqualifiedName(name) 3435 || !NodeCreator<DependentNameNode>(this)(type, name, _node)) { 3436 return false; 3437 } 3438 3439 // If there are template arguments left, add them. 3440 if (!fInput.HasPrefix('I')) 3441 return true; 3442 3443 return _ParseTemplateArgs(_node, _node); 3444 } 3445 3446 if (fInput.SkipPrefix("sZ")) { 3447 // sZ <template-param> 3448 3449 // NOTE: Unsupported by the GNU demangler. 3450 return _SetError(ERROR_UNSUPPORTED); 3451 } 3452 3453 // no special operator, so have a look for the others 3454 3455 const operator_info* info = NULL; 3456 for (int i = 0; kOperatorInfos[i].name != NULL; i++) { 3457 if (fInput.SkipPrefix(kOperatorInfos[i].mangled_name)) { 3458 info = &kOperatorInfos[i]; 3459 break; 3460 } 3461 } 3462 3463 // We can only deal with operators with a fixed argument count at this 3464 // point. 3465 if (info == NULL || info->argument_count < 0) 3466 return _SetError(ERROR_INVALID); 3467 3468 // create an operator node 3469 OperatorExpressionNode* operatorNode; 3470 if (!NodeCreator<OperatorExpressionNode>(this)(info, operatorNode)) 3471 return false; 3472 3473 // parse the arguments 3474 int i = 0; 3475 3476 // the first one might be a type 3477 if ((info->flags & OPERATOR_TYPE_PARAM) != 0) { 3478 Node* type; 3479 if (!_ParseType(type)) 3480 return false; 3481 3482 operatorNode->AddSubExpression(type); 3483 i++; 3484 } 3485 3486 // the others are expressions 3487 for (; i < info->argument_count; i++) { 3488 Node* subExpression; 3489 if (!_ParseExpression(subExpression)) 3490 return false; 3491 operatorNode->AddSubExpression(subExpression); 3492 } 3493 3494 _node = operatorNode; 3495 return true; 3496 } 3497 3498 3499 bool 3500 Demangler::_ParseExpressionPrimary(Node*& _node) 3501 { 3502 DEBUG_SCOPE("_ParseExpressionPrimary"); 3503 3504 // <expr-primary> ::= L <type> <value number> E # integer literal 3505 // ::= L <type <value float> E # floating literal 3506 // ::= L <mangled-name> E # external name 3507 3508 if (!_SkipExpected('L')) 3509 return false; 3510 3511 if (fInput.SkipPrefix("_Z")) { 3512 ObjectNode* node; 3513 if (!_ParseEncoding(node)) 3514 return false; 3515 _node = node; 3516 } else { 3517 // number or float literal 3518 Node* type; 3519 if (!_ParseType(type)) 3520 return false; 3521 3522 // GNU's demangler doesn't really seem to parse the integer/float, 3523 // but only replaces a leading 'n' by '-'. Good enough for us, too. 3524 3525 // determine the length 3526 int maxLength = fInput.CharsRemaining(); 3527 int length = 0; 3528 while (length < maxLength && fInput[length] != 'E') 3529 length++; 3530 3531 if (length == 0) 3532 return _SetError(ERROR_INVALID); 3533 3534 if (!NodeCreator<TypedNumberLiteralNode>(this)(type, 3535 fInput.String(), length, _node)) { 3536 return false; 3537 } 3538 3539 fInput.Skip(length); 3540 } 3541 3542 return _SkipExpected('E'); 3543 } 3544 3545 3546 bool 3547 Demangler::_ParseNumber(number_type& number) 3548 { 3549 DEBUG_SCOPE("_ParseNumber"); 3550 3551 bool negative = fInput.SkipPrefix('n'); 3552 3553 if (fInput.CharsRemaining() == 0) 3554 return _SetError(ERROR_INVALID); 3555 3556 number = 0; 3557 int count = fInput.CharsRemaining(); 3558 int i = 0; 3559 for (; i < count && isdigit(fInput[i]); i++) 3560 number = number * 10 + (fInput[i] - '0'); 3561 3562 fInput.Skip(i); 3563 3564 if (negative) 3565 number =-number; 3566 return true; 3567 } 3568 3569 3570 bool 3571 Demangler::_CreateNodeAndSkip(const char* name, size_t length, int toSkip, 3572 Node*& _node) 3573 { 3574 if (toSkip > 0) 3575 fInput.Skip(toSkip); 3576 3577 return NodeCreator<SimpleNameNode>(this)(name, length, _node); 3578 } 3579 3580 3581 bool 3582 Demangler::_CreateNodeAndSkip(const char* name, int toSkip, Node*& _node) 3583 { 3584 return _CreateNodeAndSkip(name, strlen(name), toSkip, _node); 3585 } 3586 3587 3588 bool 3589 Demangler::_CreateTypeNodeAndSkip(type_type type, int toSkip, Node*& _node) 3590 { 3591 if (toSkip > 0) 3592 fInput.Skip(toSkip); 3593 3594 return NodeCreator<SimpleTypeNode>(this)(type, _node); 3595 } 3596 3597 3598 bool 3599 Demangler::_CreateTypeNodeAndSkip(const char* name, const char* prefix, 3600 const char* templateArgs, int toSkip, Node*& _node) 3601 { 3602 if (toSkip > 0) 3603 fInput.Skip(toSkip); 3604 3605 // create the name node 3606 if (!NodeCreator<SimpleTypeNode>(this)(name, _node)) 3607 return false; 3608 3609 // add the prefix 3610 if (prefix != NULL) { 3611 Node* prefixNode; 3612 if (!NodeCreator<SimpleTypeNode>(this)(prefix, prefixNode) 3613 || !NodeCreator<PrefixedNode>(this)(prefixNode, _node, _node)) { 3614 return false; 3615 } 3616 } 3617 3618 // wrap the node to add the template args 3619 if (templateArgs != NULL) { 3620 TemplateNode* templateNode; 3621 Node* argsNode; 3622 if (!NodeCreator<TemplateNode>(this)(_node, templateNode) 3623 || !NodeCreator<SimpleTypeNode>(this)(templateArgs, argsNode)) { 3624 return false; 3625 } 3626 templateNode->AddArgument(argsNode); 3627 _node = templateNode; 3628 } 3629 3630 return true; 3631 } 3632 3633 3634 void 3635 Demangler::_RegisterReferenceableNode(Node* node) 3636 { 3637 // check, if not referenceable or already registered 3638 if (!node->IsReferenceable() || node == fLastReferenceableNode 3639 || node->NextReferenceable() != NULL) { 3640 return; 3641 } 3642 3643 if (fFirstReferenceableNode == NULL) { 3644 fFirstReferenceableNode = node; 3645 fLastReferenceableNode = node; 3646 } else { 3647 fLastReferenceableNode->SetNextReferenceable(node); 3648 fLastReferenceableNode = node; 3649 } 3650 } 3651 3652 3653 bool 3654 Demangler::_CreateSubstitutionNode(int index, Node*& _node) 3655 { 3656 Node* node = fFirstReferenceableNode; 3657 while (node != NULL && index > 0) { 3658 node = node->NextReferenceable(); 3659 index--; 3660 } 3661 3662 if (node == NULL) 3663 return _SetError(ERROR_INVALID); 3664 3665 // create a substitution node 3666 return NodeCreator<SubstitutionNode>(this)(node, _node); 3667 } 3668 3669 3670 // #pragma mark - 3671 3672 3673 const char* 3674 demangle_symbol_gcc3(const char* mangledName, char* buffer, size_t bufferSize, 3675 bool* _isObjectMethod) 3676 { 3677 bool isObjectMethod; 3678 if (_isObjectMethod == NULL) 3679 _isObjectMethod = &isObjectMethod; 3680 3681 Demangler demangler; 3682 DemanglingInfo info(true); 3683 if (demangler.Demangle(mangledName, buffer, bufferSize, info) != ERROR_OK) 3684 return NULL; 3685 3686 // Set the object method return value. Unless we know for sure that it isn't 3687 // an object method, we assume that it is. 3688 switch (info.objectType) { 3689 case OBJECT_TYPE_DATA: 3690 case OBJECT_TYPE_FUNCTION: 3691 case OBJECT_TYPE_METHOD_CLASS: 3692 *_isObjectMethod = false; 3693 break; 3694 case OBJECT_TYPE_METHOD_OBJECT: 3695 *_isObjectMethod = true; 3696 break; 3697 case OBJECT_TYPE_UNKNOWN: 3698 case OBJECT_TYPE_METHOD_UNKNOWN: 3699 *_isObjectMethod = strstr(buffer, "::") != NULL; 3700 break; 3701 } 3702 3703 return buffer; 3704 } 3705 3706 3707 status_t 3708 get_next_argument_gcc3(uint32* _cookie, const char* mangledName, char* name, 3709 size_t nameSize, int32* _type, size_t* _argumentLength) 3710 { 3711 Demangler demangler; 3712 ParameterInfo info; 3713 int result = demangler.GetParameterInfo(mangledName, *_cookie, name, 3714 nameSize, info); 3715 if (result != ERROR_OK) { 3716 switch (result) { 3717 case ERROR_NOT_MANGLED: 3718 return B_BAD_VALUE; 3719 case ERROR_UNSUPPORTED: 3720 return B_BAD_VALUE; 3721 case ERROR_INVALID: 3722 return B_BAD_VALUE; 3723 case ERROR_BUFFER_TOO_SMALL: 3724 return B_BUFFER_OVERFLOW; 3725 case ERROR_NO_MEMORY: 3726 return B_NO_MEMORY; 3727 case ERROR_INTERNAL: 3728 default: 3729 return B_ERROR; 3730 } 3731 } 3732 3733 // translate the type 3734 switch (info.type.type) { 3735 case TYPE_BOOL: 3736 *_type = B_BOOL_TYPE; 3737 *_argumentLength = 1; 3738 break; 3739 3740 case TYPE_CHAR: 3741 *_type = B_CHAR_TYPE; 3742 *_argumentLength = 1; 3743 break; 3744 3745 case TYPE_SIGNED_CHAR: 3746 *_type = B_INT8_TYPE; 3747 *_argumentLength = 1; 3748 break; 3749 case TYPE_UNSIGNED_CHAR: 3750 *_type = B_UINT8_TYPE; 3751 *_argumentLength = 1; 3752 break; 3753 3754 case TYPE_SHORT: 3755 *_type = B_INT16_TYPE; 3756 *_argumentLength = 2; 3757 break; 3758 case TYPE_UNSIGNED_SHORT: 3759 *_type = B_UINT16_TYPE; 3760 *_argumentLength = 2; 3761 break; 3762 3763 case TYPE_INT: 3764 *_type = B_INT32_TYPE; 3765 *_argumentLength = 4; 3766 break; 3767 case TYPE_UNSIGNED_INT: 3768 *_type = B_UINT32_TYPE; 3769 *_argumentLength = 4; 3770 break; 3771 3772 case TYPE_LONG: 3773 *_type = sizeof(long) == 4 ? B_INT32_TYPE : B_INT64_TYPE; 3774 *_argumentLength = sizeof(long); 3775 break; 3776 case TYPE_UNSIGNED_LONG: 3777 *_type = sizeof(long) == 4 ? B_UINT32_TYPE : B_UINT64_TYPE; 3778 *_argumentLength = sizeof(long); 3779 break; 3780 3781 case TYPE_LONG_LONG: 3782 *_type = B_INT64_TYPE; 3783 *_argumentLength = 8; 3784 break; 3785 case TYPE_UNSIGNED_LONG_LONG: 3786 *_type = B_INT64_TYPE; 3787 *_argumentLength = 8; 3788 break; 3789 3790 case TYPE_INT128: 3791 *_type = 0; 3792 *_argumentLength = 16; 3793 break; 3794 case TYPE_UNSIGNED_INT128: 3795 *_type = 0; 3796 *_argumentLength = 16; 3797 break; 3798 3799 case TYPE_FLOAT: 3800 *_type = B_FLOAT_TYPE; 3801 *_argumentLength = sizeof(float); 3802 break; 3803 case TYPE_DOUBLE: 3804 *_type = B_DOUBLE_TYPE; 3805 *_argumentLength = sizeof(double); 3806 break; 3807 3808 case TYPE_LONG_DOUBLE: 3809 *_type = 0; 3810 *_argumentLength = sizeof(long double); 3811 break; 3812 3813 case TYPE_FLOAT128: 3814 *_type = 0; 3815 *_argumentLength = 16; 3816 break; 3817 3818 case TYPE_DFLOAT16: 3819 *_argumentLength = 2; 3820 case TYPE_DFLOAT32: 3821 *_argumentLength *= 2; 3822 case TYPE_DFLOAT64: 3823 *_argumentLength *= 2; 3824 case TYPE_DFLOAT128: 3825 *_argumentLength *= 2; 3826 *_type = 0; 3827 break; 3828 3829 case TYPE_CHAR16_T: 3830 *_type = B_UINT16_TYPE; 3831 *_argumentLength = 2; 3832 break; 3833 3834 case TYPE_CHAR32_T: 3835 *_type = B_UINT32_TYPE; 3836 *_argumentLength = 2; 3837 break; 3838 3839 case TYPE_CONST_CHAR_POINTER: 3840 *_type = B_STRING_TYPE; 3841 *_argumentLength = sizeof(void*); 3842 break; 3843 3844 case TYPE_POINTER: 3845 *_type = B_POINTER_TYPE; 3846 *_argumentLength = sizeof(void*); 3847 break; 3848 3849 case TYPE_REFERENCE: 3850 *_type = B_REF_TYPE; 3851 // TODO: That's actually entry_ref! 3852 *_argumentLength = sizeof(void*); 3853 break; 3854 3855 case TYPE_WCHAR_T: 3856 // TODO: Type/size might change! 3857 *_type = B_UINT16_TYPE; 3858 *_argumentLength = 2; 3859 break; 3860 3861 case TYPE_UNKNOWN: 3862 case TYPE_ELLIPSIS: 3863 case TYPE_VOID: 3864 default: 3865 // Well, tell our caller *something*. 3866 *_type = 0; 3867 *_argumentLength = sizeof(int); 3868 } 3869 3870 // assume sizeof(int) argument alignment 3871 if (*_argumentLength < sizeof(int)) 3872 *_argumentLength = sizeof(int); 3873 3874 ++*_cookie; 3875 return B_OK; 3876 } 3877 3878 3879 #ifndef _KERNEL_MODE 3880 3881 const char* 3882 demangle_name_gcc3(const char* mangledName, char* buffer, size_t bufferSize) 3883 { 3884 3885 Demangler demangler; 3886 DemanglingInfo info(false); 3887 if (demangler.Demangle(mangledName, buffer, bufferSize, info) != ERROR_OK) 3888 return NULL; 3889 return buffer; 3890 } 3891 3892 #endif 3893