|
22 | 22 | #include "swift/Demangling/Errors.h"
|
23 | 23 | #include "swift/Demangling/ManglingFlavor.h"
|
24 | 24 | #include "swift/Demangling/NamespaceMacros.h"
|
| 25 | +#include "swift/Strings.h" |
25 | 26 | #include "llvm/ADT/StringRef.h"
|
26 | 27 | #include "llvm/Support/Compiler.h"
|
27 | 28 |
|
@@ -818,6 +819,136 @@ std::string mangledNameForTypeMetadataAccessor(
|
818 | 819 | llvm::StringRef moduleName, llvm::StringRef typeName, Node::Kind typeKind,
|
819 | 820 | Mangle::ManglingFlavor Flavor = Mangle::ManglingFlavor::Default);
|
820 | 821 |
|
| 822 | +class NodePrinter { |
| 823 | +private: |
| 824 | + DemanglerPrinter Printer; |
| 825 | + DemangleOptions Options; |
| 826 | + bool SpecializationPrefixPrinted = false; |
| 827 | + bool isValid = true; |
| 828 | + |
| 829 | +public: |
| 830 | + NodePrinter(DemangleOptions options) : Options(options) {} |
| 831 | + |
| 832 | + std::string printRoot(NodePointer root) { |
| 833 | + isValid = true; |
| 834 | + print(root, 0); |
| 835 | + if (isValid) |
| 836 | + return std::move(Printer).str(); |
| 837 | + return ""; |
| 838 | + } |
| 839 | + |
| 840 | +private: |
| 841 | + static const unsigned MaxDepth = 768; |
| 842 | + |
| 843 | + /// Called when the node tree in valid. |
| 844 | + /// |
| 845 | + /// The demangler already catches most error cases and mostly produces valid |
| 846 | + /// node trees. But some cases are difficult to catch in the demangler and |
| 847 | + /// instead the NodePrinter bails. |
| 848 | + void setInvalid() { isValid = false; } |
| 849 | + |
| 850 | + void printChildren(Node::iterator begin, Node::iterator end, unsigned depth, |
| 851 | + const char *sep = nullptr); |
| 852 | + |
| 853 | + void printChildren(NodePointer Node, unsigned depth, |
| 854 | + const char *sep = nullptr); |
| 855 | + |
| 856 | + NodePointer getFirstChildOfKind(NodePointer Node, Node::Kind kind); |
| 857 | + |
| 858 | + void printBoundGenericNoSugar(NodePointer Node, unsigned depth); |
| 859 | + |
| 860 | + void printOptionalIndex(NodePointer node); |
| 861 | + |
| 862 | + static bool isSwiftModule(NodePointer node) { |
| 863 | + return (node->getKind() == Node::Kind::Module && |
| 864 | + node->getText() == STDLIB_NAME); |
| 865 | + } |
| 866 | + |
| 867 | + bool printContext(NodePointer Context); |
| 868 | + |
| 869 | + static bool isIdentifier(NodePointer node, StringRef desired) { |
| 870 | + return (node->getKind() == Node::Kind::Identifier && |
| 871 | + node->getText() == desired); |
| 872 | + } |
| 873 | + |
| 874 | + enum class SugarType { |
| 875 | + None, |
| 876 | + Optional, |
| 877 | + ImplicitlyUnwrappedOptional, |
| 878 | + Array, |
| 879 | + Dictionary |
| 880 | + }; |
| 881 | + |
| 882 | + enum class TypePrinting { NoType, WithColon, FunctionStyle }; |
| 883 | + |
| 884 | + /// Determine whether this is a "simple" type, from the type-simple |
| 885 | + /// production. |
| 886 | + bool isSimpleType(NodePointer Node); |
| 887 | + |
| 888 | + void printWithParens(NodePointer type, unsigned depth); |
| 889 | + |
| 890 | + SugarType findSugar(NodePointer Node); |
| 891 | + |
| 892 | + void printBoundGeneric(NodePointer Node, unsigned depth); |
| 893 | + |
| 894 | + NodePointer getChildIf(NodePointer Node, Node::Kind Kind); |
| 895 | + |
| 896 | + void printFunctionParameters(NodePointer LabelList, NodePointer ParameterType, |
| 897 | + unsigned depth, bool showTypes); |
| 898 | + |
| 899 | + void printFunctionType(NodePointer LabelList, NodePointer node, |
| 900 | + unsigned depth); |
| 901 | + |
| 902 | + void printImplFunctionType(NodePointer fn, unsigned depth); |
| 903 | + |
| 904 | + void printGenericSignature(NodePointer Node, unsigned depth); |
| 905 | + |
| 906 | + void printFunctionSigSpecializationParams(NodePointer Node, unsigned depth); |
| 907 | + |
| 908 | + void printSpecializationPrefix(NodePointer node, StringRef Description, |
| 909 | + unsigned depth, |
| 910 | + StringRef ParamPrefix = StringRef()); |
| 911 | + |
| 912 | + /// The main big print function. |
| 913 | + NodePointer print(NodePointer Node, unsigned depth, |
| 914 | + bool asPrefixContext = false); |
| 915 | + |
| 916 | + NodePointer printAbstractStorage(NodePointer Node, unsigned depth, |
| 917 | + bool asPrefixContent, StringRef ExtraName); |
| 918 | + |
| 919 | + /// Utility function to print entities. |
| 920 | + /// |
| 921 | + /// \param Entity The entity node to print |
| 922 | + /// \param depth The depth in the print() call tree. |
| 923 | + /// \param asPrefixContext Should the entity printed as a context which as a |
| 924 | + /// prefix to another entity, e.g. the Abc in Abc.def() |
| 925 | + /// \param TypePr How should the type of the entity be printed, if at all. |
| 926 | + /// E.g. with a colon for properties or as a function type. |
| 927 | + /// \param hasName Does the entity has a name, e.g. a function in contrast to |
| 928 | + /// an initializer. |
| 929 | + /// \param ExtraName An extra name added to the entity name (if any). |
| 930 | + /// \param ExtraIndex An extra index added to the entity name (if any), |
| 931 | + /// e.g. closure #1 |
| 932 | + /// \param OverwriteName If non-empty, print this name instead of the one |
| 933 | + /// provided by the node. Gets printed even if hasName is false. |
| 934 | + /// \return If a non-null node is returned it's a context which must be |
| 935 | + /// printed in postfix-form after the entity: "<entity> in <context>". |
| 936 | + NodePointer printEntity(NodePointer Entity, unsigned depth, |
| 937 | + bool asPrefixContext, TypePrinting TypePr, |
| 938 | + bool hasName, StringRef ExtraName = "", |
| 939 | + int ExtraIndex = -1, StringRef OverwriteName = ""); |
| 940 | + |
| 941 | + /// Print the type of an entity. |
| 942 | + /// |
| 943 | + /// \param Entity The entity. |
| 944 | + /// \param type The type of the entity. |
| 945 | + /// \param genericFunctionTypeList If not null, the generic argument types |
| 946 | + /// which is printed in the generic signature. |
| 947 | + /// \param depth The depth in the print() call tree. |
| 948 | + void printEntityType(NodePointer Entity, NodePointer type, |
| 949 | + NodePointer genericFunctionTypeList, unsigned depth); |
| 950 | +}; |
| 951 | + |
821 | 952 | SWIFT_END_INLINE_NAMESPACE
|
822 | 953 | } // end namespace Demangle
|
823 | 954 | } // end namespace swift
|
|
0 commit comments