-
Notifications
You must be signed in to change notification settings - Fork 341
[lldb] Change the type alias resolution algorithm #10036
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 all commits
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 |
---|---|---|
|
@@ -1264,22 +1264,69 @@ TypeSystemSwiftTypeRef::Canonicalize(swift::Demangle::Demangler &dem, | |
// Hit the safeguard limit. | ||
return node; | ||
} | ||
default: | ||
break; | ||
default: { | ||
llvm::SmallVector<NodePointer, 2> children; | ||
bool changed = false; | ||
for (NodePointer child : *node) { | ||
NodePointer transformed = GetCanonicalNode(dem, child, flavor); | ||
changed |= (child != transformed); | ||
children.push_back(transformed); | ||
} | ||
if (changed) { | ||
// Create a new node with the transformed children. | ||
auto kind = node->getKind(); | ||
if (node->hasText()) | ||
node = dem.createNodeWithAllocatedText(kind, node->getText()); | ||
else if (node->hasIndex()) | ||
node = dem.createNode(kind, node->getIndex()); | ||
else | ||
node = dem.createNode(kind); | ||
for (NodePointer transformed_child : children) | ||
node->addChild(transformed_child, dem); | ||
} | ||
return node; | ||
} | ||
} | ||
return node; | ||
} | ||
|
||
/// Iteratively resolve all type aliases in \p node by looking up their | ||
/// desugared types in the debug info of module \p M. | ||
swift::Demangle::NodePointer | ||
TypeSystemSwiftTypeRef::GetCanonicalNode(swift::Demangle::Demangler &dem, | ||
swift::Demangle::NodePointer node, | ||
swift::Mangle::ManglingFlavor flavor) { | ||
if (!node) | ||
return nullptr; | ||
// This is a pre-order traversal, which is necessary to resolve | ||
// generic type aliases that bind other type aliases in one go, | ||
// instead of first resolving the bound type aliases. Debug Info | ||
// will have a record for SomeAlias<SomeOtherAlias> but not | ||
// SomeAlias<WhatSomeOtherAliasResolvesTo> because it tries to | ||
// preserve all sugar. | ||
using namespace swift::Demangle; | ||
return TypeSystemSwiftTypeRef::Transform(dem, node, [&](NodePointer node) { | ||
return Canonicalize(dem, node, flavor); | ||
}); | ||
NodePointer transformed = Canonicalize(dem, node, flavor); | ||
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. Should this block of code be in a separate function called 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. There is only a single use, and it has shortcut in that it won't traverse the children of a transformed node, which is something a generic preorder transform maybe shouldn't do, so I decided to punt on that until we have a second use-case. |
||
if (node != transformed) | ||
return transformed; | ||
|
||
llvm::SmallVector<NodePointer, 2> children; | ||
bool changed = false; | ||
for (NodePointer child : *node) { | ||
NodePointer transformed_child = GetCanonicalNode(dem, child, flavor); | ||
changed |= (child != transformed_child); | ||
children.push_back(transformed_child); | ||
} | ||
if (changed) { | ||
// Create a new node with the transformed children. | ||
auto kind = node->getKind(); | ||
if (node->hasText()) | ||
node = dem.createNodeWithAllocatedText(kind, node->getText()); | ||
else if (node->hasIndex()) | ||
node = dem.createNode(kind, node->getIndex()); | ||
else | ||
node = dem.createNode(kind); | ||
for (NodePointer transformed_child : children) | ||
node->addChild(transformed_child, dem); | ||
} | ||
return node; | ||
} | ||
|
||
/// Return the demangle tree representation of this type's canonical | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -394,6 +394,7 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { | |
AdjustTypeForOriginallyDefinedInModule(llvm::StringRef mangled_typename); | ||
|
||
/// Return the canonicalized Demangle tree for a Swift mangled type name. | ||
/// It resolves all type aliases and removes sugar. | ||
swift::Demangle::NodePointer | ||
GetCanonicalDemangleTree(swift::Demangle::Demangler &dem, | ||
llvm::StringRef mangled_name); | ||
|
@@ -460,13 +461,6 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { | |
/// Cast \p opaque_type as a mangled name. | ||
static const char *AsMangledName(lldb::opaque_compiler_type_t type); | ||
|
||
/// Helper function that canonicalizes node, but doesn't look at its | ||
/// children. | ||
swift::Demangle::NodePointer | ||
Canonicalize(swift::Demangle::Demangler &dem, | ||
swift::Demangle::NodePointer node, | ||
swift::Mangle::ManglingFlavor flavor); | ||
|
||
/// Demangle the mangled name of the canonical type of \p type and | ||
/// drill into the Global(TypeMangling(Type())). | ||
/// | ||
|
@@ -484,6 +478,20 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { | |
DemangleCanonicalOutermostType(swift::Demangle::Demangler &dem, | ||
lldb::opaque_compiler_type_t type); | ||
|
||
/// Desugar to this node and if it is a type alias resolve it by | ||
/// looking up its type in the debug info. | ||
swift::Demangle::NodePointer | ||
Canonicalize(swift::Demangle::Demangler &dem, | ||
swift::Demangle::NodePointer node, | ||
swift::Mangle::ManglingFlavor flavor); | ||
|
||
/// Iteratively desugar and resolve all type aliases in \p node by | ||
/// looking up their types in the debug info. | ||
swift::Demangle::NodePointer | ||
GetCanonicalNode(swift::Demangle::Demangler &dem, | ||
swift::Demangle::NodePointer node, | ||
swift::Mangle::ManglingFlavor flavor); | ||
|
||
/// If \p node is a Struct/Class/Typedef in the __C module, return a | ||
/// Swiftified node by looking up the name in the corresponding APINotes and | ||
/// optionally putting it into the correctly named module. | ||
|
@@ -514,12 +522,6 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { | |
CompilerType LookupClangForwardType(llvm::StringRef name, | ||
llvm::ArrayRef<CompilerContext> decl_context); | ||
|
||
/// Recursively resolves all type aliases. | ||
swift::Demangle::NodePointer | ||
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. ResolveAllTypeAliases is gone from the header but not implementation? 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 never existed! |
||
ResolveAllTypeAliases(swift::Demangle::Demangler &dem, | ||
swift::Demangle::NodePointer node, | ||
swift::Mangle::ManglingFlavor flavor); | ||
|
||
/// Resolve a type alias node and return a demangle tree for the | ||
/// resolved type. If the type alias resolves to a Clang type, return | ||
/// a Clang CompilerType. | ||
|
@@ -531,11 +533,6 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { | |
swift::Demangle::Demangler &dem, swift::Demangle::NodePointer node, | ||
swift::Mangle::ManglingFlavor flavor, bool prefer_clang_types = false); | ||
|
||
swift::Demangle::NodePointer | ||
GetCanonicalNode(swift::Demangle::Demangler &dem, | ||
swift::Demangle::NodePointer node, | ||
swift::Mangle::ManglingFlavor flavor); | ||
|
||
uint32_t CollectTypeInfo(swift::Demangle::Demangler &dem, | ||
swift::Demangle::NodePointer node, | ||
swift::Mangle::ManglingFlavor flavor, | ||
|
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.
Is this code meant to both be here and in
GetCanonicalNode
?