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"
26
+ #include " swift/Strings.h"
25
27
#include " llvm/ADT/StringRef.h"
26
28
#include " llvm/Support/Compiler.h"
27
29
@@ -99,6 +101,7 @@ struct DemangleOptions {
99
101
100
102
class Node ;
101
103
using NodePointer = Node *;
104
+ class NodePrinter ;
102
105
103
106
enum class FunctionSigSpecializationParamKind : unsigned {
104
107
// Option Flags use bits 0-5. This give us 6 bits implying 64 entries to
@@ -234,6 +237,18 @@ class Node {
234
237
public:
235
238
Kind getKind () const { return NodeKind; }
236
239
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
+
237
252
bool isSimilarTo (const Node *other) const {
238
253
if (NodeKind != other->NodeKind
239
254
|| NodePayloadKind != other->NodePayloadKind )
@@ -417,6 +432,10 @@ bool isOldFunctionTypeMangling(llvm::StringRef mangledName);
417
432
418
433
class Demangler ;
419
434
435
+ class DemanglerPrinter ;
436
+
437
+ class TrackingDemanglerPrinter ;
438
+
420
439
// / The demangler context.
421
440
// /
422
441
// / It owns the allocated nodes which are created during demangling.
@@ -465,16 +484,26 @@ class Context {
465
484
// / The lifetime of the returned node tree ends with the lifetime of the
466
485
// / context or with a call of clear().
467
486
NodePointer demangleTypeAsNode (llvm::StringRef MangledName);
468
-
487
+
469
488
// / Demangle the given symbol and return the readable name.
470
489
// /
471
490
// / \param MangledName The mangled symbol string, which start a mangling
472
491
// / prefix: _T, _T0, $S, _$S.
473
492
// /
474
493
// / \returns The demangled string.
475
- std::string demangleSymbolAsString (
476
- llvm::StringRef MangledName,
477
- 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);
478
507
479
508
// / Demangle the given type and return the readable name.
480
509
// /
@@ -533,6 +562,18 @@ std::string
533
562
demangleSymbolAsString (const char *mangledName, size_t mangledNameLength,
534
563
const DemangleOptions &options = DemangleOptions());
535
564
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
+
536
577
// / Standalone utility function to demangle the given symbol as string.
537
578
// /
538
579
// / If performance is an issue when demangling multiple symbols,
@@ -545,7 +586,7 @@ demangleSymbolAsString(const std::string &mangledName,
545
586
return demangleSymbolAsString (mangledName.data (), mangledName.size (),
546
587
options);
547
588
}
548
-
589
+
549
590
// / Standalone utility function to demangle the given symbol as string.
550
591
// /
551
592
// / If performance is an issue when demangling multiple symbols,
@@ -555,8 +596,20 @@ demangleSymbolAsString(const std::string &mangledName,
555
596
inline std::string
556
597
demangleSymbolAsString (llvm::StringRef MangledName,
557
598
const DemangleOptions &Options = DemangleOptions()) {
558
- return demangleSymbolAsString (MangledName.data (),
559
- 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);
560
613
}
561
614
562
615
// / Standalone utility function to demangle the given type as string.
@@ -732,6 +785,15 @@ ManglingErrorOr<const char *> mangleNodeAsObjcCString(NodePointer node,
732
785
std::string nodeToString (NodePointer Root,
733
786
const DemangleOptions &Options = DemangleOptions());
734
787
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
+
735
797
// / Transforms a mangled key path accessor thunk helper
736
798
// / into the identfier/subscript that would be used to invoke it in swift code.
737
799
std::string keyPathSourceString (const char *MangledName,
@@ -777,11 +839,14 @@ class DemanglerPrinter {
777
839
778
840
llvm::StringRef getStringRef () const { return Stream; }
779
841
842
+ size_t getStreamLength () { return Stream.length (); }
843
+
780
844
// / Shrinks the buffer.
781
845
void resetSize (size_t toPos) {
782
846
assert (toPos <= Stream.size ());
783
847
Stream.resize (toPos);
784
848
}
849
+
785
850
private:
786
851
std::string Stream;
787
852
};
@@ -818,6 +883,159 @@ std::string mangledNameForTypeMetadataAccessor(
818
883
llvm::StringRef moduleName, llvm::StringRef typeName, Node::Kind typeKind,
819
884
Mangle::ManglingFlavor Flavor = Mangle::ManglingFlavor::Default);
820
885
886
+ // / Base class for printing a Swift demangled node tree.
887
+ // /
888
+ // / NodePrinter is used to convert demangled Swift symbol nodes into
889
+ // / human-readable string representations. It handles formatting, indentation,
890
+ // / 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.
895
+ class NodePrinter {
896
+ protected:
897
+ DemanglerPrinter Printer;
898
+ DemangleOptions Options;
899
+ bool SpecializationPrefixPrinted = false ;
900
+ bool isValid = true ;
901
+
902
+ public:
903
+ NodePrinter (DemangleOptions options) : Options(options) {}
904
+
905
+ virtual ~NodePrinter () {}
906
+
907
+ void printRoot (NodePointer root) {
908
+ isValid = true ;
909
+ print (root, 0 );
910
+ }
911
+
912
+ std::string takeString () {
913
+ if (isValid)
914
+ return std::move (Printer).str ();
915
+ return " " ;
916
+ }
917
+
918
+ protected:
919
+ static const unsigned MaxDepth = 768 ;
920
+
921
+ size_t getStreamLength () { return Printer.getStreamLength (); }
922
+
923
+ // / Called when the node tree in valid.
924
+ // /
925
+ // / The demangler already catches most error cases and mostly produces valid
926
+ // / node trees. But some cases are difficult to catch in the demangler and
927
+ // / instead the NodePrinter bails.
928
+ void setInvalid () { isValid = false ; }
929
+
930
+ void printChildren (Node::iterator begin, Node::iterator end, unsigned depth,
931
+ const char *sep = nullptr );
932
+
933
+ void printChildren (NodePointer Node, unsigned depth,
934
+ const char *sep = nullptr );
935
+
936
+ NodePointer getFirstChildOfKind (NodePointer Node, Node::Kind kind);
937
+
938
+ void printBoundGenericNoSugar (NodePointer Node, unsigned depth);
939
+
940
+ void printOptionalIndex (NodePointer node);
941
+
942
+ static bool isSwiftModule (NodePointer node) {
943
+ return (node->getKind () == Node::Kind::Module &&
944
+ node->getText () == STDLIB_NAME);
945
+ }
946
+
947
+ static bool isIdentifier (NodePointer node, StringRef desired) {
948
+ return (node->getKind () == Node::Kind::Identifier &&
949
+ node->getText () == desired);
950
+ }
951
+
952
+ bool printContext (NodePointer Context);
953
+
954
+ enum class SugarType {
955
+ None,
956
+ Optional,
957
+ ImplicitlyUnwrappedOptional,
958
+ Array,
959
+ Dictionary
960
+ };
961
+
962
+ enum class TypePrinting { NoType, WithColon, FunctionStyle };
963
+
964
+ // / Determine whether this is a "simple" type, from the type-simple
965
+ // / production.
966
+ bool isSimpleType (NodePointer Node);
967
+
968
+ void printWithParens (NodePointer type, unsigned depth);
969
+
970
+ SugarType findSugar (NodePointer Node);
971
+
972
+ void printBoundGeneric (NodePointer Node, unsigned depth);
973
+
974
+ NodePointer getChildIf (NodePointer Node, Node::Kind Kind);
975
+
976
+ virtual void printFunctionParameters (NodePointer LabelList,
977
+ NodePointer ParameterType,
978
+ unsigned depth, bool showTypes);
979
+
980
+ void printFunctionType (NodePointer LabelList, NodePointer node,
981
+ unsigned depth);
982
+
983
+ void printImplFunctionType (NodePointer fn, unsigned depth);
984
+
985
+ void printGenericSignature (NodePointer Node, unsigned depth);
986
+
987
+ void printFunctionSigSpecializationParams (NodePointer Node, unsigned depth);
988
+
989
+ void printSpecializationPrefix (NodePointer node, StringRef Description,
990
+ unsigned depth,
991
+ StringRef ParamPrefix = StringRef());
992
+
993
+ // / The main big print function.
994
+ NodePointer print (NodePointer Node, unsigned depth,
995
+ bool asPrefixContext = false );
996
+
997
+ NodePointer printAbstractStorage (NodePointer Node, unsigned depth,
998
+ bool asPrefixContent, StringRef ExtraName);
999
+
1000
+ // / Utility function to print entities.
1001
+ // /
1002
+ // / \param Entity The entity node to print
1003
+ // / \param depth The depth in the print() call tree.
1004
+ // / \param asPrefixContext Should the entity printed as a context which as a
1005
+ // / prefix to another entity, e.g. the Abc in Abc.def()
1006
+ // / \param TypePr How should the type of the entity be printed, if at all.
1007
+ // / E.g. with a colon for properties or as a function type.
1008
+ // / \param hasName Does the entity has a name, e.g. a function in contrast to
1009
+ // / an initializer.
1010
+ // / \param ExtraName An extra name added to the entity name (if any).
1011
+ // / \param ExtraIndex An extra index added to the entity name (if any),
1012
+ // / e.g. closure #1
1013
+ // / \param OverwriteName If non-empty, print this name instead of the one
1014
+ // / provided by the node. Gets printed even if hasName is false.
1015
+ // / \return If a non-null node is returned it's a context which must be
1016
+ // / printed in postfix-form after the entity: "<entity> in <context>".
1017
+ NodePointer printEntity (NodePointer Entity, unsigned depth,
1018
+ bool asPrefixContext, TypePrinting TypePr,
1019
+ bool hasName, StringRef ExtraName = " " ,
1020
+ int ExtraIndex = -1 , StringRef OverwriteName = " " );
1021
+
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
+
1028
+ // / Print the type of an entity.
1029
+ // /
1030
+ // / \param Entity The entity.
1031
+ // / \param type The type of the entity.
1032
+ // / \param genericFunctionTypeList If not null, the generic argument types
1033
+ // / which is printed in the generic signature.
1034
+ // / \param depth The depth in the print() call tree.
1035
+ void printEntityType (NodePointer Entity, NodePointer type,
1036
+ NodePointer genericFunctionTypeList, unsigned depth);
1037
+ };
1038
+
821
1039
SWIFT_END_INLINE_NAMESPACE
822
1040
} // end namespace Demangle
823
1041
} // end namespace swift
0 commit comments