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"
@@ -234,6 +235,18 @@ class Node {
234
235
public:
235
236
Kind getKind () const { return NodeKind; }
236
237
238
+ bool shouldTrackNameRange () const {
239
+ switch (getKind ()) {
240
+ case Kind::Function:
241
+ case Kind::Constructor:
242
+ case Kind::Allocator:
243
+ case Kind::ExplicitClosure:
244
+ return true ;
245
+ default :
246
+ return false ;
247
+ }
248
+ }
249
+
237
250
bool isSimilarTo (const Node *other) const {
238
251
if (NodeKind != other->NodeKind
239
252
|| NodePayloadKind != other->NodePayloadKind )
@@ -417,6 +430,10 @@ bool isOldFunctionTypeMangling(llvm::StringRef mangledName);
417
430
418
431
class Demangler ;
419
432
433
+ class DemanglerPrinter ;
434
+
435
+ class TrackingDemanglerPrinter ;
436
+
420
437
// / The demangler context.
421
438
// /
422
439
// / It owns the allocated nodes which are created during demangling.
@@ -472,9 +489,10 @@ class Context {
472
489
// / prefix: _T, _T0, $S, _$S.
473
490
// /
474
491
// / \returns The demangled string.
475
- std::string demangleSymbolAsString (
476
- llvm::StringRef MangledName,
477
- const DemangleOptions &Options = DemangleOptions());
492
+ std::string
493
+ demangleSymbolAsString (llvm::StringRef MangledName,
494
+ const DemangleOptions &Options = DemangleOptions(),
495
+ DemanglerPrinter *printer = nullptr );
478
496
479
497
// / Demangle the given type and return the readable name.
480
498
// /
@@ -531,7 +549,8 @@ class Context {
531
549
// / \returns The demangled string.
532
550
std::string
533
551
demangleSymbolAsString (const char *mangledName, size_t mangledNameLength,
534
- const DemangleOptions &options = DemangleOptions());
552
+ const DemangleOptions &options = DemangleOptions(),
553
+ DemanglerPrinter *printer = nullptr);
535
554
536
555
// / Standalone utility function to demangle the given symbol as string.
537
556
// /
@@ -541,11 +560,12 @@ demangleSymbolAsString(const char *mangledName, size_t mangledNameLength,
541
560
// / \returns The demangled string.
542
561
inline std::string
543
562
demangleSymbolAsString (const std::string &mangledName,
544
- const DemangleOptions &options = DemangleOptions()) {
545
- return demangleSymbolAsString (mangledName.data (), mangledName.size (),
546
- options);
563
+ const DemangleOptions &options = DemangleOptions(),
564
+ DemanglerPrinter *printer = nullptr) {
565
+ return demangleSymbolAsString (mangledName.data (), mangledName.size (), options,
566
+ printer);
547
567
}
548
-
568
+
549
569
// / Standalone utility function to demangle the given symbol as string.
550
570
// /
551
571
// / If performance is an issue when demangling multiple symbols,
@@ -554,9 +574,10 @@ demangleSymbolAsString(const std::string &mangledName,
554
574
// / \returns The demangled string.
555
575
inline std::string
556
576
demangleSymbolAsString (llvm::StringRef MangledName,
557
- const DemangleOptions &Options = DemangleOptions()) {
558
- return demangleSymbolAsString (MangledName.data (),
559
- MangledName.size (), Options);
577
+ const DemangleOptions &Options = DemangleOptions(),
578
+ DemanglerPrinter *printer = nullptr) {
579
+ return demangleSymbolAsString (MangledName.data (), MangledName.size (), Options,
580
+ printer);
560
581
}
561
582
562
583
// / Standalone utility function to demangle the given type as string.
@@ -730,7 +751,8 @@ ManglingErrorOr<const char *> mangleNodeAsObjcCString(NodePointer node,
730
751
// / \returns A string representing the demangled name.
731
752
// /
732
753
std::string nodeToString (NodePointer Root,
733
- const DemangleOptions &Options = DemangleOptions());
754
+ const DemangleOptions &Options = DemangleOptions(),
755
+ DemanglerPrinter *printer = nullptr);
734
756
735
757
// / Transforms a mangled key path accessor thunk helper
736
758
// / into the identfier/subscript that would be used to invoke it in swift code.
@@ -777,15 +799,81 @@ class DemanglerPrinter {
777
799
778
800
llvm::StringRef getStringRef () const { return Stream; }
779
801
802
+ size_t getStreamLength () { return Stream.length (); }
803
+
780
804
// / Shrinks the buffer.
781
805
void resetSize (size_t toPos) {
782
806
assert (toPos <= Stream.size ());
783
807
Stream.resize (toPos);
784
808
}
809
+
810
+ // / Mark the start of the name of a function.
811
+ virtual void startName () {}
812
+
813
+ // / Mark the end of the name of a function.
814
+ virtual void endName () {}
815
+
816
+ // / Mark the start of the parameters of a function.
817
+ // /
818
+ // / \param depth Current depth of the parameters that are being printed.
819
+ virtual void startParameters (unsigned depth) {}
820
+
821
+ // / Mark the end of the parameters of a function.
822
+ // /
823
+ // / \param depth Current depth of the parameters that are being printed.
824
+ virtual void endParameters (unsigned depth) {}
825
+
826
+ virtual ~DemanglerPrinter () {}
827
+
785
828
private:
786
829
std::string Stream;
787
830
};
788
831
832
+ // / A class for printing to a std::string while tracking ranges.
833
+ class TrackingDemanglerPrinter : public swift ::Demangle::DemanglerPrinter {
834
+ public:
835
+ size_t getNameStart () { return baseNameRange.first ; }
836
+ size_t getNameEnd () { return baseNameRange.second ; }
837
+ size_t getParametersStart () { return parametersRange.first ; }
838
+ size_t getParametersEnd () { return parametersRange.second ; }
839
+ bool hasBaseName () { return baseNameRange.first < baseNameRange.second ; }
840
+ bool hasParameters () {
841
+ return parametersRange.first < parametersRange.second ;
842
+ }
843
+
844
+ void startName () override {
845
+ if (!hasBaseName ())
846
+ baseNameRange.first = getStreamLength ();
847
+ }
848
+
849
+ void endName () override {
850
+ if (!hasBaseName ())
851
+ baseNameRange.second = getStreamLength ();
852
+ }
853
+
854
+ void startParameters (unsigned depth) override {
855
+ if (parametersDepth || !hasBaseName () || hasParameters ()) {
856
+ return ;
857
+ }
858
+ parametersRange.first = getStreamLength ();
859
+ parametersDepth = depth;
860
+ }
861
+
862
+ void endParameters (unsigned depth) override {
863
+ if (!parametersDepth || *parametersDepth != depth || hasParameters ()) {
864
+ return ;
865
+ }
866
+ parametersRange.second = getStreamLength ();
867
+ }
868
+
869
+ private:
870
+ std::pair<size_t , size_t > baseNameRange;
871
+
872
+ std::pair<size_t , size_t > parametersRange;
873
+
874
+ std::optional<unsigned > parametersDepth;
875
+ };
876
+
789
877
// / Returns a the node kind \p k as string.
790
878
const char *getNodeKindString (swift::Demangle::Node::Kind k);
791
879
0 commit comments