@@ -101,6 +101,7 @@ struct DemangleOptions {
101101
102102class Node ;
103103using NodePointer = Node *;
104+ class NodePrinter ;
104105
105106enum class FunctionSigSpecializationParamKind : unsigned {
106107 // Option Flags use bits 0-5. This give us 6 bits implying 64 entries to
@@ -236,6 +237,18 @@ class Node {
236237public:
237238 Kind getKind () const { return NodeKind; }
238239
240+ bool shouldTrackNameRange () const {
241+ switch (getKind ()) {
242+ case Kind::Function:
243+ case Kind::Constructor:
244+ case Kind::Allocator:
245+ case Kind::ExplicitClosure:
246+ return true ;
247+ default :
248+ return false ;
249+ }
250+ }
251+
239252 bool isSimilarTo (const Node *other) const {
240253 if (NodeKind != other->NodeKind
241254 || NodePayloadKind != other->NodePayloadKind )
@@ -419,6 +432,10 @@ bool isOldFunctionTypeMangling(llvm::StringRef mangledName);
419432
420433class Demangler ;
421434
435+ class DemanglerPrinter ;
436+
437+ class TrackingDemanglerPrinter ;
438+
422439// / The demangler context.
423440// /
424441// / It owns the allocated nodes which are created during demangling.
@@ -467,16 +484,26 @@ class Context {
467484 // / The lifetime of the returned node tree ends with the lifetime of the
468485 // / context or with a call of clear().
469486 NodePointer demangleTypeAsNode (llvm::StringRef MangledName);
470-
487+
471488 // / Demangle the given symbol and return the readable name.
472489 // /
473490 // / \param MangledName The mangled symbol string, which start a mangling
474491 // / prefix: _T, _T0, $S, _$S.
475492 // /
476493 // / \returns The demangled string.
477- std::string demangleSymbolAsString (
478- llvm::StringRef MangledName,
479- const DemangleOptions &Options = DemangleOptions());
494+ std::string
495+ demangleSymbolAsString (llvm::StringRef MangledName,
496+ const DemangleOptions &Options = DemangleOptions());
497+
498+ // / Demangle the given symbol.
499+ // /
500+ // / \param MangledName The mangled symbol string, which start a mangling
501+ // / prefix: _T, _T0, $S, _$S.
502+ // / \param printer The NodePrinter that will be used to demangle the symbol.
503+ // /
504+ // / \returns The demangled string.
505+ void demangleSymbolAsString (llvm::StringRef MangledName,
506+ NodePrinter *printer);
480507
481508 // / Demangle the given type and return the readable name.
482509 // /
@@ -535,6 +562,18 @@ std::string
535562demangleSymbolAsString (const char *mangledName, size_t mangledNameLength,
536563 const DemangleOptions &options = DemangleOptions());
537564
565+ // / Standalone utility function to demangle the given symbol as string.
566+ // /
567+ // / If performance is an issue when demangling multiple symbols,
568+ // / Context::demangleSymbolAsString should be used instead.
569+ // / \param mangledName The mangled name string pointer.
570+ // / \param mangledNameLength The length of the mangledName string.
571+ // / \param printer The NodePrinter that will be used to demangle the symbol.
572+ // /
573+ // / \returns The demangled string.
574+ void demangleSymbolAsString (const char *mangledName, size_t mangledNameLength,
575+ NodePrinter *printer);
576+
538577// / Standalone utility function to demangle the given symbol as string.
539578// /
540579// / If performance is an issue when demangling multiple symbols,
@@ -547,7 +586,7 @@ demangleSymbolAsString(const std::string &mangledName,
547586 return demangleSymbolAsString (mangledName.data (), mangledName.size (),
548587 options);
549588}
550-
589+
551590// / Standalone utility function to demangle the given symbol as string.
552591// /
553592// / If performance is an issue when demangling multiple symbols,
@@ -557,8 +596,20 @@ demangleSymbolAsString(const std::string &mangledName,
557596inline std::string
558597demangleSymbolAsString (llvm::StringRef MangledName,
559598 const DemangleOptions &Options = DemangleOptions()) {
560- return demangleSymbolAsString (MangledName.data (),
561- MangledName.size (), Options);
599+ return demangleSymbolAsString (MangledName.data (), MangledName.size (),
600+ Options);
601+ }
602+
603+ // / Standalone utility function to demangle the given symbol as string.
604+ // /
605+ // / If performance is an issue when demangling multiple symbols,
606+ // / Context::demangleSymbolAsString should be used instead.
607+ // / \param MangledName The mangled name string.
608+ // /
609+ // / \returns The demangled string.
610+ inline void demangleSymbolAsString (llvm::StringRef MangledName,
611+ NodePrinter *printer) {
612+ demangleSymbolAsString (MangledName.data (), MangledName.size (), printer);
562613}
563614
564615// / Standalone utility function to demangle the given type as string.
@@ -734,6 +785,15 @@ ManglingErrorOr<const char *> mangleNodeAsObjcCString(NodePointer node,
734785std::string nodeToString (NodePointer Root,
735786 const DemangleOptions &Options = DemangleOptions());
736787
788+ // / Transform the node structure to a string.
789+ // /
790+ // / \endcode
791+ // /
792+ // / \param Root A pointer to a parse tree generated by the demangler.
793+ // / \param Printer A NodePrinter used to pretty print the demangled Node.
794+ // /
795+ void nodeToString (NodePointer Root, NodePrinter *Printer);
796+
737797// / Transforms a mangled key path accessor thunk helper
738798// / into the identfier/subscript that would be used to invoke it in swift code.
739799std::string keyPathSourceString (const char *MangledName,
@@ -779,11 +839,14 @@ class DemanglerPrinter {
779839
780840 llvm::StringRef getStringRef () const { return Stream; }
781841
842+ size_t getStreamLength () { return Stream.length (); }
843+
782844 // / Shrinks the buffer.
783845 void resetSize (size_t toPos) {
784846 assert (toPos <= Stream.size ());
785847 Stream.resize (toPos);
786848 }
849+
787850private:
788851 std::string Stream;
789852};
@@ -825,6 +888,10 @@ std::string mangledNameForTypeMetadataAccessor(
825888// / NodePrinter is used to convert demangled Swift symbol nodes into
826889// / human-readable string representations. It handles formatting, indentation,
827890// / and Swift-specific syntax.
891+ // /
892+ // / The virtual methods in this class are meant to be overriden to allow
893+ // / external consumers (e.g lldb) to track the ranges of components of the
894+ // / demangled name.
828895class NodePrinter {
829896protected:
830897 DemanglerPrinter Printer;
@@ -835,9 +902,14 @@ class NodePrinter {
835902public:
836903 NodePrinter (DemangleOptions options) : Options(options) {}
837904
838- std::string printRoot (NodePointer root) {
905+ virtual ~NodePrinter () {}
906+
907+ void printRoot (NodePointer root) {
839908 isValid = true ;
840909 print (root, 0 );
910+ }
911+
912+ std::string takeString () {
841913 if (isValid)
842914 return std::move (Printer).str ();
843915 return " " ;
@@ -846,6 +918,8 @@ class NodePrinter {
846918protected:
847919 static const unsigned MaxDepth = 768 ;
848920
921+ size_t getStreamLength () { return Printer.getStreamLength (); }
922+
849923 // / Called when the node tree in valid.
850924 // /
851925 // / The demangler already catches most error cases and mostly produces valid
@@ -899,8 +973,9 @@ class NodePrinter {
899973
900974 NodePointer getChildIf (NodePointer Node, Node::Kind Kind);
901975
902- void printFunctionParameters (NodePointer LabelList, NodePointer ParameterType,
903- unsigned depth, bool showTypes);
976+ virtual void printFunctionParameters (NodePointer LabelList,
977+ NodePointer ParameterType,
978+ unsigned depth, bool showTypes);
904979
905980 void printFunctionType (NodePointer LabelList, NodePointer node,
906981 unsigned depth);
@@ -944,6 +1019,12 @@ class NodePrinter {
9441019 bool hasName, StringRef ExtraName = " " ,
9451020 int ExtraIndex = -1 , StringRef OverwriteName = " " );
9461021
1022+ virtual void printFunctionName (bool hasName, llvm::StringRef &OverwriteName,
1023+ llvm::StringRef &ExtraName, bool MultiWordName,
1024+ int &ExtraIndex,
1025+ swift::Demangle::NodePointer Entity,
1026+ unsigned int depth);
1027+
9471028 // / Print the type of an entity.
9481029 // /
9491030 // / \param Entity The entity.
0 commit comments