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