19
19
#ifndef SWIFT_DEMANGLING_DEMANGLE_H
20
20
#define SWIFT_DEMANGLING_DEMANGLE_H
21
21
22
+ #include " swift/Demangling/Demangle.h"
22
23
#include " swift/Demangling/Errors.h"
23
24
#include " swift/Demangling/ManglingFlavor.h"
24
25
#include " swift/Demangling/NamespaceMacros.h"
@@ -99,6 +100,7 @@ struct DemangleOptions {
99
100
100
101
class Node ;
101
102
using NodePointer = Node *;
103
+ class NodePrinter ;
102
104
103
105
enum class FunctionSigSpecializationParamKind : unsigned {
104
106
// Option Flags use bits 0-5. This give us 6 bits implying 64 entries to
@@ -465,16 +467,26 @@ class Context {
465
467
// / The lifetime of the returned node tree ends with the lifetime of the
466
468
// / context or with a call of clear().
467
469
NodePointer demangleTypeAsNode (llvm::StringRef MangledName);
468
-
470
+
469
471
// / Demangle the given symbol and return the readable name.
470
472
// /
471
473
// / \param MangledName The mangled symbol string, which start a mangling
472
474
// / prefix: _T, _T0, $S, _$S.
473
475
// /
474
476
// / \returns The demangled string.
475
- std::string demangleSymbolAsString (
476
- llvm::StringRef MangledName,
477
- const DemangleOptions &Options = DemangleOptions());
477
+ std::string
478
+ demangleSymbolAsString (llvm::StringRef MangledName,
479
+ const DemangleOptions &Options = DemangleOptions());
480
+
481
+ // / Demangle the given symbol and store the result in the `printer`.
482
+ // /
483
+ // / \param MangledName The mangled symbol string, which start a mangling
484
+ // / prefix: _T, _T0, $S, _$S.
485
+ // / \param printer The NodePrinter that will be used to demangle the symbol.
486
+ // /
487
+ // / \returns The demangled string.
488
+ void demangleSymbolAsString (llvm::StringRef MangledName,
489
+ NodePrinter *printer);
478
490
479
491
// / Demangle the given type and return the readable name.
480
492
// /
@@ -533,6 +545,17 @@ std::string
533
545
demangleSymbolAsString (const char *mangledName, size_t mangledNameLength,
534
546
const DemangleOptions &options = DemangleOptions());
535
547
548
+ // / Standalone utility function to demangle the given symbol as string. The
549
+ // / demangled string is stored in the `printer`.
550
+ // /
551
+ // / If performance is an issue when demangling multiple symbols,
552
+ // / `Context::demangleSymbolAsString` should be used instead.
553
+ // / \param mangledName The mangled name string pointer.
554
+ // / \param mangledNameLength The length of the mangledName string.
555
+ // / \param printer The NodePrinter that will be used to demangle the symbol.
556
+ void demangleSymbolAsString (const char *mangledName, size_t mangledNameLength,
557
+ NodePrinter *printer);
558
+
536
559
// / Standalone utility function to demangle the given symbol as string.
537
560
// /
538
561
// / If performance is an issue when demangling multiple symbols,
@@ -545,7 +568,7 @@ demangleSymbolAsString(const std::string &mangledName,
545
568
return demangleSymbolAsString (mangledName.data (), mangledName.size (),
546
569
options);
547
570
}
548
-
571
+
549
572
// / Standalone utility function to demangle the given symbol as string.
550
573
// /
551
574
// / If performance is an issue when demangling multiple symbols,
@@ -559,6 +582,17 @@ demangleSymbolAsString(llvm::StringRef MangledName,
559
582
MangledName.size (), Options);
560
583
}
561
584
585
+ // / Standalone utility function to demangle the given symbol as string. The
586
+ // / result is stored in the `printer`.
587
+ // /
588
+ // / If performance is an issue when demangling multiple symbols,
589
+ // / Context::demangleSymbolAsString should be used instead.
590
+ // / \param MangledName The mangled name string.
591
+ inline void demangleSymbolAsString (llvm::StringRef MangledName,
592
+ NodePrinter *printer) {
593
+ demangleSymbolAsString (MangledName.data (), MangledName.size (), printer);
594
+ }
595
+
562
596
// / Standalone utility function to demangle the given type as string.
563
597
// /
564
598
// / If performance is an issue when demangling multiple symbols,
@@ -725,13 +759,19 @@ ManglingErrorOr<const char *> mangleNodeAsObjcCString(NodePointer node,
725
759
// / \endcode
726
760
// /
727
761
// / \param Root A pointer to a parse tree generated by the demangler.
728
- // / \param Options An object encapsulating options to use to perform this demangling.
762
+ // / \param Options An object encapsulating options to use to perform this
763
+ // / demangling.
729
764
// /
730
765
// / \returns A string representing the demangled name.
731
- // /
732
766
std::string nodeToString (NodePointer Root,
733
767
const DemangleOptions &Options = DemangleOptions());
734
768
769
+ // / Transform the node structure to a string, which is stored in the `Printer`.
770
+ // /
771
+ // / \param Root A pointer to a parse tree generated by the demangler.
772
+ // / \param Printer A NodePrinter used to pretty print the demangled Node.
773
+ void nodeToString (NodePointer Root, NodePrinter *Printer);
774
+
735
775
// / Transforms a mangled key path accessor thunk helper
736
776
// / into the identfier/subscript that would be used to invoke it in swift code.
737
777
std::string keyPathSourceString (const char *MangledName,
@@ -777,11 +817,14 @@ class DemanglerPrinter {
777
817
778
818
llvm::StringRef getStringRef () const { return Stream; }
779
819
820
+ size_t getStreamLength () { return Stream.length (); }
821
+
780
822
// / Shrinks the buffer.
781
823
void resetSize (size_t toPos) {
782
824
assert (toPos <= Stream.size ());
783
825
Stream.resize (toPos);
784
826
}
827
+
785
828
private:
786
829
std::string Stream;
787
830
};
@@ -818,6 +861,159 @@ std::string mangledNameForTypeMetadataAccessor(
818
861
llvm::StringRef moduleName, llvm::StringRef typeName, Node::Kind typeKind,
819
862
Mangle::ManglingFlavor Flavor = Mangle::ManglingFlavor::Default);
820
863
864
+ // / Base class for printing a Swift demangled node tree.
865
+ // /
866
+ // / NodePrinter is used to convert demangled Swift symbol nodes into
867
+ // / human-readable string representations. It handles formatting, indentation,
868
+ // / and Swift-specific syntax.
869
+ // /
870
+ // / The virtual methods in this class are meant to be overriden to allow
871
+ // / external consumers (e.g lldb) to track the ranges of components of the
872
+ // / demangled name.
873
+ class NodePrinter {
874
+ protected:
875
+ DemanglerPrinter Printer;
876
+ DemangleOptions Options;
877
+ bool SpecializationPrefixPrinted = false ;
878
+ bool isValid = true ;
879
+
880
+ public:
881
+ NodePrinter (DemangleOptions options) : Options(options) {}
882
+
883
+ virtual ~NodePrinter () = default ;
884
+
885
+ void printRoot (NodePointer root) {
886
+ isValid = true ;
887
+ print (root, 0 );
888
+ }
889
+
890
+ std::string takeString () {
891
+ if (isValid)
892
+ return std::move (Printer).str ();
893
+ return " " ;
894
+ }
895
+
896
+ protected:
897
+ static const unsigned MaxDepth = 768 ;
898
+
899
+ size_t getStreamLength () { return Printer.getStreamLength (); }
900
+
901
+ // / Called when the node tree in valid.
902
+ // /
903
+ // / The demangler already catches most error cases and mostly produces valid
904
+ // / node trees. But some cases are difficult to catch in the demangler and
905
+ // / instead the NodePrinter bails.
906
+ void setInvalid () { isValid = false ; }
907
+
908
+ void printChildren (Node::iterator begin, Node::iterator end, unsigned depth,
909
+ const char *sep = nullptr );
910
+
911
+ void printChildren (NodePointer Node, unsigned depth,
912
+ const char *sep = nullptr );
913
+
914
+ NodePointer getFirstChildOfKind (NodePointer Node, Node::Kind kind);
915
+
916
+ void printBoundGenericNoSugar (NodePointer Node, unsigned depth);
917
+
918
+ void printOptionalIndex (NodePointer node);
919
+
920
+ static bool isSwiftModule (NodePointer node) {
921
+ return (node->getKind () == Node::Kind::Module &&
922
+ node->getText () == STDLIB_NAME);
923
+ }
924
+
925
+ static bool isIdentifier (NodePointer node, StringRef desired) {
926
+ return (node->getKind () == Node::Kind::Identifier &&
927
+ node->getText () == desired);
928
+ }
929
+
930
+ bool printContext (NodePointer Context);
931
+
932
+ enum class SugarType {
933
+ None,
934
+ Optional,
935
+ ImplicitlyUnwrappedOptional,
936
+ Array,
937
+ Dictionary
938
+ };
939
+
940
+ enum class TypePrinting { NoType, WithColon, FunctionStyle };
941
+
942
+ // / Determine whether this is a "simple" type, from the type-simple
943
+ // / production.
944
+ bool isSimpleType (NodePointer Node);
945
+
946
+ void printWithParens (NodePointer type, unsigned depth);
947
+
948
+ SugarType findSugar (NodePointer Node);
949
+
950
+ void printBoundGeneric (NodePointer Node, unsigned depth);
951
+
952
+ NodePointer getChildIf (NodePointer Node, Node::Kind Kind);
953
+
954
+ virtual void printFunctionParameters (NodePointer LabelList,
955
+ NodePointer ParameterType,
956
+ unsigned depth, bool showTypes);
957
+
958
+ void printFunctionType (NodePointer LabelList, NodePointer node,
959
+ unsigned depth);
960
+
961
+ void printImplFunctionType (NodePointer fn, unsigned depth);
962
+
963
+ void printGenericSignature (NodePointer Node, unsigned depth);
964
+
965
+ void printFunctionSigSpecializationParams (NodePointer Node, unsigned depth);
966
+
967
+ void printSpecializationPrefix (NodePointer node, StringRef Description,
968
+ unsigned depth,
969
+ StringRef ParamPrefix = StringRef());
970
+
971
+ // / The main big print function.
972
+ NodePointer print (NodePointer Node, unsigned depth,
973
+ bool asPrefixContext = false );
974
+
975
+ NodePointer printAbstractStorage (NodePointer Node, unsigned depth,
976
+ bool asPrefixContent, StringRef ExtraName);
977
+
978
+ // / Utility function to print entities.
979
+ // /
980
+ // / \param Entity The entity node to print
981
+ // / \param depth The depth in the print() call tree.
982
+ // / \param asPrefixContext Should the entity printed as a context which as a
983
+ // / prefix to another entity, e.g. the Abc in Abc.def()
984
+ // / \param TypePr How should the type of the entity be printed, if at all.
985
+ // / E.g. with a colon for properties or as a function type.
986
+ // / \param hasName Does the entity has a name, e.g. a function in contrast to
987
+ // / an initializer.
988
+ // / \param ExtraName An extra name added to the entity name (if any).
989
+ // / \param ExtraIndex An extra index added to the entity name (if any),
990
+ // / e.g. closure #1
991
+ // / \param OverwriteName If non-empty, print this name instead of the one
992
+ // / provided by the node. Gets printed even if hasName is false.
993
+ // / \return If a non-null node is returned it's a context which must be
994
+ // / printed in postfix-form after the entity: "<entity> in <context>".
995
+ NodePointer printEntity (NodePointer Entity, unsigned depth,
996
+ bool asPrefixContext, TypePrinting TypePr,
997
+ bool hasName, StringRef ExtraName = " " ,
998
+ int ExtraIndex = -1 , StringRef OverwriteName = " " );
999
+
1000
+ virtual void printFunctionName (bool hasName, llvm::StringRef &OverwriteName,
1001
+ llvm::StringRef &ExtraName, bool MultiWordName,
1002
+ int &ExtraIndex,
1003
+ swift::Demangle::NodePointer Entity,
1004
+ unsigned int depth);
1005
+
1006
+ // / Print the type of an entity.
1007
+ // /
1008
+ // / \param Entity The entity.
1009
+ // / \param type The type of the entity.
1010
+ // / \param genericFunctionTypeList If not null, the generic argument types
1011
+ // / which is printed in the generic signature.
1012
+ // / \param depth The depth in the print() call tree.
1013
+ void printEntityType (NodePointer Entity, NodePointer type,
1014
+ NodePointer genericFunctionTypeList, unsigned depth);
1015
+ };
1016
+
821
1017
SWIFT_END_INLINE_NAMESPACE
822
1018
} // end namespace Demangle
823
1019
} // end namespace swift
0 commit comments