diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp index 8649156be370e..2cf73744ad4b8 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp @@ -1295,9 +1295,7 @@ TypeSystemSwiftTypeRef::GetCanonicalNode(swift::Demangle::Demangler &dem, // SomeAlias because it tries to // preserve all sugar. using namespace swift::Demangle; - NodePointer transformed = Canonicalize(dem, node, flavor); - if (node != transformed) - return transformed; + node = Canonicalize(dem, node, flavor); llvm::SmallVector children; bool changed = false; diff --git a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h index 220b7560f0f88..60be391a3b54c 100644 --- a/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h +++ b/lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h @@ -67,7 +67,10 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift { /// \} /// Provided only for unit tests. + /// \{ + friend struct TestTypeSystemSwiftTypeRef; TypeSystemSwiftTypeRef(); + /// \} ~TypeSystemSwiftTypeRef(); TypeSystemSwiftTypeRef(Module &module); /// Get the corresponding SwiftASTContext, and create one if necessary. diff --git a/lldb/test/API/lang/swift/clangimporter/objc_optional_dict/Makefile b/lldb/test/API/lang/swift/clangimporter/objc_optional_dict/Makefile new file mode 100644 index 0000000000000..2a69023633b34 --- /dev/null +++ b/lldb/test/API/lang/swift/clangimporter/objc_optional_dict/Makefile @@ -0,0 +1,3 @@ +SWIFT_SOURCES := main.swift + +include Makefile.rules diff --git a/lldb/test/API/lang/swift/clangimporter/objc_optional_dict/TestSwiftObjCOptionalDict.py b/lldb/test/API/lang/swift/clangimporter/objc_optional_dict/TestSwiftObjCOptionalDict.py new file mode 100644 index 0000000000000..4fabc01c0d8d4 --- /dev/null +++ b/lldb/test/API/lang/swift/clangimporter/objc_optional_dict/TestSwiftObjCOptionalDict.py @@ -0,0 +1,17 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil + +class TestSwiftObjCOptionalDict(TestBase): + @skipUnlessDarwin + @swiftTest + def test(self): + self.build() + lldbutil.run_to_source_breakpoint( + self, 'break here', lldb.SBFileSpec('main.swift')) + + # This should from DWRAF, without loading a Swift module. + self.expect("settings set symbols.swift-typesystem-compiler-fallback false") + d = self.frame().FindVariable("dict") + lldbutil.check_variable(self, d, summary='0 key/value pairs', value='some') diff --git a/lldb/test/API/lang/swift/clangimporter/objc_optional_dict/main.swift b/lldb/test/API/lang/swift/clangimporter/objc_optional_dict/main.swift new file mode 100644 index 0000000000000..a369469c3c2ed --- /dev/null +++ b/lldb/test/API/lang/swift/clangimporter/objc_optional_dict/main.swift @@ -0,0 +1,7 @@ +import Foundation +func f() { + var dict : [NSKeyValueChangeKey : Any]? = [:] + print("break here") +} + +f() diff --git a/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp b/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp index 9f23aef1f90b4..10e515e078305 100644 --- a/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp +++ b/lldb/unittests/Symbol/TestTypeSystemSwiftTypeRef.cpp @@ -23,6 +23,7 @@ using namespace lldb; using namespace lldb_private; using namespace llvm; +namespace lldb_private { struct TestTypeSystemSwiftTypeRef : public testing::Test { std::shared_ptr m_swift_ts; @@ -32,7 +33,13 @@ struct TestTypeSystemSwiftTypeRef : public testing::Test { ConstString internalized(mangled_name); return m_swift_ts->GetTypeFromMangledTypename(internalized); } + swift::Demangle::NodePointer + DemangleCanonicalOutermostType(swift::Demangle::Demangler &dem, + lldb::opaque_compiler_type_t type) { + return m_swift_ts->DemangleCanonicalOutermostType(dem, type); + } }; +} // namespace lldb_private /// Helper class to conveniently construct demangle tree hierarchies. class NodeBuilder { @@ -79,6 +86,15 @@ class NodeBuilder { Node(Node::Kind::Module, swift::STDLIB_NAME), Node(Node::Kind::Identifier, swift::BUILTIN_TYPE_NAME_FLOAT))); } + NodePointer DesugaredOptionalType(NodePointer type) { + return Node(Node::Kind::Type, + Node(Node::Kind::BoundGenericEnum, + Node(Node::Kind::Type, + Node(Node::Kind::Enum, + Node(Node::Kind::Module, swift::STDLIB_NAME), + Node(Node::Kind::Identifier, "Optional"))), + Node(Node::Kind::TypeList, type))); + } NodePointer GlobalTypeMangling(NodePointer type) { assert(type && type->getKind() == Node::Kind::Type); return Node(Node::Kind::Global, Node(Node::Kind::TypeMangling, type)); @@ -1025,3 +1041,42 @@ TEST_F(TestTypeSystemSwiftTypeRef, Error) { ASSERT_TRUE(m_swift_ts->ContainsError(opaque)); } } + +TEST_F(TestTypeSystemSwiftTypeRef, Canonicalize) { + using namespace swift::Demangle; + Demangler dem; + NodeBuilder b(dem); + { + { + NodePointer n0 = + b.GlobalType(b.Node(Node::Kind::SugaredOptional, b.IntType())); + NodePointer n1 = + b.GlobalTypeMangling(b.DesugaredOptionalType(b.IntType())); + CompilerType sugared = GetCompilerType(b.Mangle(n0)); + CompilerType desugared = GetCompilerType(b.Mangle(n1)); + ASSERT_EQ(sugared.GetCanonicalType().GetMangledTypeName(), + desugared.GetMangledTypeName()); + } + { + NodePointer n0 = b.GlobalType( + b.Node(Node::Kind::SugaredOptional, + b.Node(Node::Kind::Type, + b.Node(Node::Kind::SugaredOptional, b.IntType())))); + NodePointer n1 = b.GlobalTypeMangling( + b.DesugaredOptionalType(b.DesugaredOptionalType(b.IntType()))); + CompilerType sugared = GetCompilerType(b.Mangle(n0)); + CompilerType desugared = GetCompilerType(b.Mangle(n1)); + ASSERT_EQ(sugared.GetCanonicalType().GetMangledTypeName(), + desugared.GetMangledTypeName()); + + NodePointer n2 = b.GlobalType( + DemangleCanonicalOutermostType(dem, sugared.GetOpaqueQualType())); + NodePointer n3 = b.GlobalTypeMangling(b.DesugaredOptionalType( + b.Node(Node::Kind::SugaredOptional, b.IntType()))); + CompilerType single_desugared2 = GetCompilerType(b.Mangle(n2)); + CompilerType single_desugared3 = GetCompilerType(b.Mangle(n3)); + ASSERT_EQ(single_desugared2.GetMangledTypeName(), + single_desugared3.GetMangledTypeName()); + } + } +}