Skip to content

Commit ef05764

Browse files
committed
[lldb] Recursively resolve type aliases when canonicalizing types
A type alias that resolved to a type containing more type aliase can now also be handled. To safeguard against broken debug info with cyclic aliases a limit to this is also enforced. rdar://143156979
1 parent 5f7c906 commit ef05764

File tree

5 files changed

+61
-15
lines changed

5 files changed

+61
-15
lines changed

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -936,13 +936,6 @@ IsClangImportedType(NodePointer node,
936936
}
937937
}
938938

939-
/// Resolve a type alias node and return a demangle tree for the
940-
/// resolved type. If the type alias resolves to a Clang type, return
941-
/// a Clang CompilerType.
942-
///
943-
/// \param prefer_clang_types if this is true, type aliases in the
944-
/// __C module are resolved as Clang types.
945-
///
946939
std::pair<swift::Demangle::NodePointer, CompilerType>
947940
TypeSystemSwiftTypeRef::ResolveTypeAlias(swift::Demangle::Demangler &dem,
948941
swift::Demangle::NodePointer node,
@@ -1191,7 +1184,7 @@ TypeSystemSwiftTypeRef::Canonicalize(swift::Demangle::Demangler &dem,
11911184
Node::Kind::Structure, "Array");
11921185
}
11931186
case Node::Kind::SugaredDictionary:
1194-
// FIXME: This isnt covered by any test.
1187+
// FIXME: This isn't covered by any test.
11951188
assert(node->getNumChildren() == 2);
11961189
if (node->getNumChildren() != 2)
11971190
return node;
@@ -1205,15 +1198,27 @@ TypeSystemSwiftTypeRef::Canonicalize(swift::Demangle::Demangler &dem,
12051198

12061199
case Node::Kind::BoundGenericTypeAlias:
12071200
case Node::Kind::TypeAlias: {
1208-
auto node_clangtype = ResolveTypeAlias(dem, node);
1209-
if (CompilerType clang_type = node_clangtype.second) {
1210-
if (auto result = GetClangTypeNode(clang_type, dem))
1211-
return result;
1212-
else
1201+
// Safeguard against cyclic aliases.
1202+
for (unsigned alias_depth = 0; alias_depth < 64; ++alias_depth) {
1203+
auto node_clangtype = ResolveTypeAlias(dem, node);
1204+
if (CompilerType clang_type = node_clangtype.second) {
1205+
if (auto result = GetClangTypeNode(clang_type, dem))
1206+
return result;
1207+
// Failed to convert that clang type into a demangle node.
1208+
return node;
1209+
}
1210+
if (!node_clangtype.first)
1211+
return node;
1212+
if (node_clangtype.first == node)
12131213
return node;
1214+
node = node_clangtype.first;
1215+
if (node->getKind() != Node::Kind::BoundGenericTypeAlias &&
1216+
node->getKind() != Node::Kind::TypeAlias)
1217+
// Resolve any type aliases in the resolved type.
1218+
return GetCanonicalNode(dem, node);
1219+
// This type alias resolved to another type alias.
12141220
}
1215-
if (node_clangtype.first)
1216-
return node_clangtype.first;
1221+
// Hit the safeguard limit.
12171222
return node;
12181223
}
12191224
default:

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,18 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
490490
CompilerType LookupClangForwardType(llvm::StringRef name,
491491
llvm::ArrayRef<CompilerContext> decl_context);
492492

493+
/// Recursively resolves all type aliases.
494+
swift::Demangle::NodePointer
495+
ResolveAllTypeAliases(swift::Demangle::Demangler &dem,
496+
swift::Demangle::NodePointer node);
497+
498+
/// Resolve a type alias node and return a demangle tree for the
499+
/// resolved type. If the type alias resolves to a Clang type, return
500+
/// a Clang CompilerType.
501+
///
502+
/// \param prefer_clang_types if this is true, type aliases in the
503+
/// __C module are resolved as Clang types.
504+
///
493505
std::pair<swift::Demangle::NodePointer, CompilerType>
494506
ResolveTypeAlias(swift::Demangle::Demangler &dem,
495507
swift::Demangle::NodePointer node,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SWIFT_SOURCES = main.swift
2+
3+
include Makefile.rules
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from lldbsuite.test.lldbtest import *
2+
from lldbsuite.test.decorators import *
3+
import lldbsuite.test.lldbutil as lldbutil
4+
5+
class TestSwiftTypeAliasRecurtsive(TestBase):
6+
@swiftTest
7+
def test(self):
8+
"""Test that type aliases of type aliases can be resolved"""
9+
self.build()
10+
self.runCmd("settings set symbols.swift-validate-typesystem false")
11+
self.expect("log enable lldb types")
12+
target, process, _, _ = lldbutil.run_to_source_breakpoint(
13+
self, "break here", lldb.SBFileSpec("main.swift"))
14+
self.expect("frame variable cls", substrs=["ClassAlias?", "0x"])
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
open class MyClass<A, B> {}
2+
public typealias LocalAlias = Bool
3+
let anchor : LocalAlias = true
4+
public typealias ClassAlias = MyClass<LocalAlias, Bool>
5+
class Repro {
6+
let field: ClassAlias?
7+
init(cls: ClassAlias?) {
8+
self.field = cls // break here
9+
}
10+
}
11+
12+
Repro(cls: ClassAlias())

0 commit comments

Comments
 (0)