diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 4a6e7373990a9..8bc9b10ab134f 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -961,8 +961,9 @@ BuildDeclContext(llvm::StringRef mangled_name, return {}; } -/// Detect the AnyObject type alias. -static bool IsAnyObjectTypeAlias(swift::Demangle::NodePointer node) { +/// Detect a Swift stdlib type alias with the given identifier. +static bool IsStdlibTypeAlias(swift::Demangle::NodePointer node, + llvm::StringRef name) { using namespace swift::Demangle; if (!node || node->getKind() != Node::Kind::TypeAlias) return false; @@ -972,7 +973,7 @@ static bool IsAnyObjectTypeAlias(swift::Demangle::NodePointer node) { if (!module || !module->hasText() || module->getText() != swift::STDLIB_NAME) return false; NodePointer ident = node->getChild(1); - if (!ident || !ident->hasText() || ident->getText() != "AnyObject") + if (!ident || !ident->hasText() || ident->getText() != name) return false; return true; } @@ -1029,7 +1030,7 @@ TypeSystemSwiftTypeRef::ResolveTypeAlias(swift::Demangle::Demangler &dem, bool prefer_clang_types) { // Hardcode that the Swift.AnyObject type alias always resolves to // the builtin AnyObject type. - if (IsAnyObjectTypeAlias(node)) + if (IsStdlibTypeAlias(node, "AnyObject")) return {GetBuiltinAnyObjectNode(dem), {}}; using namespace swift::Demangle; @@ -1598,6 +1599,10 @@ static swift::Demangle::NodePointer Desugar(swift::Demangle::Demangler &dem, if (node->getNumChildren() != 1) return node; return node->getFirstChild(); + case Node::Kind::TypeAlias: + if (IsStdlibTypeAlias(node, "Void")) + return dem.createNode(Node::Kind::Tuple); + return node; default: return node; } @@ -5840,7 +5845,7 @@ bool TypeSystemSwiftTypeRef::IsTypedefType(opaque_compiler_type_t type) { // Sometimes SwiftASTContext returns the resolved AnyObject type. Demangler dem; NodePointer node = GetDemangledType(dem, AsMangledName(type)); - if (IsAnyObjectTypeAlias(node)) + if (IsStdlibTypeAlias(node, "AnyObject")) return impl(); } #endif diff --git a/lldb/test/API/lang/swift/void_typealias_generic/Makefile b/lldb/test/API/lang/swift/void_typealias_generic/Makefile new file mode 100644 index 0000000000000..cb73d9276d0ed --- /dev/null +++ b/lldb/test/API/lang/swift/void_typealias_generic/Makefile @@ -0,0 +1,2 @@ +SWIFT_SOURCES := main.swift +include Makefile.rules diff --git a/lldb/test/API/lang/swift/void_typealias_generic/TestSwiftVoidTypealiasGeneric.py b/lldb/test/API/lang/swift/void_typealias_generic/TestSwiftVoidTypealiasGeneric.py new file mode 100644 index 0000000000000..4028934203234 --- /dev/null +++ b/lldb/test/API/lang/swift/void_typealias_generic/TestSwiftVoidTypealiasGeneric.py @@ -0,0 +1,27 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil + + +class TestSwiftVoidTypealiasGeneric(TestBase): + @swiftTest + def test(self): + self.build() + self.runCmd("settings set symbols.swift-enable-ast-context false") + lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec("main.swift") + ) + + frame = self.frame() + + box_of_void = frame.FindVariable("boxOfVoid") + lldbutil.check_variable(self, box_of_void, num_children=2) + tag = box_of_void.GetChildMemberWithName("tag") + lldbutil.check_variable(self, tag, value="7") + + nested_void = frame.FindVariable("nestedVoid") + lldbutil.check_variable(self, nested_void, num_children=2) + snd = nested_void.GetChildAtIndex(1) + lldbutil.check_variable(self, snd, value="42") + diff --git a/lldb/test/API/lang/swift/void_typealias_generic/main.swift b/lldb/test/API/lang/swift/void_typealias_generic/main.swift new file mode 100644 index 0000000000000..5388897c87653 --- /dev/null +++ b/lldb/test/API/lang/swift/void_typealias_generic/main.swift @@ -0,0 +1,13 @@ +public struct Box { + public let payload: T + public let tag: Int +} + +func f() { + let boxOfVoid = Box(payload: (), tag: 7) + let nestedVoid: (Void, Int) = ((), 42) + + print("break here") +} + +f() diff --git a/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp b/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp index c782f6c78c201..5fd2615cb6061 100644 --- a/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp +++ b/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp @@ -1017,6 +1017,24 @@ TEST_F(TestTypeSystemSwiftTypeRef, Error) { } } +TEST_F(TestTypeSystemSwiftTypeRef, CanonicalizeVoidTypeAlias) { + using namespace swift::Demangle; + Demangler dem; + TestingNodeBuilder b(dem); + { + // Swift.Void on its own. + NodePointer void_alias = b.Node( + Node::Kind::TypeAlias, b.Node(Node::Kind::Module, swift::STDLIB_NAME), + b.Node(Node::Kind::Identifier, "Void")); + CompilerType sugared = GetCompilerType(b.Mangle(b.GlobalType(void_alias))); + CompilerType empty_tuple = + GetCompilerType(b.Mangle(b.GlobalType(b.Node(Node::Kind::Tuple)))); + ASSERT_EQ(sugared.GetCanonicalType().GetMangledTypeName(), + empty_tuple.GetMangledTypeName()); + ASSERT_TRUE(sugared.GetCanonicalType().IsVoidType()); + } +} + TEST_F(TestTypeSystemSwiftTypeRef, Canonicalize) { using namespace swift::Demangle; Demangler dem;