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