Demangler: Add option to omit closure signatures (#73331)

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`
This commit is contained in:
Dave Lee
2024-04-30 12:48:02 -07:00
committed by GitHub
parent dbc8c4b08b
commit c3488c60e1
4 changed files with 28 additions and 1 deletions

View File

@@ -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;

View File

@@ -1349,6 +1349,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) {
@@ -3492,7 +3509,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 << ' ';

View File

@@ -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

View File

@@ -94,6 +94,11 @@ static llvm::cl::opt<std::string> HidingModule(
"hiding-module",
llvm::cl::desc("Don't qualify types originating from this module"),
llvm::cl::Hidden);
static llvm::cl::opt<bool>
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;