1919#ifndef SWIFT_DEMANGLING_DEMANGLE_H
2020#define SWIFT_DEMANGLING_DEMANGLE_H
2121
22+ #include " swift/Demangling/Demangle.h"
2223#include " swift/Demangling/Errors.h"
2324#include " swift/Demangling/ManglingFlavor.h"
2425#include " swift/Demangling/NamespaceMacros.h"
@@ -100,6 +101,7 @@ struct DemangleOptions {
100101
101102class Node ;
102103using NodePointer = Node *;
104+ class NodePrinter ;
103105
104106enum class FunctionSigSpecializationParamKind : unsigned {
105107 // Option Flags use bits 0-5. This give us 6 bits implying 64 entries to
@@ -466,16 +468,26 @@ class Context {
466468 // / The lifetime of the returned node tree ends with the lifetime of the
467469 // / context or with a call of clear().
468470 NodePointer demangleTypeAsNode (llvm::StringRef MangledName);
469-
471+
470472 // / Demangle the given symbol and return the readable name.
471473 // /
472474 // / \param MangledName The mangled symbol string, which start a mangling
473475 // / prefix: _T, _T0, $S, _$S.
474476 // /
475477 // / \returns The demangled string.
476- std::string demangleSymbolAsString (
477- llvm::StringRef MangledName,
478- const DemangleOptions &Options = DemangleOptions());
478+ std::string
479+ demangleSymbolAsString (llvm::StringRef MangledName,
480+ const DemangleOptions &Options = DemangleOptions());
481+
482+ // / Demangle the given symbol and store the result in the `printer`.
483+ // /
484+ // / \param MangledName The mangled symbol string, which start a mangling
485+ // / prefix: _T, _T0, $S, _$S.
486+ // / \param printer The NodePrinter that will be used to demangle the symbol.
487+ // /
488+ // / \returns The demangled string.
489+ void demangleSymbolAsString (llvm::StringRef MangledName,
490+ NodePrinter *printer);
479491
480492 // / Demangle the given type and return the readable name.
481493 // /
@@ -534,6 +546,17 @@ std::string
534546demangleSymbolAsString (const char *mangledName, size_t mangledNameLength,
535547 const DemangleOptions &options = DemangleOptions());
536548
549+ // / Standalone utility function to demangle the given symbol as string. The
550+ // / demangled string is stored in the `printer`.
551+ // /
552+ // / If performance is an issue when demangling multiple symbols,
553+ // / `Context::demangleSymbolAsString` should be used instead.
554+ // / \param mangledName The mangled name string pointer.
555+ // / \param mangledNameLength The length of the mangledName string.
556+ // / \param printer The NodePrinter that will be used to demangle the symbol.
557+ void demangleSymbolAsString (const char *mangledName, size_t mangledNameLength,
558+ NodePrinter *printer);
559+
537560// / Standalone utility function to demangle the given symbol as string.
538561// /
539562// / If performance is an issue when demangling multiple symbols,
@@ -546,7 +569,7 @@ demangleSymbolAsString(const std::string &mangledName,
546569 return demangleSymbolAsString (mangledName.data (), mangledName.size (),
547570 options);
548571}
549-
572+
550573// / Standalone utility function to demangle the given symbol as string.
551574// /
552575// / If performance is an issue when demangling multiple symbols,
@@ -560,6 +583,17 @@ demangleSymbolAsString(llvm::StringRef MangledName,
560583 MangledName.size (), Options);
561584}
562585
586+ // / Standalone utility function to demangle the given symbol as string. The
587+ // / result is stored in the `printer`.
588+ // /
589+ // / If performance is an issue when demangling multiple symbols,
590+ // / Context::demangleSymbolAsString should be used instead.
591+ // / \param MangledName The mangled name string.
592+ inline void demangleSymbolAsString (llvm::StringRef MangledName,
593+ NodePrinter *printer) {
594+ demangleSymbolAsString (MangledName.data (), MangledName.size (), printer);
595+ }
596+
563597// / Standalone utility function to demangle the given type as string.
564598// /
565599// / If performance is an issue when demangling multiple symbols,
@@ -726,13 +760,19 @@ ManglingErrorOr<const char *> mangleNodeAsObjcCString(NodePointer node,
726760// / \endcode
727761// /
728762// / \param Root A pointer to a parse tree generated by the demangler.
729- // / \param Options An object encapsulating options to use to perform this demangling.
763+ // / \param Options An object encapsulating options to use to perform this
764+ // / demangling.
730765// /
731766// / \returns A string representing the demangled name.
732- // /
733767std::string nodeToString (NodePointer Root,
734768 const DemangleOptions &Options = DemangleOptions());
735769
770+ // / Transform the node structure to a string, which is stored in the `Printer`.
771+ // /
772+ // / \param Root A pointer to a parse tree generated by the demangler.
773+ // / \param Printer A NodePrinter used to pretty print the demangled Node.
774+ void nodeToString (NodePointer Root, NodePrinter *Printer);
775+
736776// / Transforms a mangled key path accessor thunk helper
737777// / into the identfier/subscript that would be used to invoke it in swift code.
738778std::string keyPathSourceString (const char *MangledName,
@@ -778,11 +818,14 @@ class DemanglerPrinter {
778818
779819 llvm::StringRef getStringRef () const { return Stream; }
780820
821+ size_t getStreamLength () { return Stream.length (); }
822+
781823 // / Shrinks the buffer.
782824 void resetSize (size_t toPos) {
783825 assert (toPos <= Stream.size ());
784826 Stream.resize (toPos);
785827 }
828+
786829private:
787830 std::string Stream;
788831};
@@ -819,8 +862,17 @@ std::string mangledNameForTypeMetadataAccessor(
819862 llvm::StringRef moduleName, llvm::StringRef typeName, Node::Kind typeKind,
820863 Mangle::ManglingFlavor Flavor = Mangle::ManglingFlavor::Default);
821864
865+ // / Base class for printing a Swift demangled node tree.
866+ // /
867+ // / NodePrinter is used to convert demangled Swift symbol nodes into
868+ // / human-readable string representations. It handles formatting, indentation,
869+ // / and Swift-specific syntax.
870+ // /
871+ // / The virtual methods in this class are meant to be overriden to allow
872+ // / external consumers (e.g lldb) to track the ranges of components of the
873+ // / demangled name.
822874class NodePrinter {
823- private :
875+ protected :
824876 DemanglerPrinter Printer;
825877 DemangleOptions Options;
826878 bool SpecializationPrefixPrinted = false ;
@@ -829,17 +881,24 @@ class NodePrinter {
829881public:
830882 NodePrinter (DemangleOptions options) : Options(options) {}
831883
832- std::string printRoot (NodePointer root) {
884+ virtual ~NodePrinter () = default ;
885+
886+ void printRoot (NodePointer root) {
833887 isValid = true ;
834888 print (root, 0 );
889+ }
890+
891+ std::string takeString () {
835892 if (isValid)
836893 return std::move (Printer).str ();
837894 return " " ;
838895 }
839896
840- private :
897+ protected :
841898 static const unsigned MaxDepth = 768 ;
842899
900+ size_t getStreamLength () { return Printer.getStreamLength (); }
901+
843902 // / Called when the node tree in valid.
844903 // /
845904 // / The demangler already catches most error cases and mostly produces valid
@@ -864,13 +923,13 @@ class NodePrinter {
864923 node->getText () == STDLIB_NAME);
865924 }
866925
867- bool printContext (NodePointer Context);
868-
869926 static bool isIdentifier (NodePointer node, StringRef desired) {
870927 return (node->getKind () == Node::Kind::Identifier &&
871928 node->getText () == desired);
872929 }
873930
931+ bool printContext (NodePointer Context);
932+
874933 enum class SugarType {
875934 None,
876935 Optional,
@@ -893,8 +952,9 @@ class NodePrinter {
893952
894953 NodePointer getChildIf (NodePointer Node, Node::Kind Kind);
895954
896- void printFunctionParameters (NodePointer LabelList, NodePointer ParameterType,
897- unsigned depth, bool showTypes);
955+ virtual void printFunctionParameters (NodePointer LabelList,
956+ NodePointer ParameterType,
957+ unsigned depth, bool showTypes);
898958
899959 void printFunctionType (NodePointer LabelList, NodePointer node,
900960 unsigned depth);
@@ -938,6 +998,12 @@ class NodePrinter {
938998 bool hasName, StringRef ExtraName = " " ,
939999 int ExtraIndex = -1 , StringRef OverwriteName = " " );
9401000
1001+ virtual void printFunctionName (bool hasName, llvm::StringRef &OverwriteName,
1002+ llvm::StringRef &ExtraName, bool MultiWordName,
1003+ int &ExtraIndex,
1004+ swift::Demangle::NodePointer Entity,
1005+ unsigned int depth);
1006+
9411007 // / Print the type of an entity.
9421008 // /
9431009 // / \param Entity The entity.
0 commit comments