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, Node* 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 1318 buffer.Append(" [clone "); 1319 if (!fCloneNode->GetName(buffer)) 1320 return false; 1321 buffer.Append("]"); 1322 return true; 1323 } 1324 1325 virtual Node* GetUnqualifiedNode(Node* beforeNode) 1326 { 1327 return beforeNode == fCloneNode 1328 ? fNode->GetUnqualifiedNode(beforeNode) 1329 : fCloneNode->GetUnqualifiedNode(beforeNode); 1330 } 1331 1332 virtual bool IsNoReturnValueFunction() const 1333 { 1334 return fNode->IsNoReturnValueFunction(); 1335 } 1336 1337 virtual object_type ObjectType() const 1338 { 1339 return fNode->ObjectType(); 1340 } 1341 1342 virtual prefix_type PrefixType() const 1343 { 1344 return PREFIX_UNKNOWN; 1345 } 1346 1347 private: 1348 Node* fNode; 1349 Node* fCloneNode; 1350 }; 1351 1352 1353 typedef PrefixedNode DependentNameNode; 1354 1355 1356 class TemplateNode : public Node { 1357 public: 1358 TemplateNode(Node* base) 1359 : 1360 fBase(base), 1361 fFirstArgument(NULL), 1362 fLastArgument(NULL) 1363 { 1364 fBase->SetParent(this); 1365 } 1366 1367 void AddArgument(Node* child) 1368 { 1369 child->SetParent(this); 1370 1371 if (fLastArgument != NULL) { 1372 fLastArgument->SetNext(child); 1373 fLastArgument = child; 1374 } else { 1375 fFirstArgument = child; 1376 fLastArgument = child; 1377 } 1378 } 1379 1380 virtual bool GetName(NameBuffer& buffer) const 1381 { 1382 if (!fBase->GetName(buffer)) 1383 return false; 1384 1385 buffer.Append("<"); 1386 1387 Node* child = fFirstArgument; 1388 while (child != NULL) { 1389 if (child != fFirstArgument) 1390 buffer.Append(", "); 1391 1392 if (!child->GetName(buffer)) 1393 return false; 1394 1395 child = child->Next(); 1396 } 1397 1398 // add a space between consecutive '>' 1399 if (buffer.LastChar() == '>') 1400 buffer.Append(" "); 1401 1402 return buffer.Append(">"); 1403 } 1404 1405 virtual Node* GetUnqualifiedNode(Node* beforeNode) 1406 { 1407 return fBase != beforeNode 1408 ? fBase->GetUnqualifiedNode(beforeNode) : this; 1409 } 1410 1411 virtual bool IsTemplatized() const 1412 { 1413 return true; 1414 } 1415 1416 virtual Node* TemplateParameterAt(int index) const 1417 { 1418 Node* child = fFirstArgument; 1419 while (child != NULL) { 1420 if (index == 0) 1421 return child; 1422 index--; 1423 child = child->Next(); 1424 } 1425 1426 return NULL; 1427 } 1428 1429 virtual bool IsNoReturnValueFunction() const 1430 { 1431 return fBase->IsNoReturnValueFunction(); 1432 } 1433 1434 virtual object_type ObjectType() const 1435 { 1436 return fBase->ObjectType(); 1437 } 1438 1439 virtual prefix_type PrefixType() const 1440 { 1441 return fBase->PrefixType(); 1442 } 1443 1444 protected: 1445 Node* fBase; 1446 Node* fFirstArgument; 1447 Node* fLastArgument; 1448 }; 1449 1450 1451 class MultiSubExpressionsNode : public Node { 1452 public: 1453 MultiSubExpressionsNode() 1454 : 1455 fFirstSubExpression(NULL), 1456 fLastSubExpression(NULL) 1457 { 1458 } 1459 1460 void AddSubExpression(Node* child) 1461 { 1462 child->SetParent(this); 1463 1464 if (fLastSubExpression != NULL) { 1465 fLastSubExpression->SetNext(child); 1466 fLastSubExpression = child; 1467 } else { 1468 fFirstSubExpression = child; 1469 fLastSubExpression = child; 1470 } 1471 } 1472 1473 protected: 1474 Node* fFirstSubExpression; 1475 Node* fLastSubExpression; 1476 }; 1477 1478 1479 class CallNode : public MultiSubExpressionsNode { 1480 public: 1481 CallNode() 1482 { 1483 } 1484 1485 virtual bool GetName(NameBuffer& buffer) const 1486 { 1487 // TODO: Use the real syntax! 1488 buffer.Append("call("); 1489 1490 Node* child = fFirstSubExpression; 1491 while (child != NULL) { 1492 if (child != fFirstSubExpression) 1493 buffer.Append(", "); 1494 1495 if (!child->GetName(buffer)) 1496 return false; 1497 1498 child = child->Next(); 1499 } 1500 1501 buffer.Append(")"); 1502 1503 return true; 1504 } 1505 }; 1506 1507 1508 class OperatorExpressionNode : public MultiSubExpressionsNode { 1509 public: 1510 OperatorExpressionNode(const operator_info* info) 1511 : 1512 fInfo(info) 1513 { 1514 } 1515 1516 virtual bool GetName(NameBuffer& buffer) const 1517 { 1518 bool isIdentifier = isalpha(fInfo->name[0]) || fInfo->name[0] == '_'; 1519 1520 if (fInfo->argument_count == 1 || isIdentifier 1521 || fInfo->argument_count > 3 1522 || (fInfo->argument_count == 3 && strcmp(fInfo->name, "?") != 0)) { 1523 // prefix operator 1524 buffer.Append(fInfo->name); 1525 1526 if (isIdentifier) 1527 buffer.Append("("); 1528 1529 Node* child = fFirstSubExpression; 1530 while (child != NULL) { 1531 if (child != fFirstSubExpression) 1532 buffer.Append(", "); 1533 1534 if (!child->GetName(buffer)) 1535 return false; 1536 1537 child = child->Next(); 1538 } 1539 1540 if (isIdentifier) 1541 buffer.Append(")"); 1542 1543 return true; 1544 } 1545 1546 Node* arg1 = fFirstSubExpression; 1547 Node* arg2 = arg1->Next(); 1548 1549 buffer.Append("("); 1550 1551 if (fInfo->argument_count == 2) { 1552 // binary infix operator 1553 if (!arg1->GetName(buffer)) 1554 return false; 1555 1556 buffer.Append(" "); 1557 buffer.Append(fInfo->name); 1558 buffer.Append(" "); 1559 1560 if (!arg2->GetName(buffer)) 1561 return false; 1562 1563 return buffer.Append(")"); 1564 } 1565 1566 Node* arg3 = arg2->Next(); 1567 1568 if (fInfo->argument_count == 2) { 1569 // trinary operator "... ? ... : ..." 1570 if (!arg1->GetName(buffer)) 1571 return false; 1572 1573 buffer.Append(" ? "); 1574 1575 if (!arg2->GetName(buffer)) 1576 return false; 1577 1578 buffer.Append(" : "); 1579 1580 if (!arg3->GetName(buffer)) 1581 return false; 1582 1583 return buffer.Append(")"); 1584 } 1585 1586 return false; 1587 } 1588 1589 private: 1590 const operator_info* fInfo; 1591 }; 1592 1593 1594 class ConversionExpressionNode : public MultiSubExpressionsNode { 1595 public: 1596 ConversionExpressionNode(Node* type) 1597 : 1598 fType(type) 1599 { 1600 fType->SetParent(this); 1601 } 1602 1603 virtual bool GetName(NameBuffer& buffer) const 1604 { 1605 buffer.Append("("); 1606 1607 if (!fType->GetName(buffer)) 1608 return false; 1609 1610 buffer.Append(")("); 1611 1612 Node* child = fFirstSubExpression; 1613 while (child != NULL) { 1614 if (child != fFirstSubExpression) 1615 buffer.Append(", "); 1616 1617 if (!child->GetName(buffer)) 1618 return false; 1619 1620 child = child->Next(); 1621 } 1622 1623 return buffer.Append(")"); 1624 } 1625 1626 private: 1627 Node* fType; 1628 }; 1629 1630 1631 class PointerToMemberNode : public DecoratingNode { 1632 public: 1633 PointerToMemberNode(Node* classType, Node* memberType) 1634 : 1635 DecoratingNode(memberType), 1636 fClassType(classType) 1637 { 1638 fClassType->SetParent(this); 1639 } 1640 1641 virtual bool AddDecoration(NameBuffer& buffer, 1642 const Node* stopDecorator) const 1643 { 1644 if (this == stopDecorator) 1645 return true; 1646 1647 if (!fChildNode->AddDecoration(buffer, stopDecorator)) 1648 return false; 1649 1650 // In most cases we need a space before the name. In some it is 1651 // superfluous, though. 1652 if (!buffer.IsEmpty() && buffer.LastChar() != '(') 1653 buffer.Append(" "); 1654 1655 if (!fClassType->GetName(buffer)) 1656 return false; 1657 1658 return buffer.Append("::*"); 1659 } 1660 1661 virtual object_type ObjectType() const 1662 { 1663 return OBJECT_TYPE_DATA; 1664 } 1665 1666 virtual TypeInfo Type() const 1667 { 1668 // TODO: Method pointers aren't ordinary pointers. Though we might not 1669 // be able to determine the difference. 1670 return TypeInfo(TYPE_POINTER); 1671 } 1672 1673 1674 private: 1675 Node* fClassType; 1676 }; 1677 1678 1679 class FunctionNode : public ObjectNode { 1680 public: 1681 FunctionNode(Node* nameNode, bool hasReturnType, bool isExternC) 1682 : 1683 ObjectNode(nameNode), 1684 fFirstTypeNode(NULL), 1685 fLastTypeNode(NULL), 1686 fHasReturnType(hasReturnType), 1687 fIsExternC(isExternC) 1688 { 1689 } 1690 1691 void AddType(Node* child) 1692 { 1693 child->SetParent(this); 1694 1695 if (fLastTypeNode != NULL) { 1696 fLastTypeNode->SetNext(child); 1697 fLastTypeNode = child; 1698 } else { 1699 fFirstTypeNode = child; 1700 fLastTypeNode = child; 1701 } 1702 } 1703 1704 virtual bool GetName(NameBuffer& buffer) const 1705 { 1706 NameDecorationInfo decorationInfo(NULL); 1707 return GetDecoratedName(buffer, decorationInfo); 1708 } 1709 1710 virtual bool GetDecoratedName(NameBuffer& buffer, 1711 NameDecorationInfo& decorationInfo) const 1712 { 1713 // write 'extern "C"' 1714 // if (fIsExternC) 1715 // buffer.Append("extern \"C\""); 1716 1717 // write the return type 1718 Node* child = fFirstTypeNode; 1719 if (_HasReturnType() && child != NULL) { 1720 if (!child->GetName(buffer)) 1721 return false; 1722 child = child->Next(); 1723 1724 buffer.Append(" ", 1); 1725 } 1726 1727 // write the function name 1728 if (fName == NULL) 1729 buffer.Append("(", 1); 1730 1731 CVQualifierInfo info; 1732 if (fName != NULL) { 1733 // skip CV qualifiers on our name -- we'll add them later 1734 fName->GetCVQualifierInfo(info); 1735 if (info.firstNonCVQualifier != NULL 1736 && !info.firstNonCVQualifier->GetName(buffer)) { 1737 return false; 1738 } 1739 } 1740 1741 // add non-CV qualifier decorations 1742 if (decorationInfo.firstDecorator != NULL) { 1743 if (!decorationInfo.firstDecorator->AddDecoration(buffer, 1744 decorationInfo.closestCVDecoratorList)) { 1745 return false; 1746 } 1747 } 1748 1749 if (fName == NULL) 1750 buffer.Append(")", 1); 1751 1752 // add the parameter types 1753 buffer.Append("("); 1754 1755 // don't add a single "void" parameter 1756 if (child != NULL && child->Next() == NULL 1757 && child->IsTypeName("void", 4)) { 1758 child = NULL; 1759 } 1760 1761 Node* firstParam = child; 1762 while (child != NULL) { 1763 if (child != firstParam) 1764 buffer.Append(", "); 1765 1766 if (!child->GetName(buffer)) 1767 return false; 1768 1769 child = child->Next(); 1770 } 1771 1772 buffer.Append(")"); 1773 1774 // add CV qualifiers on our name 1775 if (info.firstCVQualifier != NULL) { 1776 if (!info.firstCVQualifier->AddDecoration(buffer, 1777 info.firstNonCVQualifier)) { 1778 return false; 1779 } 1780 } 1781 1782 // add CV qualifiers on us 1783 if (decorationInfo.closestCVDecoratorList != NULL) 1784 decorationInfo.closestCVDecoratorList->AddDecoration(buffer, NULL); 1785 1786 return true; 1787 } 1788 1789 virtual object_type ObjectType() const 1790 { 1791 // no name, no fun 1792 if (fName == NULL) 1793 return OBJECT_TYPE_FUNCTION; 1794 1795 // check our name's prefix 1796 switch (fName->PrefixType()) { 1797 case PREFIX_NONE: 1798 case PREFIX_NAMESPACE: 1799 return OBJECT_TYPE_FUNCTION; 1800 case PREFIX_CLASS: 1801 case PREFIX_UNKNOWN: 1802 break; 1803 } 1804 1805 // Our name has a prefix, but we don't know, whether it is a class or 1806 // namespace. Let's ask our name what it thinks it is. 1807 object_type type = fName->ObjectType(); 1808 switch (type) { 1809 case OBJECT_TYPE_FUNCTION: 1810 case OBJECT_TYPE_METHOD_CLASS: 1811 case OBJECT_TYPE_METHOD_OBJECT: 1812 case OBJECT_TYPE_METHOD_UNKNOWN: 1813 // That's as good as it gets. 1814 return type; 1815 case OBJECT_TYPE_UNKNOWN: 1816 case OBJECT_TYPE_DATA: 1817 default: 1818 // Obviously our name doesn't have a clue. 1819 return OBJECT_TYPE_METHOD_UNKNOWN; 1820 } 1821 } 1822 1823 virtual Node* ParameterAt(uint32 index) const 1824 { 1825 // skip return type 1826 Node* child = fFirstTypeNode; 1827 if (_HasReturnType() && child != NULL) 1828 child = child->Next(); 1829 1830 // ignore a single "void" parameter 1831 if (child != NULL && child->Next() == NULL 1832 && child->IsTypeName("void", 4)) { 1833 return NULL; 1834 } 1835 1836 // get the type at the index 1837 while (child != NULL && index > 0) { 1838 child = child->Next(); 1839 index--; 1840 } 1841 1842 return child; 1843 } 1844 1845 private: 1846 bool _HasReturnType() const 1847 { 1848 return fHasReturnType 1849 || fName == NULL 1850 || (fName->IsTemplatized() && !fName->IsNoReturnValueFunction()); 1851 } 1852 1853 private: 1854 Node* fFirstTypeNode; 1855 Node* fLastTypeNode; 1856 bool fHasReturnType; 1857 bool fIsExternC; 1858 }; 1859 1860 1861 // #pragma mark - Demangler 1862 1863 1864 class Demangler { 1865 public: 1866 Demangler(); 1867 1868 int Demangle(const char* mangledName, char* buffer, 1869 size_t size, 1870 DemanglingInfo& demanglingInfo); 1871 int GetParameterInfo(const char* mangledName, 1872 uint32 index, char* buffer, size_t size, 1873 ParameterInfo& info); 1874 1875 // actually private, but public to make gcc 2 happy 1876 inline bool _SetError(int error); 1877 inline void _AddAllocatedNode(Node* node); 1878 1879 private: 1880 template<typename NodeType> struct NodeCreator; 1881 1882 inline bool _SkipExpected(char c); 1883 inline bool _SkipExpected(const char* string); 1884 1885 void _Init(); 1886 void _Cleanup(); 1887 1888 int _Demangle(const char* mangledName, char* buffer, 1889 size_t size, 1890 DemanglingInfo& demanglingInfo); 1891 int _GetParameterInfo(const char* mangledName, 1892 uint32 index, char* buffer, size_t size, 1893 ParameterInfo& info); 1894 1895 int _Parse(const char* mangledName, 1896 const char*& versionSuffix, 1897 ObjectNode*& _node); 1898 1899 bool _ParseClone(ObjectNode*& _node); 1900 bool _ParseEncoding(ObjectNode*& _node); 1901 bool _ParseSpecialName(Node*& _node); 1902 bool _ParseCallOffset(bool& nonVirtual, 1903 number_type& offset1, number_type& offset2); 1904 bool _ParseName(Node*& _node); 1905 bool _ParseNestedName(Node*& _node); 1906 bool _ParseNestedNameInternal(Node*& _node); 1907 bool _ParseLocalName(Node*& _node); 1908 bool _ParseUnqualifiedName(Node*& _node); 1909 bool _ParseSourceName(Node*& _node); 1910 bool _ParseOperatorName(Node*& _node); 1911 bool _ParseType(Node*& _node); 1912 bool _ParseTypeInternal(Node*& _node); 1913 void _ParseCVQualifiers(int& qualifiers); 1914 bool _ParseTypeWithModifier(type_modifier modifier, 1915 int toSkip, Node*& _node); 1916 bool _TryParseBuiltinType(Node*& _node); 1917 bool _ParseFunctionType(FunctionNode*& _node);; 1918 bool _ParseArrayType(Node*& _node); 1919 bool _ParsePointerToMemberType(Node*& _node); 1920 bool _ParseTemplateParam(Node*& _node); 1921 bool _ParseSubstitution(Node*& _node); 1922 bool _ParseSubstitutionInternal(Node*& _node); 1923 bool _ParseBareFunctionType(FunctionNode* node); 1924 bool _ParseTemplateArgs(Node* node, Node*& _node); 1925 bool _ParseTemplateArg(Node*& _node); 1926 bool _ParseExpression(Node*& _node); 1927 bool _ParseExpressionPrimary(Node*& _node); 1928 bool _ParseNumber(number_type& number); 1929 1930 bool _CreateNodeAndSkip(const char* name, 1931 size_t length, int toSkip, Node*& _node); 1932 bool _CreateNodeAndSkip(const char* name, int toSkip, 1933 Node*& _node); 1934 bool _CreateTypeNodeAndSkip(type_type type, 1935 int toSkip, Node*& _node); 1936 bool _CreateTypeNodeAndSkip(const char* name, 1937 const char* prefix, 1938 const char* templateArgs, int toSkip, 1939 Node*& _node); 1940 1941 void _RegisterReferenceableNode(Node* node); 1942 bool _CreateSubstitutionNode(int index, 1943 Node*& _node); 1944 1945 private: 1946 Input fInput; 1947 int fError; 1948 Node* fAllocatedNodes; 1949 Node* fFirstReferenceableNode; 1950 Node* fLastReferenceableNode; 1951 Node* fTemplatizedNode; 1952 }; 1953 1954 1955 template<typename NodeType> 1956 struct Demangler::NodeCreator { 1957 NodeCreator(Demangler* demangler) 1958 : 1959 fDemangler(demangler) 1960 { 1961 } 1962 1963 template<typename ReturnType> 1964 inline bool operator()(ReturnType*& _node) const 1965 { 1966 _node = NEW(NodeType); 1967 if (_node == NULL) 1968 return fDemangler->_SetError(ERROR_NO_MEMORY); 1969 1970 fDemangler->_AddAllocatedNode(_node); 1971 return true; 1972 } 1973 1974 template<typename ParameterType1, typename ReturnType> 1975 inline bool operator()(ParameterType1 arg1, ReturnType*& _node) const 1976 { 1977 _node = NEW(NodeType(arg1)); 1978 if (_node == NULL) 1979 return fDemangler->_SetError(ERROR_NO_MEMORY); 1980 1981 fDemangler->_AddAllocatedNode(_node); 1982 return true; 1983 } 1984 1985 template<typename ParameterType1, typename ParameterType2, 1986 typename ReturnType> 1987 inline bool operator()(ParameterType1 arg1, ParameterType2 arg2, 1988 ReturnType*& _node) const 1989 { 1990 _node = NEW(NodeType(arg1, arg2)); 1991 if (_node == NULL) 1992 return fDemangler->_SetError(ERROR_NO_MEMORY); 1993 1994 fDemangler->_AddAllocatedNode(_node); 1995 return true; 1996 } 1997 1998 template<typename ParameterType1, typename ParameterType2, 1999 typename ParameterType3, typename ReturnType> 2000 inline bool operator()(ParameterType1 arg1, ParameterType2 arg2, 2001 ParameterType3 arg3, ReturnType*& _node) const 2002 { 2003 _node = NEW(NodeType(arg1, arg2, arg3)); 2004 if (_node == NULL) 2005 return fDemangler->_SetError(ERROR_NO_MEMORY); 2006 2007 fDemangler->_AddAllocatedNode(_node); 2008 return true; 2009 } 2010 2011 private: 2012 Demangler* fDemangler; 2013 }; 2014 2015 2016 inline bool 2017 Demangler::_SetError(int error) 2018 { 2019 if (fError == ERROR_OK) { 2020 fError = error; 2021 #ifdef TRACE_GCC3_DEMANGLER 2022 DebugScope::Print("_SetError(): %d, remaining input: \"%s\"\n", 2023 error, fInput.String()); 2024 #endif 2025 } 2026 return false; 2027 } 2028 2029 2030 inline void 2031 Demangler::_AddAllocatedNode(Node* node) 2032 { 2033 node->SetNextAllocated(fAllocatedNodes); 2034 fAllocatedNodes = node; 2035 } 2036 2037 2038 inline bool 2039 Demangler::_SkipExpected(char c) 2040 { 2041 return fInput.SkipPrefix(c) || _SetError(ERROR_INVALID); 2042 } 2043 2044 2045 inline bool 2046 Demangler::_SkipExpected(const char* string) 2047 { 2048 return fInput.SkipPrefix(string) || _SetError(ERROR_INVALID); 2049 } 2050 2051 2052 Demangler::Demangler() 2053 : 2054 fInput(), 2055 fAllocatedNodes(NULL) 2056 { 2057 } 2058 2059 2060 int 2061 Demangler::Demangle(const char* mangledName, char* buffer, size_t size, 2062 DemanglingInfo& demanglingInfo) 2063 { 2064 DEBUG_SCOPE("Demangle"); 2065 2066 _Init(); 2067 2068 int result = _Demangle(mangledName, buffer, size, demanglingInfo); 2069 2070 _Cleanup(); 2071 2072 return result; 2073 } 2074 2075 2076 int 2077 Demangler::GetParameterInfo(const char* mangledName, uint32 index, char* buffer, 2078 size_t size, ParameterInfo& info) 2079 { 2080 DEBUG_SCOPE("GetParameterInfo"); 2081 2082 _Init(); 2083 2084 int result = _GetParameterInfo(mangledName, index, buffer, size, info); 2085 2086 _Cleanup(); 2087 2088 return result; 2089 } 2090 2091 2092 void 2093 Demangler::_Init() 2094 { 2095 fError = ERROR_OK; 2096 2097 fFirstReferenceableNode = NULL; 2098 fLastReferenceableNode = NULL; 2099 fAllocatedNodes = NULL; 2100 fTemplatizedNode = NULL; 2101 } 2102 2103 2104 void 2105 Demangler::_Cleanup() 2106 { 2107 while (fAllocatedNodes != NULL) { 2108 Node* node = fAllocatedNodes; 2109 fAllocatedNodes = node->NextAllocated(); 2110 DELETE(node); 2111 } 2112 } 2113 2114 2115 int 2116 Demangler::_Demangle(const char* mangledName, char* buffer, size_t size, 2117 DemanglingInfo& demanglingInfo) 2118 { 2119 // parse the name 2120 const char* versionSuffix; 2121 ObjectNode* node; 2122 int error = _Parse(mangledName, versionSuffix, node); 2123 if (error != ERROR_OK) 2124 return error; 2125 2126 NameBuffer nameBuffer(buffer, size); 2127 bool success = node->GetObjectName(nameBuffer, demanglingInfo); 2128 2129 // If versioned, append the unmodified version string 2130 if (success && versionSuffix != NULL) 2131 nameBuffer.Append(versionSuffix); 2132 2133 if (nameBuffer.HadOverflow()) 2134 return ERROR_BUFFER_TOO_SMALL; 2135 2136 if (!success) 2137 return ERROR_INTERNAL; 2138 2139 demanglingInfo.objectType = node->ObjectType(); 2140 2141 nameBuffer.Terminate(); 2142 return ERROR_OK; 2143 } 2144 2145 2146 int 2147 Demangler::_GetParameterInfo(const char* mangledName, uint32 index, 2148 char* buffer, size_t size, ParameterInfo& info) 2149 { 2150 // parse the name 2151 const char* versionSuffix; 2152 ObjectNode* node; 2153 int error = _Parse(mangledName, versionSuffix, node); 2154 if (error != ERROR_OK) 2155 return error; 2156 2157 // get the parameter node 2158 Node* parameter = node->ParameterAt(index); 2159 if (parameter == NULL) 2160 return ERROR_INVALID_PARAMETER_INDEX; 2161 2162 // get the parameter name 2163 NameBuffer nameBuffer(buffer, size); 2164 bool success = parameter->GetName(nameBuffer); 2165 2166 if (nameBuffer.HadOverflow()) 2167 return ERROR_BUFFER_TOO_SMALL; 2168 2169 if (!success) 2170 return ERROR_INTERNAL; 2171 2172 nameBuffer.Terminate(); 2173 2174 // get the type 2175 info.type = parameter->Type(); 2176 2177 return ERROR_OK; 2178 } 2179 2180 2181 int 2182 Demangler::_Parse(const char* mangledName, const char*& versionSuffix, 2183 ObjectNode*& _node) 2184 { 2185 // To support versioned symbols, we ignore the version suffix when 2186 // demangling. 2187 versionSuffix = strchr(mangledName, '@'); 2188 fInput.SetTo(mangledName, 2189 versionSuffix != NULL 2190 ? versionSuffix - mangledName : strlen(mangledName)); 2191 2192 // <mangled-name> ::= _Z <encoding> [<clone-suffix>]* 2193 2194 if (!fInput.SkipPrefix("_Z")) 2195 return ERROR_NOT_MANGLED; 2196 2197 if (!_ParseEncoding(_node) || !_ParseClone(_node)) 2198 return fError; 2199 2200 if (fInput.CharsRemaining() != 0) { 2201 // bogus at end of input 2202 return ERROR_INVALID; 2203 } 2204 2205 return ERROR_OK; 2206 } 2207 2208 2209 bool 2210 Demangler::_ParseClone(ObjectNode*& _node) 2211 { 2212 DEBUG_SCOPE("_ParseClone"); 2213 2214 while (fInput.HasPrefix('.')) { 2215 int count = fInput.CharsRemaining(); 2216 int i = 1; 2217 while (true) { 2218 for (; i < count && fInput[i] != '.'; i++) 2219 ; 2220 if (i + 1 >= count || fInput[i + 1] < '0' || fInput[i + 1] > '9') 2221 break; 2222 i++; 2223 } 2224 if (i == 1) 2225 break; 2226 Node* clone; 2227 if (!_CreateNodeAndSkip(fInput.String(), i, i, clone)) 2228 return false; 2229 2230 if (!NodeCreator<ClonedNode>(this)(clone, _node, _node)) 2231 return false; 2232 } 2233 return true; 2234 } 2235 2236 2237 bool 2238 Demangler::_ParseEncoding(ObjectNode*& _node) 2239 { 2240 DEBUG_SCOPE("_ParseEncoding"); 2241 2242 // <encoding> ::= <function name> <bare-function-type> 2243 // ::= <data name> 2244 // ::= <special-name> 2245 2246 // NOTE: This is not in the specs: Local entities seem to be prefixed 2247 // by an 'L'. 2248 fInput.SkipPrefix('L'); 2249 2250 // parse <special-name>, if it is one 2251 Node* name; 2252 if (fInput.HasPrefix('T') || fInput.HasPrefix("GV")) { 2253 return _ParseSpecialName(name) 2254 && NodeCreator<ObjectNode>(this)(name, _node); 2255 } 2256 2257 // either <data name> or <function name> 2258 if (!_ParseName(name)) 2259 return false; 2260 2261 if (fInput.CharsRemaining() == 0 || fInput.HasPrefix('E') 2262 || fInput.HasPrefix('.')) { 2263 // <data name> 2264 return NodeCreator<ObjectNode>(this)(name, _node); 2265 } 2266 2267 // <function name> -- parse remaining <bare-function-type> 2268 FunctionNode* functionNode; 2269 if (!NodeCreator<FunctionNode>(this)(name, false, false, functionNode)) 2270 return false; 2271 _node = functionNode; 2272 2273 // If our name is templatized, we push it onto the templatized node 2274 // stack while parsing the function parameters. 2275 Node* previousTemplatizedNode = fTemplatizedNode; 2276 if (name->IsTemplatized()) 2277 fTemplatizedNode = name; 2278 2279 if (!_ParseBareFunctionType(functionNode)) 2280 return false; 2281 2282 fTemplatizedNode = previousTemplatizedNode; 2283 2284 return true; 2285 } 2286 2287 2288 bool 2289 Demangler::_ParseSpecialName(Node*& _node) 2290 { 2291 DEBUG_SCOPE("_ParseSpecialName"); 2292 2293 if (fInput.CharsRemaining() == 0) 2294 return _SetError(ERROR_INVALID); 2295 2296 // <special-name> ::= GV <object name> # Guard variable for one-time 2297 // # initialization 2298 // # No <type> 2299 if (!fInput.SkipPrefix('T')) { 2300 Node* name; 2301 return _SkipExpected("GV") 2302 && _ParseName(name) 2303 && NodeCreator<SpecialNameNode>(this)("guard variable for ", 2304 name, _node); 2305 } 2306 2307 // <special-name> ::= TV <type> # virtual table 2308 // ::= TT <type> # VTT structure (construction vtable 2309 // # index) 2310 // ::= TI <type> # typeinfo structure 2311 // ::= TS <type> # typeinfo name (null-terminated byte 2312 // # string) 2313 const char* prefix = NULL; 2314 switch (fInput[0]) { 2315 case 'V': 2316 prefix = "vtable for "; 2317 break; 2318 case 'T': 2319 prefix = "VTT for "; 2320 break; 2321 case 'I': 2322 prefix = "typeinfo for "; 2323 break; 2324 case 'S': 2325 prefix = "typeinfo name for "; 2326 break; 2327 } 2328 2329 if (prefix != NULL) { 2330 fInput.Skip(1); 2331 Node* type; 2332 return _ParseType(type) 2333 && NodeCreator<SpecialNameNode>(this)(prefix, type, _node); 2334 } 2335 2336 // <special-name> ::= Tc <call-offset> <call-offset> <base encoding> 2337 // # base is the nominal target function of thunk 2338 // # first call-offset is 'this' adjustment 2339 // # second call-offset is result adjustment 2340 if (fInput.SkipPrefix('c')) { 2341 bool nonVirtual; 2342 number_type offset1; 2343 number_type offset2; 2344 ObjectNode* name; 2345 return _ParseCallOffset(nonVirtual, offset1, offset2) 2346 && _ParseCallOffset(nonVirtual, offset1, offset2) 2347 && _ParseEncoding(name) 2348 && NodeCreator<SpecialNameNode>(this)( 2349 "covariant return thunk to ", name, _node); 2350 } 2351 2352 // <special-name> ::= T <call-offset> <base encoding> 2353 // # base is the nominal target function of thunk 2354 bool nonVirtual; 2355 number_type offset1; 2356 number_type offset2; 2357 ObjectNode* name; 2358 return _ParseCallOffset(nonVirtual, offset1, offset2) 2359 && _ParseEncoding(name) 2360 && NodeCreator<SpecialNameNode>(this)( 2361 nonVirtual ? "non-virtual thunk to " : "virtual thunk to ", 2362 name, _node); 2363 } 2364 2365 2366 bool 2367 Demangler::_ParseCallOffset(bool& nonVirtual, number_type& offset1, 2368 number_type& offset2) 2369 { 2370 // <call-offset> ::= h <nv-offset> _ 2371 // ::= v <v-offset> _ 2372 // <nv-offset> ::= <offset number> 2373 // # non-virtual base override 2374 // <v-offset> ::= <offset number> _ <virtual offset number> 2375 // # virtual base override, with vcall offset 2376 2377 // non-virtual 2378 if (fInput.SkipPrefix('h')) { 2379 nonVirtual = true; 2380 return _ParseNumber(offset1) && _SkipExpected('_'); 2381 } 2382 2383 // virtual 2384 nonVirtual = false; 2385 return _SkipExpected('v') 2386 && _ParseNumber(offset1) 2387 && _SkipExpected('_') 2388 && _ParseNumber(offset2) 2389 && _SkipExpected('_'); 2390 } 2391 2392 bool 2393 Demangler::_ParseName(Node*& _node) 2394 { 2395 DEBUG_SCOPE("_ParseName"); 2396 2397 if (fInput.CharsRemaining() == 0) 2398 return _SetError(ERROR_INVALID); 2399 2400 // <name> ::= <nested-name> 2401 // ::= <unscoped-name> 2402 // ::= <unscoped-template-name> <template-args> 2403 // ::= <local-name> # See Scope Encoding below 2404 // 2405 // <unscoped-name> ::= <unqualified-name> 2406 // ::= St <unqualified-name> # ::std:: 2407 // 2408 // <unscoped-template-name> ::= <unscoped-name> 2409 // ::= <substitution> 2410 2411 switch (fInput[0]) { 2412 case 'N': 2413 // <nested-name> 2414 return _ParseNestedName(_node); 2415 case 'Z': 2416 // <local-name> 2417 return _ParseLocalName(_node); 2418 case 'S': 2419 { 2420 // <substitution> 2421 if (!fInput.HasPrefix("St")) { 2422 if (!_ParseSubstitution(_node)) 2423 return false; 2424 break; 2425 } 2426 2427 // std:: namespace 2428 fInput.Skip(2); 2429 2430 Node* prefix; 2431 if (!NodeCreator<SimpleNameNode>(this)("std", prefix)) 2432 return false; 2433 2434 // <unqualified-name> 2435 Node* node; 2436 if (!_ParseUnqualifiedName(node) 2437 || !NodeCreator<PrefixedNode>(this)(prefix, node, _node)) { 2438 return false; 2439 } 2440 2441 break; 2442 } 2443 default: 2444 // <unqualified-name> 2445 if (!_ParseUnqualifiedName(_node)) 2446 return false; 2447 break; 2448 } 2449 2450 // We get here for the names that might be an <unscoped-template-name>. 2451 // Check whether <template-args> are following. 2452 if (!fInput.HasPrefix('I')) 2453 return true; 2454 2455 // <unscoped-template-name> is referenceable 2456 _RegisterReferenceableNode(_node); 2457 2458 return _ParseTemplateArgs(_node, _node); 2459 } 2460 2461 2462 bool 2463 Demangler::_ParseNestedName(Node*& _node) 2464 { 2465 DEBUG_SCOPE("_ParseNestedName"); 2466 2467 // <nested-name> ::= N [<CV-qualifiers>] <prefix> <unqualified-name> E 2468 // ::= N [<CV-qualifiers>] <template-prefix> 2469 // <template-args> E 2470 // 2471 // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const 2472 // 2473 // <prefix> ::= <prefix> <unqualified-name> 2474 // ::= <template-prefix> <template-args> 2475 // ::= <template-param> 2476 // ::= # empty 2477 // ::= <substitution> 2478 // 2479 // <template-prefix> ::= <prefix> <template unqualified-name> 2480 // ::= <template-param> 2481 // ::= <substitution> 2482 2483 if (!_SkipExpected('N')) 2484 return false; 2485 2486 // parse CV qualifiers 2487 int qualifiers; 2488 _ParseCVQualifiers(qualifiers); 2489 2490 // parse the main part 2491 if (!_ParseNestedNameInternal(_node)) 2492 return false; 2493 2494 // create a CV qualifiers wrapper node, if necessary 2495 if (qualifiers != 0) { 2496 return NodeCreator<CVQualifiersNode>(this)(qualifiers, _node, 2497 _node); 2498 } 2499 2500 return true; 2501 } 2502 2503 2504 bool 2505 Demangler::_ParseNestedNameInternal(Node*& _node) 2506 { 2507 DEBUG_SCOPE("_ParseNestedNameMain"); 2508 2509 if (fInput.CharsRemaining() == 0) 2510 return _SetError(ERROR_INVALID); 2511 2512 // the initial prefix might be a template param or a substitution 2513 Node* initialPrefixNode = NULL; 2514 Node* prefixNode = NULL; 2515 switch (fInput[0]) { 2516 case 'T': // <template-param> 2517 if (!_ParseTemplateParam(initialPrefixNode)) 2518 return false; 2519 2520 // a <prefix> or <template-prefix> and as such referenceable 2521 _RegisterReferenceableNode(initialPrefixNode); 2522 break; 2523 2524 case 'S': // <substitution> 2525 if (!_ParseSubstitution(initialPrefixNode)) 2526 return false; 2527 break; 2528 } 2529 2530 while (true) { 2531 bool canTerminate = false; 2532 Node* node; 2533 2534 if (initialPrefixNode != NULL) { 2535 node = initialPrefixNode; 2536 initialPrefixNode = NULL; 2537 } else { 2538 if (!_ParseUnqualifiedName(node)) 2539 return false; 2540 canTerminate = true; 2541 } 2542 2543 // join prefix and the new node 2544 if (prefixNode != NULL) { 2545 if (!NodeCreator<PrefixedNode>(this)(prefixNode, node, node)) 2546 return false; 2547 } 2548 2549 // template arguments? 2550 if (fInput.HasPrefix('I')) { 2551 // <template-prefix> is referenceable 2552 _RegisterReferenceableNode(node); 2553 2554 // parse the template arguments 2555 if (!_ParseTemplateArgs(node, node)) 2556 return false; 2557 canTerminate = true; 2558 } 2559 2560 if (fInput.CharsRemaining() == 0) 2561 return _SetError(ERROR_INVALID); 2562 2563 // end of nested name? 2564 if (fInput.SkipPrefix('E')) { 2565 // If it doesn't have template args, it must end in an 2566 // unqualified name. 2567 if (!canTerminate) 2568 return _SetError(ERROR_INVALID); 2569 2570 _node = node; 2571 return true; 2572 } 2573 2574 // The fun continues, so this is a <prefix> or <template-prefix> 2575 // and as such referenceable. 2576 prefixNode = node; 2577 _RegisterReferenceableNode(node); 2578 } 2579 } 2580 2581 2582 bool 2583 Demangler::_ParseLocalName(Node*& _node) 2584 { 2585 DEBUG_SCOPE("_ParseLocalName"); 2586 2587 // <local-name> := Z <function encoding> E <entity name> 2588 // [<discriminator>] 2589 // := Z <function encoding> E s [<discriminator>] 2590 // <discriminator> := _ <non-negative number> 2591 2592 // parse the function name 2593 ObjectNode* functionName; 2594 if (!_SkipExpected('Z') 2595 || !_ParseEncoding(functionName) 2596 || !_SkipExpected('E')) { 2597 return false; 2598 } 2599 2600 Node* entityName; 2601 if (fInput.SkipPrefix('s')) { 2602 // string literal 2603 if (!NodeCreator<SimpleNameNode>(this)("string literal", 2604 entityName)) { 2605 return false; 2606 } 2607 } else { 2608 // local type or object 2609 if (!_ParseName(entityName)) 2610 return false; 2611 } 2612 2613 // parse discriminator 2614 number_type discriminator = 0; 2615 if (fInput.SkipPrefix('_')) { 2616 if (!_ParseNumber(discriminator)) 2617 return false; 2618 if (discriminator < 0) 2619 return _SetError(ERROR_INVALID); 2620 discriminator++; 2621 } 2622 2623 return NodeCreator<PrefixedNode>(this)(functionName, entityName, _node); 2624 } 2625 2626 2627 bool 2628 Demangler::_ParseUnqualifiedName(Node*& _node) 2629 { 2630 DEBUG_SCOPE("_ParseUnqualifiedName"); 2631 2632 // <unqualified-name> ::= <operator-name> 2633 // ::= <ctor-dtor-name> 2634 // ::= <source-name> 2635 // 2636 // <source-name> ::= <positive length number> <identifier> 2637 // <number> ::= [n] <non-negative decimal integer> 2638 // <identifier> ::= <unqualified source code identifier> 2639 // 2640 // <ctor-dtor-name> ::= C1 # complete object constructor 2641 // ::= C2 # base object constructor 2642 // ::= C3 # complete object allocating constructor 2643 // ::= D0 # deleting destructor 2644 // ::= D1 # complete object destructor 2645 // ::= D2 # base object destructor 2646 2647 // we need at least 2 chars 2648 if (fInput.CharsRemaining() < 2) 2649 return _SetError(ERROR_INVALID); 2650 2651 if (isdigit(fInput[0]) || (fInput[0] == 'n' && isdigit(fInput[1]))) { 2652 // <source-name> 2653 return _ParseSourceName(_node); 2654 } 2655 2656 if (fInput[0] == 'C') { 2657 // <ctor-dtor-name> -- constructors 2658 switch (fInput[1]) { 2659 case '1': 2660 case '2': 2661 case '3': 2662 if (!NodeCreator<XtructorNode>(this)(true, fInput[1] - '1', 2663 _node)) { 2664 return false; 2665 } 2666 2667 fInput.Skip(2); 2668 return true; 2669 default: 2670 return _SetError(ERROR_INVALID); 2671 } 2672 } 2673 2674 if (fInput[0] == 'D') { 2675 // <ctor-dtor-name> -- destructors 2676 switch (fInput[1]) { 2677 case '0': 2678 case '1': 2679 case '2': 2680 if (!NodeCreator<XtructorNode>(this)(false, fInput[1] - '0', 2681 _node)) { 2682 return false; 2683 } 2684 2685 fInput.Skip(2); 2686 return true; 2687 default: 2688 return _SetError(ERROR_INVALID); 2689 } 2690 } 2691 2692 // must be an <operator-name> 2693 return _ParseOperatorName(_node); 2694 } 2695 2696 2697 bool 2698 Demangler::_ParseSourceName(Node*& _node) 2699 { 2700 DEBUG_SCOPE("_ParseSourceName"); 2701 2702 if (fInput.CharsRemaining() == 0) 2703 return _SetError(ERROR_INVALID); 2704 2705 number_type number; 2706 if (!_ParseNumber(number)) 2707 return false; 2708 2709 if (number <= 0 || number > fInput.CharsRemaining()) 2710 return _SetError(ERROR_INVALID); 2711 2712 return _CreateNodeAndSkip(fInput.String(), number, number, _node); 2713 } 2714 2715 2716 bool 2717 Demangler::_ParseOperatorName(Node*& _node) 2718 { 2719 DEBUG_SCOPE("_ParseOperatorName"); 2720 2721 if (fInput.CharsRemaining() < 2) 2722 return _SetError(ERROR_INVALID); 2723 2724 const operator_info* info = NULL; 2725 for (int i = 0; kOperatorInfos[i].name != NULL; i++) { 2726 if (fInput.SkipPrefix(kOperatorInfos[i].mangled_name)) { 2727 info = &kOperatorInfos[i]; 2728 break; 2729 } 2730 } 2731 2732 if (info != NULL) 2733 return NodeCreator<OperatorNode>(this)(info, _node); 2734 2735 // <operator-name> ::= cv <type> # (cast) 2736 if (fInput.SkipPrefix("cv")) { 2737 Node* typeNode; 2738 if (!_ParseType(typeNode)) 2739 return false; 2740 2741 return NodeCreator<CastOperatorNode>(this)(typeNode, _node); 2742 } 2743 2744 // <operator-name> ::= v <digit> <source-name> # vendor extended 2745 // operator 2746 if (fInput.SkipPrefix('v')) { 2747 if (fInput.CharsRemaining() == 0 || !isdigit(fInput[0])) 2748 return _SetError(ERROR_INVALID); 2749 fInput.Skip(1); 2750 2751 Node* name; 2752 return _ParseSourceName(name) 2753 && NodeCreator<VendorOperatorNode>(this)(name, _node); 2754 } 2755 2756 return _SetError(ERROR_INVALID); 2757 } 2758 2759 2760 bool 2761 Demangler::_ParseType(Node*& _node) 2762 { 2763 DEBUG_SCOPE("_ParseType"); 2764 2765 if (!_ParseTypeInternal(_node)) 2766 return false; 2767 2768 _RegisterReferenceableNode(_node); 2769 return true; 2770 } 2771 2772 2773 bool 2774 Demangler::_ParseTypeInternal(Node*& _node) 2775 { 2776 DEBUG_SCOPE("_ParseTypeInternal"); 2777 2778 // <type> ::= <builtin-type> 2779 // ::= <function-type> 2780 // ::= <class-enum-type> 2781 // ::= <array-type> 2782 // ::= <pointer-to-member-type> 2783 // ::= <template-param> 2784 // ::= <template-template-param> <template-args> 2785 // ::= <substitution> # See Compression below 2786 // 2787 // <template-template-param> ::= <template-param> 2788 // ::= <substitution> 2789 // 2790 // <type> ::= <CV-qualifiers> <type> 2791 // ::= P <type> # pointer-to 2792 // ::= R <type> # reference-to 2793 // ::= O <type> # rvalue reference-to (C++0x) 2794 // ::= C <type> # complex pair (C 2000) 2795 // ::= G <type> # imaginary (C 2000) 2796 // ::= U <source-name> <type> # vendor extended type qualifier 2797 // 2798 // <CV-qualifiers> ::= [r] [V] [K] # restrict (C99), volatile, const 2799 // 2800 // <type> ::= Dp <type> # pack expansion of (C++0x) 2801 // ::= Dt <expression> E # decltype of an id-expression or 2802 // # class member access (C++0x) 2803 // ::= DT <expression> E # decltype of an expression (C++0x) 2804 2805 if (_TryParseBuiltinType(_node)) { 2806 _node->SetReferenceable(false); 2807 return true; 2808 } 2809 if (fError != ERROR_OK) 2810 return false; 2811 2812 if (fInput.CharsRemaining() == 0) 2813 return _SetError(ERROR_INVALID); 2814 2815 switch (fInput[0]) { 2816 // function type 2817 case 'F': 2818 { 2819 FunctionNode* functionNode; 2820 if (!_ParseFunctionType(functionNode)) 2821 return false; 2822 _node = functionNode; 2823 return true; 2824 } 2825 2826 // array type 2827 case 'A': 2828 return _ParseArrayType(_node); 2829 2830 // pointer to member type 2831 case 'M': 2832 return _ParsePointerToMemberType(_node); 2833 2834 // template param 2835 case 'T': 2836 if (!_ParseTemplateParam(_node)) 2837 return false; 2838 break; 2839 2840 // CV qualifiers 2841 case 'r': 2842 case 'V': 2843 case 'K': 2844 { 2845 // parse CV qualifiers 2846 int qualifiers; 2847 _ParseCVQualifiers(qualifiers); 2848 2849 // parse the type 2850 if (!_ParseType(_node)) 2851 return false; 2852 2853 // create the wrapper node 2854 return NodeCreator<CVQualifiersNode>(this)(qualifiers, _node, 2855 _node); 2856 } 2857 2858 // pointer, reference, etc. 2859 case 'P': 2860 return _ParseTypeWithModifier(TYPE_QUALIFIER_POINTER, 1, _node); 2861 case 'R': 2862 return _ParseTypeWithModifier(TYPE_QUALIFIER_REFERENCE, 1, 2863 _node); 2864 case 'O': 2865 return _ParseTypeWithModifier( 2866 TYPE_QUALIFIER_RVALUE_REFERENCE, 1, _node); 2867 case 'C': 2868 return _ParseTypeWithModifier(TYPE_QUALIFIER_COMPLEX, 1, _node); 2869 case 'G': 2870 return _ParseTypeWithModifier(TYPE_QUALIFIER_IMAGINARY, 1, 2871 _node); 2872 2873 // pack and decltype 2874 case 'D': 2875 #if 0 2876 if (fInput.CharsRemaining() < 2) 2877 return _SetError(ERROR_INVALID); 2878 2879 switch(fInput[1]) { 2880 case 'p': 2881 fInput.Skip(2); 2882 return _ParseType(_node); 2883 case 't': 2884 case 'T': 2885 { 2886 fInput.Skip(2); 2887 Node* nameNode; 2888 if (!_ParseExpression(nameNode)) 2889 return false; 2890 if (!fInput.SkipPrefix('E')) 2891 return ERROR_INVALID; 2892 } 2893 } 2894 #endif 2895 // NOTE: Unsupported by the GNU demangler. 2896 return _SetError(ERROR_UNSUPPORTED); 2897 2898 // vendor extended type qualifier 2899 case 'U': 2900 fInput.Skip(1); 2901 Node* name; 2902 Node* type; 2903 return _ParseSourceName(name) && _ParseType(type) 2904 && NodeCreator<VendorTypeModifierNode>(this)(name, type, 2905 _node); 2906 2907 // substitution 2908 case 'S': 2909 if (!fInput.HasPrefix("St")) { 2910 if (!_ParseSubstitution(_node)) 2911 return false; 2912 break; 2913 } 2914 2915 // "St" -- the "std" namespace. The grammar is ambiguous here, 2916 // since we could parse that as <substitution> or as 2917 // <class-enum-type>. We assume the latter and fall through. 2918 2919 default: 2920 { 2921 // <class-enum-type> ::= <name> 2922 Node* nameNode; 2923 return _ParseName(nameNode) 2924 && NodeCreator<NamedTypeNode>(this)(nameNode, _node); 2925 } 2926 } 2927 2928 // We get here for the types that might be a <template-template-param>. 2929 // Check whether <template-args> are following. 2930 if (!fInput.HasPrefix('I')) 2931 return true; 2932 2933 // <template-template-param> is referenceable 2934 _RegisterReferenceableNode(_node); 2935 2936 return _ParseTemplateArgs(_node, _node); 2937 } 2938 2939 2940 void 2941 Demangler::_ParseCVQualifiers(int& qualifiers) 2942 { 2943 qualifiers = 0; 2944 2945 if (fInput.SkipPrefix('r')) 2946 qualifiers |= CV_QUALIFIER_RESTRICT; 2947 if (fInput.SkipPrefix('V')) 2948 qualifiers |= CV_QUALIFIER_VOLATILE; 2949 if (fInput.SkipPrefix('K')) 2950 qualifiers |= CV_QUALIFIER_CONST; 2951 } 2952 2953 2954 bool 2955 Demangler::_ParseTypeWithModifier(type_modifier modifier, int toSkip, 2956 Node*& _node) 2957 { 2958 if (toSkip > 0) 2959 fInput.Skip(toSkip); 2960 2961 Node* node; 2962 if (!_ParseType(node)) 2963 return false; 2964 2965 return NodeCreator<TypeModifierNode>(this)(modifier, node, _node); 2966 } 2967 2968 2969 bool 2970 Demangler::_TryParseBuiltinType(Node*& _node) 2971 { 2972 DEBUG_SCOPE("_TryParseBuiltinType"); 2973 2974 // <builtin-type> ::= v # void 2975 // ::= w # wchar_t 2976 // ::= b # bool 2977 // ::= c # char 2978 // ::= a # signed char 2979 // ::= h # unsigned char 2980 // ::= s # short 2981 // ::= t # unsigned short 2982 // ::= i # int 2983 // ::= j # unsigned int 2984 // ::= l # long 2985 // ::= m # unsigned long 2986 // ::= x # long long, __int64 2987 // ::= y # unsigned long long, __int64 2988 // ::= n # __int128 2989 // ::= o # unsigned __int128 2990 // ::= f # float 2991 // ::= d # double 2992 // ::= e # long double, __float80 2993 // ::= g # __float128 2994 // ::= z # ellipsis 2995 // ::= Dd # IEEE 754r decimal floating point (64 bits) 2996 // ::= De # IEEE 754r decimal floating point (128 bits) 2997 // ::= Df # IEEE 754r decimal floating point (32 bits) 2998 // ::= Dh # IEEE 754r half-precision floating point 2999 // # (16 bits) 3000 // ::= Di # char32_t 3001 // ::= Ds # char16_t 3002 // ::= u <source-name> # vendor extended type 3003 3004 if (fInput.CharsRemaining() == 0) 3005 return false; 3006 3007 switch (fInput[0]) { 3008 case 'v': 3009 return _CreateTypeNodeAndSkip(TYPE_VOID, 1, _node); 3010 case 'w': 3011 return _CreateTypeNodeAndSkip(TYPE_WCHAR_T, 1, _node); 3012 case 'b': 3013 return _CreateTypeNodeAndSkip(TYPE_BOOL, 1, _node); 3014 case 'c': 3015 return _CreateTypeNodeAndSkip(TYPE_CHAR, 1, _node); 3016 case 'a': 3017 return _CreateTypeNodeAndSkip(TYPE_SIGNED_CHAR, 1, _node); 3018 case 'h': 3019 return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_CHAR, 1, _node); 3020 case 's': 3021 return _CreateTypeNodeAndSkip(TYPE_SHORT, 1, _node); 3022 case 't': 3023 return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_SHORT, 1, 3024 _node); 3025 case 'i': 3026 return _CreateTypeNodeAndSkip(TYPE_INT, 1, _node); 3027 case 'j': 3028 return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_INT, 1, _node); 3029 case 'l': 3030 return _CreateTypeNodeAndSkip(TYPE_LONG, 1, _node); 3031 case 'm': 3032 return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_LONG, 1, _node); 3033 case 'x': 3034 return _CreateTypeNodeAndSkip(TYPE_LONG_LONG, 1, _node); 3035 case 'y': 3036 return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_LONG_LONG, 1, _node); 3037 case 'n': 3038 return _CreateTypeNodeAndSkip(TYPE_INT128, 1, _node); 3039 case 'o': 3040 return _CreateTypeNodeAndSkip(TYPE_UNSIGNED_INT128, 1, _node); 3041 case 'f': 3042 return _CreateTypeNodeAndSkip(TYPE_FLOAT, 1, _node); 3043 case 'd': 3044 return _CreateTypeNodeAndSkip(TYPE_DOUBLE, 1, _node); 3045 case 'e': 3046 return _CreateTypeNodeAndSkip(TYPE_LONG_DOUBLE, 1, _node); 3047 case 'g': 3048 return _CreateTypeNodeAndSkip(TYPE_FLOAT128, 1, _node); 3049 case 'z': 3050 return _CreateTypeNodeAndSkip(TYPE_ELLIPSIS, 1, _node); 3051 3052 case 'D': 3053 if (fInput.CharsRemaining() < 2) 3054 return false; 3055 3056 // TODO: Official names for the __dfloat*! 3057 switch (fInput[1]) { 3058 case 'd': 3059 return _CreateTypeNodeAndSkip(TYPE_DFLOAT64, 2, _node); 3060 case 'e': 3061 return _CreateTypeNodeAndSkip(TYPE_DFLOAT128, 2, _node); 3062 case 'f': 3063 return _CreateTypeNodeAndSkip(TYPE_DFLOAT32, 2, _node); 3064 case 'h': 3065 return _CreateTypeNodeAndSkip(TYPE_DFLOAT16, 2, _node); 3066 case 'i': 3067 return _CreateTypeNodeAndSkip(TYPE_CHAR16_T, 2, _node); 3068 case 's': 3069 return _CreateTypeNodeAndSkip(TYPE_CHAR32_T, 2, _node); 3070 default: 3071 return false; 3072 } 3073 3074 case 'u': 3075 { 3076 fInput.Skip(1); 3077 Node* nameNode; 3078 return _ParseSourceName(nameNode) 3079 && NodeCreator<NamedTypeNode>(this)(nameNode, _node); 3080 } 3081 3082 default: 3083 return false; 3084 } 3085 } 3086 3087 3088 bool 3089 Demangler::_ParseFunctionType(FunctionNode*& _node) 3090 { 3091 DEBUG_SCOPE("_ParseFunctionType"); 3092 3093 // <function-type> ::= F [Y] <bare-function-type> E 3094 3095 if (!_SkipExpected('F')) 3096 return false; 3097 3098 // is 'extern "C"'? 3099 bool isExternC = fInput.SkipPrefix('Y'); 3100 3101 // create function and parse function type 3102 if (!NodeCreator<FunctionNode>(this)((Node*)NULL, true, isExternC, 3103 _node) 3104 || !_ParseBareFunctionType(_node)) { 3105 return false; 3106 } 3107 3108 // skip terminating 'E' 3109 return _SkipExpected('E'); 3110 } 3111 3112 3113 bool 3114 Demangler::_ParseArrayType(Node*& _node) 3115 { 3116 DEBUG_SCOPE("_ParseArrayType"); 3117 3118 // <array-type> ::= A <positive dimension number> _ <element type> 3119 // ::= A [<dimension expression>] _ <element type> 3120 3121 if (fInput.CharsRemaining() < 2 || !fInput.SkipPrefix('A')) 3122 return _SetError(ERROR_INVALID); 3123 3124 number_type dimensionNumber; 3125 Node* dimensionExpression = NULL; 3126 3127 // If it looks like a number, it must be the first production, otherwise 3128 // the second one. 3129 if (isdigit(fInput[0]) 3130 || (fInput[0] == 'n' && fInput.CharsRemaining() >= 2 3131 && isdigit(fInput[1]))) { 3132 if (!_ParseNumber(dimensionNumber)) 3133 return false; 3134 } else { 3135 if (!_ParseExpression(dimensionExpression)) 3136 return false; 3137 } 3138 3139 // parse the type 3140 Node* type; 3141 if (!_SkipExpected('_') || !_ParseType(type)) 3142 return false; 3143 3144 // create the array node 3145 return dimensionExpression != NULL 3146 ? NodeCreator<ArrayNode>(this)(type, dimensionExpression, _node) 3147 : NodeCreator<ArrayNode>(this)(type, dimensionNumber, _node); 3148 } 3149 3150 3151 bool 3152 Demangler::_ParsePointerToMemberType(Node*& _node) 3153 { 3154 DEBUG_SCOPE("_ParsePointerToMemberType"); 3155 3156 // <pointer-to-member-type> ::= M <class type> <member type> 3157 Node* classType; 3158 Node* memberType; 3159 return _SkipExpected('M') 3160 && _ParseType(classType) 3161 && _ParseType(memberType) 3162 && NodeCreator<PointerToMemberNode>(this)(classType, memberType, 3163 _node); 3164 } 3165 3166 3167 bool 3168 Demangler::_ParseTemplateParam(Node*& _node) 3169 { 3170 DEBUG_SCOPE("_ParseTemplateParam"); 3171 3172 // <template-param> ::= T_ # first template parameter 3173 // ::= T <parameter-2 non-negative number> _ 3174 3175 if (!_SkipExpected('T')) 3176 return false; 3177 if (fTemplatizedNode == NULL) 3178 return _SetError(ERROR_INVALID); 3179 3180 // get the index; 3181 number_type index = 0; 3182 if (!fInput.HasPrefix('_')) { 3183 if (!_ParseNumber(index)) 3184 return false; 3185 3186 if (index < 0) 3187 return _SetError(ERROR_INVALID); 3188 index++; 3189 } 3190 3191 if (!_SkipExpected('_')) 3192 return false; 3193 3194 // get the parameter 3195 Node* parameter = fTemplatizedNode->TemplateParameterAt(index); 3196 if (parameter == NULL) 3197 return _SetError(ERROR_INVALID); 3198 3199 // create a substitution node 3200 return NodeCreator<SubstitutionNode>(this)(parameter, _node); 3201 } 3202 3203 3204 bool 3205 Demangler::_ParseSubstitution(Node*& _node) 3206 { 3207 DEBUG_SCOPE("_ParseSubstitution"); 3208 3209 if (!_ParseSubstitutionInternal(_node)) 3210 return false; 3211 3212 // substitutions are never referenceable 3213 _node->SetReferenceable(false); 3214 3215 return true; 3216 } 3217 3218 3219 bool 3220 Demangler::_ParseSubstitutionInternal(Node*& _node) 3221 { 3222 DEBUG_SCOPE("_ParseSubstitutionInternal"); 3223 3224 // <substitution> ::= S <seq-id> _ 3225 // ::= S_ 3226 // 3227 // <substitution> ::= St # ::std:: 3228 // <substitution> ::= Sa # ::std::allocator 3229 // <substitution> ::= Sb # ::std::basic_string 3230 // <substitution> ::= Ss # ::std::basic_string < char, 3231 // ::std::char_traits<char>, 3232 // ::std::allocator<char> > 3233 // <substitution> ::= Si # ::std::basic_istream<char, 3234 // std::char_traits<char> > 3235 // <substitution> ::= So # ::std::basic_ostream<char, 3236 // std::char_traits<char> > 3237 // <substitution> ::= Sd # ::std::basic_iostream<char, 3238 // std::char_traits<char> > 3239 3240 if (fInput.CharsRemaining() < 2 || !fInput.SkipPrefix('S')) 3241 return _SetError(ERROR_INVALID); 3242 3243 switch (fInput[0]) { 3244 case 't': 3245 return _CreateNodeAndSkip("std", 1, _node); 3246 case 'a': 3247 return _CreateTypeNodeAndSkip("allocator", "std", NULL, 1, 3248 _node); 3249 case 'b': 3250 return _CreateTypeNodeAndSkip("basic_string", "std", NULL, 1, 3251 _node); 3252 case 's': 3253 return _CreateTypeNodeAndSkip("basic_string", "std", 3254 "char, std::char_traits<char>, std::allocator<char>", 1, 3255 _node); 3256 case 'i': 3257 return _CreateTypeNodeAndSkip("basic_istream", "std", 3258 "char, std::char_traits<char>", 1, _node); 3259 case 'o': 3260 return _CreateTypeNodeAndSkip("basic_ostream", "std", 3261 "char, std::char_traits<char>", 1, _node); 3262 case 'd': 3263 return _CreateTypeNodeAndSkip("basic_iostream", "std", 3264 "char, std::char_traits<char>", 1, _node); 3265 case '_': 3266 fInput.Skip(1); 3267 return _CreateSubstitutionNode(0, _node); 3268 } 3269 3270 // parse <seq-id> 3271 int seqID = 0; 3272 int count = fInput.CharsRemaining(); 3273 int i = 0; 3274 for (; i < count && fInput[i] != '_'; i++) { 3275 char c = fInput[i]; 3276 if (isdigit(c)) 3277 seqID = seqID * 36 + (c - '0'); 3278 else if (c >= 'A' && c <= 'Z') 3279 seqID = seqID * 36 + 10 + (c - 'A'); 3280 else 3281 return _SetError(ERROR_INVALID); 3282 } 3283 3284 if (i == count) 3285 return _SetError(ERROR_INVALID); 3286 3287 // skip digits and '_' 3288 fInput.Skip(i + 1); 3289 3290 return _CreateSubstitutionNode(seqID + 1, _node); 3291 } 3292 3293 3294 bool 3295 Demangler::_ParseBareFunctionType(FunctionNode* node) 3296 { 3297 DEBUG_SCOPE("_ParseBareFunctionType"); 3298 3299 // <bare-function-type> ::= <signature type>+ 3300 // # types are possible return type, then parameter types 3301 3302 if (fInput.CharsRemaining() == 0) 3303 return _SetError(ERROR_INVALID); 3304 3305 do { 3306 Node* typeNode; 3307 if (!_ParseType(typeNode)) 3308 return false; 3309 3310 node->AddType(typeNode); 3311 } while (fInput.CharsRemaining() > 0 && fInput[0] != 'E' 3312 && fInput[0] != '.'); 3313 // 'E' und '.' delimit <function-type> 3314 3315 return true; 3316 } 3317 3318 3319 bool 3320 Demangler::_ParseTemplateArgs(Node* node, Node*& _node) 3321 { 3322 DEBUG_SCOPE("_ParseTemplateArgs"); 3323 3324 // <template-args> ::= I <template-arg>+ E 3325 3326 if (!_SkipExpected('I')) 3327 return false; 3328 3329 // we need at least one <template-arg> 3330 if (fInput.CharsRemaining() == 0 || fInput[0] == 'E') 3331 return _SetError(ERROR_INVALID); 3332 3333 // create the node 3334 TemplateNode* templateNode; 3335 if (!NodeCreator<TemplateNode>(this)(node, templateNode)) 3336 return false; 3337 _node = templateNode; 3338 3339 // parse the args 3340 while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') { 3341 Node* arg; 3342 if (!_ParseTemplateArg(arg)) 3343 return false; 3344 templateNode->AddArgument(arg); 3345 } 3346 3347 // skip the trailing 'E' 3348 return _SkipExpected('E'); 3349 } 3350 3351 3352 bool 3353 Demangler::_ParseTemplateArg(Node*& _node) 3354 { 3355 DEBUG_SCOPE("_ParseTemplateArg"); 3356 3357 // <template-arg> ::= <type> # type or template 3358 // ::= X <expression> E # expression 3359 // ::= <expr-primary> # simple expressions 3360 // ::= I <template-arg>* E # argument pack 3361 // ::= sp <expression> # pack expansion of (C++0x) 3362 3363 if (fInput.CharsRemaining() == 0) 3364 return _SetError(ERROR_INVALID); 3365 3366 switch (fInput[0]) { 3367 case 'X': // X <expression> E 3368 fInput.Skip(1); 3369 return _ParseExpression(_node) && _SkipExpected('E'); 3370 3371 case 'L': // <expr-primary> 3372 return _ParseExpressionPrimary(_node); 3373 3374 case 'I': // I <template-arg>* E 3375 { 3376 #if 0 3377 fInput.Skip(1); 3378 3379 while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') { 3380 Node* arg; 3381 if (!_ParseTemplateArg(arg)) 3382 return false; 3383 } 3384 3385 if (!fInput.SkipPrefix('E')) 3386 return _SetError(ERROR_INVALID); 3387 return true; 3388 #endif 3389 // NOTE: Unsupported by the GNU demangler. 3390 return _SetError(ERROR_UNSUPPORTED); 3391 } 3392 3393 case 's': 3394 if (fInput.SkipPrefix("sp")) { 3395 // sp <expression> 3396 #if 0 3397 return _ParseExpression(_node); 3398 #endif 3399 // NOTE: Unsupported by the GNU demangler. 3400 return _SetError(ERROR_UNSUPPORTED); 3401 } 3402 3403 // fall through... 3404 3405 default: // <type> 3406 return _ParseType(_node); 3407 } 3408 } 3409 3410 3411 bool 3412 Demangler::_ParseExpression(Node*& _node) 3413 { 3414 DEBUG_SCOPE("_ParseExpression"); 3415 3416 // <expression> ::= <unary operator-name> <expression> 3417 // ::= <binary operator-name> <expression> <expression> 3418 // ::= <trinary operator-name> <expression> <expression> 3419 // <expression> 3420 // ::= cl <expression>* E # call 3421 // ::= cv <type> expression # conversion with one 3422 // argument 3423 // ::= cv <type> _ <expression>* E # conversion with a 3424 // different number of 3425 // arguments 3426 // ::= st <type> # sizeof (a type) 3427 // ::= at <type> # alignof (a type) 3428 // ::= <template-param> 3429 // ::= <function-param> 3430 // ::= sr <type> <unqualified-name> 3431 // # dependent name 3432 // ::= sr <type> <unqualified-name> <template-args> 3433 // # dependent template-id 3434 // ::= sZ <template-param> 3435 // # size of a parameter pack 3436 // ::= <expr-primary> 3437 // 3438 // <expr-primary> ::= L <type> <value number> E # integer literal 3439 // ::= L <type <value float> E # floating literal 3440 // ::= L <mangled-name> E # external name 3441 3442 if (fInput.CharsRemaining() == 0) 3443 return _SetError(ERROR_INVALID); 3444 3445 switch (fInput[0]) { 3446 case 'L': 3447 return _ParseExpressionPrimary(_node); 3448 case 'T': 3449 return _ParseTemplateParam(_node); 3450 // NOTE: <function-param> is not defined in the specs! 3451 } 3452 3453 // must be an operator 3454 if (fInput.CharsRemaining() < 2) 3455 return _SetError(ERROR_INVALID); 3456 3457 // some operators need special handling 3458 3459 if (fInput.SkipPrefix("cl")) { 3460 // cl <expression>* E # call 3461 CallNode* callNode; 3462 if (!NodeCreator<CallNode>(this)(callNode)) 3463 return false; 3464 3465 while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') { 3466 Node* subExpression; 3467 if (!_ParseExpression(subExpression)) 3468 return false; 3469 callNode->AddSubExpression(subExpression); 3470 } 3471 3472 _node = callNode; 3473 return _SkipExpected('E'); 3474 } 3475 3476 if (fInput.SkipPrefix("cv")) { 3477 // cv <type> expression # conversion with one argument 3478 // cv <type> _ <expression>* E # conversion with a different number 3479 // of arguments 3480 3481 // parse the type 3482 Node* type; 3483 if (!_ParseType(type)) 3484 return false; 3485 3486 // create a conversion expression node 3487 ConversionExpressionNode* expression; 3488 if (!NodeCreator<ConversionExpressionNode>(this)(type, expression)) 3489 return false; 3490 _node = expression; 3491 3492 if (fInput.SkipPrefix('_')) { 3493 // multi argument conversion 3494 while (fInput.CharsRemaining() > 0 && fInput[0] != 'E') { 3495 Node* subExpression; 3496 if (!_ParseExpression(subExpression)) 3497 return false; 3498 expression->AddSubExpression(subExpression); 3499 } 3500 3501 return _SkipExpected('E'); 3502 } 3503 3504 // single argument conversion 3505 Node* subExpression; 3506 if (!_ParseExpression(subExpression)) 3507 return false; 3508 expression->AddSubExpression(subExpression); 3509 3510 return true; 3511 } 3512 3513 if (fInput.SkipPrefix("sr")) { 3514 // sr <type> <unqualified-name> 3515 // sr <type> <unqualified-name> <template-args> 3516 3517 // parse type and unqualified name and create the node 3518 Node* type; 3519 Node* name; 3520 if (!_ParseType(type) || !_ParseUnqualifiedName(name) 3521 || !NodeCreator<DependentNameNode>(this)(type, name, _node)) { 3522 return false; 3523 } 3524 3525 // If there are template arguments left, add them. 3526 if (!fInput.HasPrefix('I')) 3527 return true; 3528 3529 return _ParseTemplateArgs(_node, _node); 3530 } 3531 3532 if (fInput.SkipPrefix("sZ")) { 3533 // sZ <template-param> 3534 3535 // NOTE: Unsupported by the GNU demangler. 3536 return _SetError(ERROR_UNSUPPORTED); 3537 } 3538 3539 // no special operator, so have a look for the others 3540 3541 const operator_info* info = NULL; 3542 for (int i = 0; kOperatorInfos[i].name != NULL; i++) { 3543 if (fInput.SkipPrefix(kOperatorInfos[i].mangled_name)) { 3544 info = &kOperatorInfos[i]; 3545 break; 3546 } 3547 } 3548 3549 // We can only deal with operators with a fixed argument count at this 3550 // point. 3551 if (info == NULL || info->argument_count < 0) 3552 return _SetError(ERROR_INVALID); 3553 3554 // create an operator node 3555 OperatorExpressionNode* operatorNode; 3556 if (!NodeCreator<OperatorExpressionNode>(this)(info, operatorNode)) 3557 return false; 3558 3559 // parse the arguments 3560 int i = 0; 3561 3562 // the first one might be a type 3563 if ((info->flags & OPERATOR_TYPE_PARAM) != 0) { 3564 Node* type; 3565 if (!_ParseType(type)) 3566 return false; 3567 3568 operatorNode->AddSubExpression(type); 3569 i++; 3570 } 3571 3572 // the others are expressions 3573 for (; i < info->argument_count; i++) { 3574 Node* subExpression; 3575 if (!_ParseExpression(subExpression)) 3576 return false; 3577 operatorNode->AddSubExpression(subExpression); 3578 } 3579 3580 _node = operatorNode; 3581 return true; 3582 } 3583 3584 3585 bool 3586 Demangler::_ParseExpressionPrimary(Node*& _node) 3587 { 3588 DEBUG_SCOPE("_ParseExpressionPrimary"); 3589 3590 // <expr-primary> ::= L <type> <value number> E # integer literal 3591 // ::= L <type <value float> E # floating literal 3592 // ::= L <mangled-name> E # external name 3593 3594 if (!_SkipExpected('L')) 3595 return false; 3596 3597 if (fInput.SkipPrefix("_Z")) { 3598 ObjectNode* node; 3599 if (!_ParseEncoding(node)) 3600 return false; 3601 _node = node; 3602 } else { 3603 // number or float literal 3604 Node* type; 3605 if (!_ParseType(type)) 3606 return false; 3607 3608 // GNU's demangler doesn't really seem to parse the integer/float, 3609 // but only replaces a leading 'n' by '-'. Good enough for us, too. 3610 3611 // determine the length 3612 int maxLength = fInput.CharsRemaining(); 3613 int length = 0; 3614 while (length < maxLength && fInput[length] != 'E') 3615 length++; 3616 3617 if (length == 0) 3618 return _SetError(ERROR_INVALID); 3619 3620 if (!NodeCreator<TypedNumberLiteralNode>(this)(type, 3621 fInput.String(), length, _node)) { 3622 return false; 3623 } 3624 3625 fInput.Skip(length); 3626 } 3627 3628 return _SkipExpected('E'); 3629 } 3630 3631 3632 bool 3633 Demangler::_ParseNumber(number_type& number) 3634 { 3635 DEBUG_SCOPE("_ParseNumber"); 3636 3637 bool negative = fInput.SkipPrefix('n'); 3638 3639 if (fInput.CharsRemaining() == 0) 3640 return _SetError(ERROR_INVALID); 3641 3642 number = 0; 3643 int count = fInput.CharsRemaining(); 3644 int i = 0; 3645 for (; i < count && isdigit(fInput[i]); i++) 3646 number = number * 10 + (fInput[i] - '0'); 3647 3648 fInput.Skip(i); 3649 3650 if (negative) 3651 number =-number; 3652 return true; 3653 } 3654 3655 3656 bool 3657 Demangler::_CreateNodeAndSkip(const char* name, size_t length, int toSkip, 3658 Node*& _node) 3659 { 3660 if (toSkip > 0) 3661 fInput.Skip(toSkip); 3662 3663 return NodeCreator<SimpleNameNode>(this)(name, length, _node); 3664 } 3665 3666 3667 bool 3668 Demangler::_CreateNodeAndSkip(const char* name, int toSkip, Node*& _node) 3669 { 3670 return _CreateNodeAndSkip(name, strlen(name), toSkip, _node); 3671 } 3672 3673 3674 bool 3675 Demangler::_CreateTypeNodeAndSkip(type_type type, int toSkip, Node*& _node) 3676 { 3677 if (toSkip > 0) 3678 fInput.Skip(toSkip); 3679 3680 return NodeCreator<SimpleTypeNode>(this)(type, _node); 3681 } 3682 3683 3684 bool 3685 Demangler::_CreateTypeNodeAndSkip(const char* name, const char* prefix, 3686 const char* templateArgs, int toSkip, Node*& _node) 3687 { 3688 if (toSkip > 0) 3689 fInput.Skip(toSkip); 3690 3691 // create the name node 3692 if (!NodeCreator<SimpleTypeNode>(this)(name, _node)) 3693 return false; 3694 3695 // add the prefix 3696 if (prefix != NULL) { 3697 Node* prefixNode; 3698 if (!NodeCreator<SimpleTypeNode>(this)(prefix, prefixNode) 3699 || !NodeCreator<PrefixedNode>(this)(prefixNode, _node, _node)) { 3700 return false; 3701 } 3702 } 3703 3704 // wrap the node to add the template args 3705 if (templateArgs != NULL) { 3706 TemplateNode* templateNode; 3707 Node* argsNode; 3708 if (!NodeCreator<TemplateNode>(this)(_node, templateNode) 3709 || !NodeCreator<SimpleTypeNode>(this)(templateArgs, argsNode)) { 3710 return false; 3711 } 3712 templateNode->AddArgument(argsNode); 3713 _node = templateNode; 3714 } 3715 3716 return true; 3717 } 3718 3719 3720 void 3721 Demangler::_RegisterReferenceableNode(Node* node) 3722 { 3723 // check, if not referenceable or already registered 3724 if (!node->IsReferenceable() || node == fLastReferenceableNode 3725 || node->NextReferenceable() != NULL) { 3726 return; 3727 } 3728 3729 if (fFirstReferenceableNode == NULL) { 3730 fFirstReferenceableNode = node; 3731 fLastReferenceableNode = node; 3732 } else { 3733 fLastReferenceableNode->SetNextReferenceable(node); 3734 fLastReferenceableNode = node; 3735 } 3736 } 3737 3738 3739 bool 3740 Demangler::_CreateSubstitutionNode(int index, Node*& _node) 3741 { 3742 Node* node = fFirstReferenceableNode; 3743 while (node != NULL && index > 0) { 3744 node = node->NextReferenceable(); 3745 index--; 3746 } 3747 3748 if (node == NULL) 3749 return _SetError(ERROR_INVALID); 3750 3751 // create a substitution node 3752 return NodeCreator<SubstitutionNode>(this)(node, _node); 3753 } 3754 3755 3756 // #pragma mark - 3757 3758 3759 const char* 3760 demangle_symbol_gcc3(const char* mangledName, char* buffer, size_t bufferSize, 3761 bool* _isObjectMethod) 3762 { 3763 bool isObjectMethod; 3764 if (_isObjectMethod == NULL) 3765 _isObjectMethod = &isObjectMethod; 3766 3767 Demangler demangler; 3768 DemanglingInfo info(true); 3769 if (demangler.Demangle(mangledName, buffer, bufferSize, info) != ERROR_OK) 3770 return NULL; 3771 3772 // Set the object method return value. Unless we know for sure that it isn't 3773 // an object method, we assume that it is. 3774 switch (info.objectType) { 3775 case OBJECT_TYPE_DATA: 3776 case OBJECT_TYPE_FUNCTION: 3777 case OBJECT_TYPE_METHOD_CLASS: 3778 *_isObjectMethod = false; 3779 break; 3780 case OBJECT_TYPE_METHOD_OBJECT: 3781 *_isObjectMethod = true; 3782 break; 3783 case OBJECT_TYPE_UNKNOWN: 3784 case OBJECT_TYPE_METHOD_UNKNOWN: 3785 *_isObjectMethod = strstr(buffer, "::") != NULL; 3786 break; 3787 } 3788 3789 return buffer; 3790 } 3791 3792 3793 status_t 3794 get_next_argument_gcc3(uint32* _cookie, const char* mangledName, char* name, 3795 size_t nameSize, int32* _type, size_t* _argumentLength) 3796 { 3797 Demangler demangler; 3798 ParameterInfo info; 3799 int result = demangler.GetParameterInfo(mangledName, *_cookie, name, 3800 nameSize, info); 3801 if (result != ERROR_OK) { 3802 switch (result) { 3803 case ERROR_NOT_MANGLED: 3804 return B_BAD_VALUE; 3805 case ERROR_UNSUPPORTED: 3806 return B_BAD_VALUE; 3807 case ERROR_INVALID: 3808 return B_BAD_VALUE; 3809 case ERROR_BUFFER_TOO_SMALL: 3810 return B_BUFFER_OVERFLOW; 3811 case ERROR_NO_MEMORY: 3812 return B_NO_MEMORY; 3813 case ERROR_INVALID_PARAMETER_INDEX: 3814 return B_BAD_INDEX; 3815 case ERROR_INTERNAL: 3816 default: 3817 return B_ERROR; 3818 } 3819 } 3820 3821 // translate the type 3822 switch (info.type.type) { 3823 case TYPE_BOOL: 3824 *_type = B_BOOL_TYPE; 3825 *_argumentLength = 1; 3826 break; 3827 3828 case TYPE_CHAR: 3829 *_type = B_CHAR_TYPE; 3830 *_argumentLength = 1; 3831 break; 3832 3833 case TYPE_SIGNED_CHAR: 3834 *_type = B_INT8_TYPE; 3835 *_argumentLength = 1; 3836 break; 3837 case TYPE_UNSIGNED_CHAR: 3838 *_type = B_UINT8_TYPE; 3839 *_argumentLength = 1; 3840 break; 3841 3842 case TYPE_SHORT: 3843 *_type = B_INT16_TYPE; 3844 *_argumentLength = 2; 3845 break; 3846 case TYPE_UNSIGNED_SHORT: 3847 *_type = B_UINT16_TYPE; 3848 *_argumentLength = 2; 3849 break; 3850 3851 case TYPE_INT: 3852 *_type = B_INT32_TYPE; 3853 *_argumentLength = 4; 3854 break; 3855 case TYPE_UNSIGNED_INT: 3856 *_type = B_UINT32_TYPE; 3857 *_argumentLength = 4; 3858 break; 3859 3860 case TYPE_LONG: 3861 *_type = sizeof(long) == 4 ? B_INT32_TYPE : B_INT64_TYPE; 3862 *_argumentLength = sizeof(long); 3863 break; 3864 case TYPE_UNSIGNED_LONG: 3865 *_type = sizeof(long) == 4 ? B_UINT32_TYPE : B_UINT64_TYPE; 3866 *_argumentLength = sizeof(long); 3867 break; 3868 3869 case TYPE_LONG_LONG: 3870 *_type = B_INT64_TYPE; 3871 *_argumentLength = 8; 3872 break; 3873 case TYPE_UNSIGNED_LONG_LONG: 3874 *_type = B_INT64_TYPE; 3875 *_argumentLength = 8; 3876 break; 3877 3878 case TYPE_INT128: 3879 *_type = 0; 3880 *_argumentLength = 16; 3881 break; 3882 case TYPE_UNSIGNED_INT128: 3883 *_type = 0; 3884 *_argumentLength = 16; 3885 break; 3886 3887 case TYPE_FLOAT: 3888 *_type = B_FLOAT_TYPE; 3889 *_argumentLength = sizeof(float); 3890 break; 3891 case TYPE_DOUBLE: 3892 *_type = B_DOUBLE_TYPE; 3893 *_argumentLength = sizeof(double); 3894 break; 3895 3896 case TYPE_LONG_DOUBLE: 3897 *_type = 0; 3898 *_argumentLength = sizeof(long double); 3899 break; 3900 3901 case TYPE_FLOAT128: 3902 *_type = 0; 3903 *_argumentLength = 16; 3904 break; 3905 3906 case TYPE_DFLOAT16: 3907 *_argumentLength = 2; 3908 case TYPE_DFLOAT32: 3909 *_argumentLength *= 2; 3910 case TYPE_DFLOAT64: 3911 *_argumentLength *= 2; 3912 case TYPE_DFLOAT128: 3913 *_argumentLength *= 2; 3914 *_type = 0; 3915 break; 3916 3917 case TYPE_CHAR16_T: 3918 *_type = B_UINT16_TYPE; 3919 *_argumentLength = 2; 3920 break; 3921 3922 case TYPE_CHAR32_T: 3923 *_type = B_UINT32_TYPE; 3924 *_argumentLength = 2; 3925 break; 3926 3927 case TYPE_CONST_CHAR_POINTER: 3928 *_type = B_STRING_TYPE; 3929 *_argumentLength = sizeof(void*); 3930 break; 3931 3932 case TYPE_POINTER: 3933 *_type = B_POINTER_TYPE; 3934 *_argumentLength = sizeof(void*); 3935 break; 3936 3937 case TYPE_REFERENCE: 3938 *_type = B_REF_TYPE; 3939 // TODO: That's actually entry_ref! 3940 *_argumentLength = sizeof(void*); 3941 break; 3942 3943 case TYPE_WCHAR_T: 3944 // TODO: Type/size might change! 3945 *_type = B_UINT16_TYPE; 3946 *_argumentLength = 2; 3947 break; 3948 3949 case TYPE_UNKNOWN: 3950 case TYPE_ELLIPSIS: 3951 case TYPE_VOID: 3952 default: 3953 // Well, tell our caller *something*. 3954 *_type = 0; 3955 *_argumentLength = sizeof(int); 3956 } 3957 3958 // assume sizeof(int) argument alignment 3959 if (*_argumentLength < sizeof(int)) 3960 *_argumentLength = sizeof(int); 3961 3962 ++*_cookie; 3963 return B_OK; 3964 } 3965 3966 3967 #ifndef _KERNEL_MODE 3968 3969 const char* 3970 demangle_name_gcc3(const char* mangledName, char* buffer, size_t bufferSize) 3971 { 3972 3973 Demangler demangler; 3974 DemanglingInfo info(false); 3975 if (demangler.Demangle(mangledName, buffer, bufferSize, info) != ERROR_OK) 3976 return NULL; 3977 return buffer; 3978 } 3979 3980 #endif 3981