diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp index d3639f5a52624..b5ff3403343a7 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp @@ -1527,6 +1527,11 @@ CompilerType SwiftLanguageRuntimeImpl::GetChildCompilerTypeAtIndex( lldb::addr_t pointer = valobj->GetPointerValue(); reflection_ctx->ForEachSuperClassType( &tip, pointer, [&](SuperClassType sc) -> bool { + // If the typeref is invalid, we don't want to process it (for + // example, this could be an artifical ObjC class). + if (!sc.get_typeref()) + return false; + if (!found_start) { // The ValueObject always points to the same class instance, // even when querying base classes. Drop base classes until we @@ -2013,7 +2018,8 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_Class( } Log *log(GetLog(LLDBLog::Types)); ThreadSafeReflectionContext reflection_ctx = GetReflectionContext(); - const auto *typeref = reflection_ctx->readTypeFromInstance(instance_ptr); + const auto *typeref = + reflection_ctx->readTypeFromInstance(instance_ptr, true); if (!typeref) { LLDB_LOGF(log, "could not read typeref for type: %s (instance_ptr = 0x%" PRIx64 diff --git a/lldb/test/API/lang/swift/artificial_subclass/Makefile b/lldb/test/API/lang/swift/artificial_subclass/Makefile new file mode 100644 index 0000000000000..cb73d9276d0ed --- /dev/null +++ b/lldb/test/API/lang/swift/artificial_subclass/Makefile @@ -0,0 +1,2 @@ +SWIFT_SOURCES := main.swift +include Makefile.rules diff --git a/lldb/test/API/lang/swift/artificial_subclass/TestSwiftArtificialSubclass.py b/lldb/test/API/lang/swift/artificial_subclass/TestSwiftArtificialSubclass.py new file mode 100644 index 0000000000000..b75fe87c2f4cf --- /dev/null +++ b/lldb/test/API/lang/swift/artificial_subclass/TestSwiftArtificialSubclass.py @@ -0,0 +1,22 @@ +import lldb +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * +import lldbsuite.test.lldbutil as lldbutil +import unittest2 + + +class TestSwiftArtificialSubclass(TestBase): + @skipUnlessObjCInterop + @swiftTest + def test(self): + """ Test that displaying an artificial type works correctly""" + self.build() + _, _, _, _ = lldbutil.run_to_source_breakpoint( + self, "break here", lldb.SBFileSpec("main.swift") + ) + + + self.expect( + "frame variable m", + substrs=["Subclass)", "Superclass", "a = 42", "b = 97"] + ) diff --git a/lldb/test/API/lang/swift/artificial_subclass/main.swift b/lldb/test/API/lang/swift/artificial_subclass/main.swift new file mode 100644 index 0000000000000..8431dbd02631f --- /dev/null +++ b/lldb/test/API/lang/swift/artificial_subclass/main.swift @@ -0,0 +1,19 @@ +import ObjectiveC + +class Superclass { + let a = 42 +} + +class Subclass: Superclass { + let b = 97 + + override init() { + super.init() + let c: AnyClass = objc_allocateClassPair(Subclass.self, "DynamicSubclass", 0)! + objc_registerClassPair(c); + object_setClass(self, c) + } +} + +let m = Subclass() +print(m) // break here