From a85dbaf8aa3e874dcc30b94ac2091273876ef70c Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 1 May 2024 10:03:38 -0700 Subject: [PATCH] Demangler: Add option to omit closure signatures (#73331) (#73353) Add a new demangler option which excludes a closure's type signature. This will be used in lldb. Closures are not subject to overloading, and so the signature will never be used to disambiguate. A demangled closure is uniquely identifiable by its index(s) and parent. Where opaque types are involved, the concrete type signature can be quite complex. This demangling option allows callers to avoid printing the underlying complex nested concrete types. Example: before: `closure #1 (Swift.Int) -> () in closure #1 (Swift.Int) -> () in main` after: `closure #1 in closure #1 in main` --- include/swift/Demangling/Demangle.h | 1 + lib/Demangling/NodePrinter.cpp | 19 ++++++++++++++++++- test/Demangle/demangle-special-options.test | 3 +++ tools/swift-demangle/swift-demangle.cpp | 6 ++++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/include/swift/Demangling/Demangle.h b/include/swift/Demangling/Demangle.h index 0345940c5549d..584c4cb86c4f6 100644 --- a/include/swift/Demangling/Demangle.h +++ b/include/swift/Demangling/Demangle.h @@ -63,6 +63,7 @@ struct DemangleOptions { bool DisplayObjCModule = true; bool PrintForTypeName = false; bool ShowAsyncResumePartial = true; + bool ShowClosureSignature = true; /// If this is nonempty, entities in this module name will not be qualified. llvm::StringRef HidingCurrentModule; diff --git a/lib/Demangling/NodePrinter.cpp b/lib/Demangling/NodePrinter.cpp index 39c4d40353068..61429c3ad3dd8 100644 --- a/lib/Demangling/NodePrinter.cpp +++ b/lib/Demangling/NodePrinter.cpp @@ -1348,6 +1348,23 @@ static bool needSpaceBeforeType(NodePointer Type) { } } +/// Determine whether to print an entity's type. +static bool shouldShowEntityType(Node::Kind EntityKind, + const DemangleOptions &Options) { + switch (EntityKind) { + case Node::Kind::ExplicitClosure: + case Node::Kind::ImplicitClosure: + // The signature of a closure (its `Type` node) can optionally be omitted. + // Unlike functions which can have overloads, the signature of a closure is + // not needed to be uniquely identified. A closure is uniquely identified by + // its index and parent. Omitting the signature improves the readability + // when long type names are in use. + return Options.ShowClosureSignature; + default: + return true; + } +} + NodePointer NodePrinter::print(NodePointer Node, unsigned depth, bool asPrefixContext) { if (depth > NodePrinter::MaxDepth) { @@ -3484,7 +3501,7 @@ NodePointer NodePrinter::printEntity(NodePointer Entity, unsigned depth, Printer << " : "; printEntityType(Entity, type, genericFunctionTypeList, depth); } - } else { + } else if (shouldShowEntityType(Entity->getKind(), Options)) { assert(TypePr == TypePrinting::FunctionStyle); if (MultiWordName || needSpaceBeforeType(type)) Printer << ' '; diff --git a/test/Demangle/demangle-special-options.test b/test/Demangle/demangle-special-options.test index 4d3ab0b3c874e..f6e1e00c789df 100644 --- a/test/Demangle/demangle-special-options.test +++ b/test/Demangle/demangle-special-options.test @@ -16,3 +16,6 @@ LOCAL: ByteBuffer #1 in closure #6 RUN: swift-demangle -display-local-name-contexts=false s1a4mainyyFySRys5UInt8VGXEfU4_10ByteBufferL_aD | %FileCheck %s --check-prefix=NOLOCAL NOLOCAL: {{ ByteBuffer$}} + +RUN: swift-demangle -show-closure-signature=false s4mainySiXEfU_ySiXEfU_ | %FileCheck %s --check-prefix=CLOSURE +CLOSURE: closure #1 in closure #1 in main diff --git a/tools/swift-demangle/swift-demangle.cpp b/tools/swift-demangle/swift-demangle.cpp index 35e25378ecd16..f3cff2ba3c9ca 100644 --- a/tools/swift-demangle/swift-demangle.cpp +++ b/tools/swift-demangle/swift-demangle.cpp @@ -94,6 +94,11 @@ static llvm::cl::opt HidingModule( "hiding-module", llvm::cl::desc("Don't qualify types originating from this module"), llvm::cl::Hidden); + +static llvm::cl::opt + ShowClosureSignature("show-closure-signature", llvm::cl::init(true), + llvm::cl::desc("Show type signature of closures"), + llvm::cl::Hidden); /// \} @@ -390,6 +395,7 @@ int main(int argc, char **argv) { options.DisplayObjCModule = DisplayObjCModule; options.HidingCurrentModule = HidingModule; options.DisplayLocalNameContexts = DisplayLocalNameContexts; + options.ShowClosureSignature = ShowClosureSignature; if (InputNames.empty()) { CompactMode = true;