-
Notifications
You must be signed in to change notification settings - Fork 10.6k
add range tracking when demangling a name #82298
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -101,6 +101,7 @@ struct DemangleOptions { | |||||||
|
|
||||||||
| class Node; | ||||||||
| using NodePointer = Node *; | ||||||||
| class NodePrinter; | ||||||||
|
|
||||||||
| enum class FunctionSigSpecializationParamKind : unsigned { | ||||||||
| // Option Flags use bits 0-5. This give us 6 bits implying 64 entries to | ||||||||
|
|
@@ -236,6 +237,18 @@ class Node { | |||||||
| public: | ||||||||
| Kind getKind() const { return NodeKind; } | ||||||||
|
|
||||||||
| bool shouldTrackNameRange() const { | ||||||||
| switch (getKind()) { | ||||||||
| case Kind::Function: | ||||||||
| case Kind::Constructor: | ||||||||
| case Kind::Allocator: | ||||||||
| case Kind::ExplicitClosure: | ||||||||
| return true; | ||||||||
| default: | ||||||||
| return false; | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| bool isSimilarTo(const Node *other) const { | ||||||||
| if (NodeKind != other->NodeKind | ||||||||
| || NodePayloadKind != other->NodePayloadKind) | ||||||||
|
|
@@ -419,6 +432,10 @@ bool isOldFunctionTypeMangling(llvm::StringRef mangledName); | |||||||
|
|
||||||||
| class Demangler; | ||||||||
|
|
||||||||
| class DemanglerPrinter; | ||||||||
|
|
||||||||
| class TrackingDemanglerPrinter; | ||||||||
|
Comment on lines
+435
to
+437
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Don't think these are needed There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||
|
|
||||||||
| /// The demangler context. | ||||||||
| /// | ||||||||
| /// It owns the allocated nodes which are created during demangling. | ||||||||
|
|
@@ -467,16 +484,26 @@ class Context { | |||||||
| /// The lifetime of the returned node tree ends with the lifetime of the | ||||||||
| /// context or with a call of clear(). | ||||||||
| NodePointer demangleTypeAsNode(llvm::StringRef MangledName); | ||||||||
|
|
||||||||
| /// Demangle the given symbol and return the readable name. | ||||||||
| /// | ||||||||
| /// \param MangledName The mangled symbol string, which start a mangling | ||||||||
| /// prefix: _T, _T0, $S, _$S. | ||||||||
| /// | ||||||||
| /// \returns The demangled string. | ||||||||
| std::string demangleSymbolAsString( | ||||||||
| llvm::StringRef MangledName, | ||||||||
| const DemangleOptions &Options = DemangleOptions()); | ||||||||
| std::string | ||||||||
| demangleSymbolAsString(llvm::StringRef MangledName, | ||||||||
| const DemangleOptions &Options = DemangleOptions()); | ||||||||
|
|
||||||||
| /// Demangle the given symbol. | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Lets briefly describe what the intended usage of this overload is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||
| /// | ||||||||
| /// \param MangledName The mangled symbol string, which start a mangling | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not sure where this came from, probably a bad copy paste. Removed in: |
||||||||
| /// prefix: _T, _T0, $S, _$S. | ||||||||
| /// \param printer The NodePrinter that will be used to demangle the symbol. | ||||||||
| /// | ||||||||
| /// \returns The demangled string. | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function doesn't return anything though. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Adjusted the doxygen of this method and a few others in: |
||||||||
| void demangleSymbolAsString(llvm::StringRef MangledName, | ||||||||
| NodePrinter *printer); | ||||||||
|
|
||||||||
| /// Demangle the given type and return the readable name. | ||||||||
| /// | ||||||||
|
|
@@ -535,6 +562,18 @@ std::string | |||||||
| demangleSymbolAsString(const char *mangledName, size_t mangledNameLength, | ||||||||
| const DemangleOptions &options = DemangleOptions()); | ||||||||
|
|
||||||||
| /// Standalone utility function to demangle the given symbol as string. | ||||||||
| /// | ||||||||
| /// If performance is an issue when demangling multiple symbols, | ||||||||
| /// Context::demangleSymbolAsString should be used instead. | ||||||||
| /// \param mangledName The mangled name string pointer. | ||||||||
| /// \param mangledNameLength The length of the mangledName string. | ||||||||
| /// \param printer The NodePrinter that will be used to demangle the symbol. | ||||||||
| /// | ||||||||
| /// \returns The demangled string. | ||||||||
| void demangleSymbolAsString(const char *mangledName, size_t mangledNameLength, | ||||||||
| NodePrinter *printer); | ||||||||
|
|
||||||||
| /// Standalone utility function to demangle the given symbol as string. | ||||||||
| /// | ||||||||
| /// If performance is an issue when demangling multiple symbols, | ||||||||
|
|
@@ -547,7 +586,7 @@ demangleSymbolAsString(const std::string &mangledName, | |||||||
| return demangleSymbolAsString(mangledName.data(), mangledName.size(), | ||||||||
| options); | ||||||||
| } | ||||||||
|
|
||||||||
| /// Standalone utility function to demangle the given symbol as string. | ||||||||
| /// | ||||||||
| /// If performance is an issue when demangling multiple symbols, | ||||||||
|
|
@@ -557,8 +596,20 @@ demangleSymbolAsString(const std::string &mangledName, | |||||||
| inline std::string | ||||||||
| demangleSymbolAsString(llvm::StringRef MangledName, | ||||||||
| const DemangleOptions &Options = DemangleOptions()) { | ||||||||
| return demangleSymbolAsString(MangledName.data(), | ||||||||
| MangledName.size(), Options); | ||||||||
| return demangleSymbolAsString(MangledName.data(), MangledName.size(), | ||||||||
| Options); | ||||||||
| } | ||||||||
|
|
||||||||
| /// Standalone utility function to demangle the given symbol as string. | ||||||||
| /// | ||||||||
| /// If performance is an issue when demangling multiple symbols, | ||||||||
| /// Context::demangleSymbolAsString should be used instead. | ||||||||
| /// \param MangledName The mangled name string. | ||||||||
| /// | ||||||||
| /// \returns The demangled string. | ||||||||
| inline void demangleSymbolAsString(llvm::StringRef MangledName, | ||||||||
| NodePrinter *printer) { | ||||||||
| demangleSymbolAsString(MangledName.data(), MangledName.size(), printer); | ||||||||
| } | ||||||||
|
|
||||||||
| /// Standalone utility function to demangle the given type as string. | ||||||||
|
|
@@ -734,6 +785,15 @@ ManglingErrorOr<const char *> mangleNodeAsObjcCString(NodePointer node, | |||||||
| std::string nodeToString(NodePointer Root, | ||||||||
| const DemangleOptions &Options = DemangleOptions()); | ||||||||
|
|
||||||||
| /// Transform the node structure to a string. | ||||||||
| /// | ||||||||
| /// \endcode | ||||||||
| /// | ||||||||
| /// \param Root A pointer to a parse tree generated by the demangler. | ||||||||
| /// \param Printer A NodePrinter used to pretty print the demangled Node. | ||||||||
| /// | ||||||||
| void nodeToString(NodePointer Root, NodePrinter *Printer); | ||||||||
|
|
||||||||
| /// Transforms a mangled key path accessor thunk helper | ||||||||
| /// into the identfier/subscript that would be used to invoke it in swift code. | ||||||||
| std::string keyPathSourceString(const char *MangledName, | ||||||||
|
|
@@ -779,11 +839,14 @@ class DemanglerPrinter { | |||||||
|
|
||||||||
| llvm::StringRef getStringRef() const { return Stream; } | ||||||||
|
|
||||||||
| size_t getStreamLength() { return Stream.length(); } | ||||||||
|
|
||||||||
| /// Shrinks the buffer. | ||||||||
| void resetSize(size_t toPos) { | ||||||||
| assert(toPos <= Stream.size()); | ||||||||
| Stream.resize(toPos); | ||||||||
| } | ||||||||
|
|
||||||||
| private: | ||||||||
| std::string Stream; | ||||||||
| }; | ||||||||
|
|
@@ -825,6 +888,10 @@ std::string mangledNameForTypeMetadataAccessor( | |||||||
| /// NodePrinter is used to convert demangled Swift symbol nodes into | ||||||||
| /// human-readable string representations. It handles formatting, indentation, | ||||||||
| /// and Swift-specific syntax. | ||||||||
| /// | ||||||||
| /// The virtual methods in this class are meant to be overriden to allow | ||||||||
| /// external consumers (e.g lldb) to track the ranges of components of the | ||||||||
| /// demangled name. | ||||||||
| class NodePrinter { | ||||||||
| protected: | ||||||||
| DemanglerPrinter Printer; | ||||||||
|
|
@@ -835,9 +902,14 @@ class NodePrinter { | |||||||
| public: | ||||||||
| NodePrinter(DemangleOptions options) : Options(options) {} | ||||||||
|
|
||||||||
| std::string printRoot(NodePointer root) { | ||||||||
| virtual ~NodePrinter() {} | ||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||||||||
|
|
||||||||
| void printRoot(NodePointer root) { | ||||||||
| isValid = true; | ||||||||
| print(root, 0); | ||||||||
| } | ||||||||
|
|
||||||||
| std::string takeString() { | ||||||||
| if (isValid) | ||||||||
| return std::move(Printer).str(); | ||||||||
| return ""; | ||||||||
|
|
@@ -846,6 +918,8 @@ class NodePrinter { | |||||||
| protected: | ||||||||
| static const unsigned MaxDepth = 768; | ||||||||
|
|
||||||||
| size_t getStreamLength() { return Printer.getStreamLength(); } | ||||||||
|
|
||||||||
| /// Called when the node tree in valid. | ||||||||
| /// | ||||||||
| /// The demangler already catches most error cases and mostly produces valid | ||||||||
|
|
@@ -899,8 +973,9 @@ class NodePrinter { | |||||||
|
|
||||||||
| NodePointer getChildIf(NodePointer Node, Node::Kind Kind); | ||||||||
|
|
||||||||
| void printFunctionParameters(NodePointer LabelList, NodePointer ParameterType, | ||||||||
| unsigned depth, bool showTypes); | ||||||||
| virtual void printFunctionParameters(NodePointer LabelList, | ||||||||
| NodePointer ParameterType, | ||||||||
| unsigned depth, bool showTypes); | ||||||||
|
|
||||||||
| void printFunctionType(NodePointer LabelList, NodePointer node, | ||||||||
| unsigned depth); | ||||||||
|
|
@@ -944,6 +1019,12 @@ class NodePrinter { | |||||||
| bool hasName, StringRef ExtraName = "", | ||||||||
| int ExtraIndex = -1, StringRef OverwriteName = ""); | ||||||||
|
|
||||||||
| virtual void printFunctionName(bool hasName, llvm::StringRef &OverwriteName, | ||||||||
| llvm::StringRef &ExtraName, bool MultiWordName, | ||||||||
| int &ExtraIndex, | ||||||||
| swift::Demangle::NodePointer Entity, | ||||||||
| unsigned int depth); | ||||||||
|
|
||||||||
| /// Print the type of an entity. | ||||||||
| /// | ||||||||
| /// \param Entity The entity. | ||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -3568,6 +3568,43 @@ NodePointer NodePrinter::printEntity(NodePointer Entity, unsigned depth, | |
| return PostfixContext; | ||
| } | ||
|
|
||
| void NodePrinter::printFunctionName(bool hasName, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Has this function just been moved? Or has it been adjusted? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a new function which was extracted from the |
||
| llvm::StringRef &OverwriteName, | ||
| llvm::StringRef &ExtraName, | ||
| bool MultiWordName, int &ExtraIndex, | ||
| swift::Demangle::NodePointer Entity, | ||
| unsigned int depth) { | ||
| if (hasName || !OverwriteName.empty()) { | ||
| if (!ExtraName.empty() && MultiWordName) { | ||
| Printer << ExtraName; | ||
| if (ExtraIndex >= 0) | ||
| Printer << ExtraIndex; | ||
|
|
||
| Printer << " of "; | ||
| ExtraName = ""; | ||
| ExtraIndex = -1; | ||
| } | ||
| size_t CurrentPos = Printer.getStringRef().size(); | ||
| if (!OverwriteName.empty()) { | ||
| Printer << OverwriteName; | ||
| } else { | ||
| auto Name = Entity->getChild(1); | ||
| if (Name->getKind() != Node::Kind::PrivateDeclName) | ||
| print(Name, depth + 1); | ||
|
|
||
| if (auto PrivateName = getChildIf(Entity, Node::Kind::PrivateDeclName)) | ||
| print(PrivateName, depth + 1); | ||
| } | ||
| if (Printer.getStringRef().size() != CurrentPos && !ExtraName.empty()) | ||
| Printer << '.'; | ||
| } | ||
| if (!ExtraName.empty()) { | ||
| Printer << ExtraName; | ||
| if (ExtraIndex >= 0) | ||
| Printer << ExtraIndex; | ||
| } | ||
| } | ||
|
|
||
| void NodePrinter::printEntityType(NodePointer Entity, NodePointer type, | ||
| NodePointer genericFunctionTypeList, | ||
| unsigned depth) { | ||
|
|
@@ -3751,7 +3788,15 @@ std::string Demangle::nodeToString(NodePointer root, | |
| if (!root) | ||
| return ""; | ||
|
|
||
| return NodePrinter(options).printRoot(root); | ||
| NodePrinter printer = NodePrinter(options); | ||
| nodeToString(root, &printer); | ||
| return printer.takeString(); | ||
| } | ||
|
|
||
| void Demangle::nodeToString(NodePointer root, NodePrinter *printer) { | ||
| if (!root) | ||
| return; | ||
| printer->printRoot(root); | ||
| } | ||
|
|
||
| #endif | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Where is this used?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's used here: https://github.com/swiftlang/llvm-project/pull/10710/files#diff-5c0cd3ffc206ebb1e41b4984b7629c896aa79951708915cfafff560b1da51aa1
The code was moved there instead because it does not make sense to have it in the swift repo. It has been removed in: