Skip to content

Commit 8458d10

Browse files
committed
[lldb] Resolve Swift-implemented Objective-C classes using Swift runtime
if the Objective-C runtime fails. If an Objective-C class is lazy, the Objective-C runtie may not have materialized class metadata for it. However, if the class is actually implemented in Swift, we can still resolve it using the Swift runtime. We should probably also add the same logic to the Objective-C runtime, but I don't want risk adding an inifinite recursion at this point in the release. rdar://145253225
1 parent 0a257a1 commit 8458d10

File tree

13 files changed

+185
-147
lines changed

13 files changed

+185
-147
lines changed

lldb/source/Plugins/ExpressionParser/Swift/SwiftREPL.cpp

+21-4
Original file line numberDiff line numberDiff line change
@@ -501,13 +501,30 @@ bool SwiftREPL::PrintOneVariable(Debugger &debugger, StreamFileSP &output_sp,
501501
options.SetRevealEmptyAggregates(false);
502502
options.SetHidePointerValue(true);
503503
options.SetVariableFormatDisplayLanguage(lldb::eLanguageTypeSwift);
504-
options.SetDeclPrintingHelper([](ConstString type_name,
505-
ConstString var_name,
506-
const DumpValueObjectOptions &options,
507-
Stream &stream) -> bool {
504+
options.SetDeclPrintingHelper([&](ConstString type_name,
505+
ConstString var_name,
506+
const DumpValueObjectOptions &options,
507+
Stream &stream) -> bool {
508508
if (!type_name || !var_name)
509509
return false;
510510

511+
// Try to get the SwiftASTContext representation of the type. It
512+
// will hide Objective-C implemention details that are not
513+
// publicly declared in the SDK.
514+
if (valobj_sp) {
515+
auto static_valobj_sp = valobj_sp->GetStaticValue();
516+
auto dynamic_valobj_sp =
517+
valobj_sp->GetDynamicValue(lldb::eDynamicCanRunTarget);
518+
if (static_valobj_sp && dynamic_valobj_sp) {
519+
CompilerType static_type = static_valobj_sp->GetCompilerType();
520+
CompilerType dynamic_type = dynamic_valobj_sp->GetCompilerType();
521+
auto ts =
522+
dynamic_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>();
523+
if (ts &&
524+
ts->IsImportedType(dynamic_type.GetOpaqueQualType(), nullptr))
525+
type_name = static_type.GetDisplayTypeName();
526+
}
527+
}
511528
std::string type_name_str(type_name ? type_name.GetCString() : "");
512529
for (auto iter = type_name_str.find(" *"); iter != std::string::npos;
513530
iter = type_name_str.find(" *")) {

lldb/source/Plugins/Language/Swift/SwiftHashedContainer.cpp

+20-10
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ HashedCollectionConfig::RegisterSummaryProviders(
200200
AddCXXSummary(swift_category_sp, summaryProvider,
201201
m_summaryProviderName.AsCString(),
202202
m_emptyStorage_demangled, flags, false);
203+
AddCXXSummary(swift_category_sp, summaryProvider,
204+
m_summaryProviderName.AsCString(),
205+
m_nativeStorageRoot_demangled, flags, false);
203206
AddCXXSummary(swift_category_sp, summaryProvider,
204207
m_summaryProviderName.AsCString(),
205208
m_deferredBridgedStorage_demangledRegex, flags, true);
@@ -231,6 +234,9 @@ HashedCollectionConfig::RegisterSyntheticChildrenCreators(
231234
AddCXXSynthetic(swift_category_sp, creator,
232235
m_syntheticChildrenName.AsCString(),
233236
m_nativeStorage_demangledRegex, flags, true);
237+
AddCXXSynthetic(swift_category_sp, creator,
238+
m_syntheticChildrenName.AsCString(),
239+
m_nativeStorageRoot_demangled, flags, false);
234240
AddCXXSynthetic(swift_category_sp, creator,
235241
m_syntheticChildrenName.AsCString(),
236242
m_emptyStorage_demangled, flags, false);
@@ -648,18 +654,22 @@ HashedCollectionConfig::CreateHandler(ValueObject &valobj) const {
648654
return CreateNativeHandler(valobj_sp, storage_sp);
649655
}
650656

651-
ValueObjectSP variant_sp =
652-
valobj_sp->GetChildMemberWithName(g__variant, true);
653-
if (!variant_sp)
654-
return nullptr;
657+
lldb::addr_t storage_location = LLDB_INVALID_ADDRESS;
658+
if (type_name_cs == m_nativeStorageRoot_demangled)
659+
storage_location = valobj_sp->GetPointerValue();
660+
else {
661+
ValueObjectSP variant_sp =
662+
valobj_sp->GetChildMemberWithName(g__variant, true);
663+
if (!variant_sp)
664+
return nullptr;
655665

656-
ValueObjectSP bobject_sp =
657-
variant_sp->GetChildAtNamePath({g_object, g_rawValue});
658-
if (!bobject_sp)
659-
return nullptr;
666+
ValueObjectSP bobject_sp =
667+
variant_sp->GetChildAtNamePath({g_object, g_rawValue});
668+
if (!bobject_sp)
669+
return nullptr;
660670

661-
lldb::addr_t storage_location =
662-
bobject_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
671+
storage_location = bobject_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
672+
}
663673
if (storage_location == LLDB_INVALID_ADDRESS)
664674
return nullptr;
665675

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp

+55-61
Original file line numberDiff line numberDiff line change
@@ -2022,21 +2022,6 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Pack(
20222022
return true;
20232023
}
20242024

2025-
static bool IsPrivateNSClass(NodePointer node) {
2026-
if (!node || node->getKind() != Node::Kind::Type ||
2027-
node->getNumChildren() == 0)
2028-
return false;
2029-
NodePointer classNode = node->getFirstChild();
2030-
if (!classNode || classNode->getKind() != Node::Kind::Class ||
2031-
classNode->getNumChildren() < 2)
2032-
return false;
2033-
for (NodePointer child : *classNode)
2034-
if (child->getKind() == Node::Kind::Identifier && child->hasText())
2035-
return child->getText().starts_with("__NS") ||
2036-
child->getText().starts_with("NSTaggedPointer");
2037-
return false;
2038-
}
2039-
20402025
CompilerType SwiftLanguageRuntime::GetDynamicTypeAndAddress_EmbeddedClass(
20412026
uint64_t instance_ptr, CompilerType class_type) {
20422027
ThreadSafeReflectionContext reflection_ctx = GetReflectionContext();
@@ -2091,44 +2076,41 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class(
20912076
return false;
20922077

20932078
auto tss = class_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>();
2079+
if (!tss) {
2080+
// This could be an Objective-C type implemented in Swift. Get the
2081+
// Swift typesystem.
2082+
if (auto module_sp = in_value.GetModule()) {
2083+
auto type_system_or_err =
2084+
module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeSwift);
2085+
if (!type_system_or_err) {
2086+
llvm::consumeError(type_system_or_err.takeError());
2087+
return false;
2088+
}
2089+
auto ts_sp = *type_system_or_err;
2090+
tss =
2091+
llvm::cast<TypeSystemSwift>(ts_sp.get())->GetTypeSystemSwiftTypeRef();
2092+
} else if (auto target_sp = in_value.GetTargetSP()) {
2093+
auto type_system_or_err =
2094+
target_sp->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeSwift);
2095+
if (!type_system_or_err) {
2096+
llvm::consumeError(type_system_or_err.takeError());
2097+
return false;
2098+
}
2099+
auto ts_sp = *type_system_or_err;
2100+
tss =
2101+
llvm::cast<TypeSystemSwift>(ts_sp.get())->GetTypeSystemSwiftTypeRef();
2102+
}
2103+
}
20942104
if (!tss)
20952105
return false;
2106+
20962107
address.SetRawAddress(instance_ptr);
20972108
auto ts = tss->GetTypeSystemSwiftTypeRef();
20982109
if (!ts)
20992110
return false;
2100-
// Ask the Objective-C runtime about Objective-C types.
2101-
if (tss->IsImportedType(class_type.GetOpaqueQualType(), nullptr))
2102-
if (auto *objc_runtime =
2103-
SwiftLanguageRuntime::GetObjCRuntime(GetProcess())) {
2104-
Value::ValueType value_type;
2105-
if (objc_runtime->GetDynamicTypeAndAddress(in_value, use_dynamic,
2106-
class_type_or_name, address,
2107-
value_type, local_buffer)) {
2108-
bool found = false;
2109-
// Return the most specific class which we can get the typeref.
2110-
ForEachSuperClassType(in_value, [&](SuperClassType sc) -> bool {
2111-
if (auto *tr = sc.get_typeref()) {
2112-
swift::Demangle::Demangler dem;
2113-
swift::Demangle::NodePointer node = tr->getDemangling(dem);
2114-
// Skip private Foundation types since it's unlikely that would be
2115-
// useful to users.
2116-
if (IsPrivateNSClass(node))
2117-
return false;
2118-
class_type_or_name.SetCompilerType(ts->RemangleAsType(
2119-
dem, node, swift::Mangle::ManglingFlavor::Default));
2120-
found = true;
2121-
return true;
2122-
}
2123-
return false;
2124-
});
2125-
return found;
2126-
}
2127-
return false;
2128-
}
2129-
Log *log(GetLog(LLDBLog::Types));
2130-
// Scope reflection_ctx to minimize its lock scope.
2131-
{
2111+
2112+
auto resolve_swift = [&]() {
2113+
// Scope reflection_ctx to minimize its lock scope.
21322114
ThreadSafeReflectionContext reflection_ctx = GetReflectionContext();
21332115
if (!reflection_ctx)
21342116
return false;
@@ -2172,10 +2154,17 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class(
21722154
return false;
21732155
}
21742156
}
2175-
2176-
LLDB_LOG(log, "dynamic type of instance_ptr {0:x} is {1}", instance_ptr,
2177-
class_type.GetMangledTypeName());
21782157
class_type_or_name.SetCompilerType(dynamic_type);
2158+
LLDB_LOG(GetLog(LLDBLog::Types),
2159+
"dynamic type of instance_ptr {0:x} is {1}", instance_ptr,
2160+
class_type.GetMangledTypeName());
2161+
return true;
2162+
};
2163+
2164+
if (!resolve_swift()) {
2165+
// When returning false here, the next compatible runtime (=
2166+
// Objective-C) will get ask to resolve this type.
2167+
return false;
21792168
}
21802169

21812170
#ifndef NDEBUG
@@ -2833,12 +2822,12 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_IndirectEnumCase(
28332822

28342823
return GetDynamicTypeAndAddress(*valobj_sp, use_dynamic, class_type_or_name,
28352824
address, value_type, local_buffer);
2836-
} else {
2837-
// This is most likely a statically known type.
2838-
address.SetLoadAddress(box_value, &GetProcess().GetTarget());
2839-
value_type = Value::GetValueTypeFromAddressType(eAddressTypeLoad);
2840-
return true;
28412825
}
2826+
2827+
// This is most likely a statically known type.
2828+
address.SetLoadAddress(box_value, &GetProcess().GetTarget());
2829+
value_type = Value::GetValueTypeFromAddressType(eAddressTypeLoad);
2830+
return true;
28422831
}
28432832

28442833
void SwiftLanguageRuntime::DumpTyperef(CompilerType type,
@@ -3156,22 +3145,27 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
31563145
return false;
31573146

31583147
LLDB_SCOPED_TIMER();
3148+
CompilerType val_type(in_value.GetCompilerType());
3149+
Value::ValueType static_value_type = Value::ValueType::Invalid;
31593150

31603151
// Try to import a Clang type into Swift.
3161-
if (in_value.GetObjectRuntimeLanguage() == eLanguageTypeObjC)
3162-
return GetDynamicTypeAndAddress_ClangType(in_value, use_dynamic,
3163-
class_type_or_name, address,
3164-
value_type, local_buffer);
3152+
if (in_value.GetObjectRuntimeLanguage() == eLanguageTypeObjC) {
3153+
if (GetDynamicTypeAndAddress_ClangType(in_value, use_dynamic,
3154+
class_type_or_name, address,
3155+
value_type, local_buffer))
3156+
return true;
3157+
return GetDynamicTypeAndAddress_Class(in_value, val_type, use_dynamic,
3158+
class_type_or_name, address,
3159+
static_value_type, local_buffer);
3160+
}
31653161

31663162
if (!CouldHaveDynamicValue(in_value))
31673163
return false;
31683164

3169-
CompilerType val_type(in_value.GetCompilerType());
31703165
Flags type_info(val_type.GetTypeInfo());
31713166
if (!type_info.AnySet(eTypeIsSwift))
31723167
return false;
31733168

3174-
Value::ValueType static_value_type = Value::ValueType::Invalid;
31753169
bool success = false;
31763170
bool is_indirect_enum_case = IsIndirectEnumCase(in_value);
31773171
// Type kinds with instance metadata don't need generic type resolution.

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

+21-17
Original file line numberDiff line numberDiff line change
@@ -996,7 +996,7 @@ SwiftASTContext::SwiftASTContext()
996996
}
997997
#endif
998998

999-
SwiftASTContext::SwiftASTContext(std::string description,
999+
SwiftASTContext::SwiftASTContext(std::string description, ModuleSP module_sp,
10001000
TypeSystemSwiftTypeRefSP typeref_typesystem)
10011001
: TypeSystemSwift(), m_typeref_typesystem(typeref_typesystem),
10021002
m_compiler_invocation_ap(new swift::CompilerInvocation()),
@@ -1006,6 +1006,7 @@ SwiftASTContext::SwiftASTContext(std::string description,
10061006
"Swift AST context instantiation is disabled!");
10071007

10081008
m_description = description;
1009+
m_module = module_sp.get();
10091010

10101011
// Set the clang modules cache path.
10111012
m_compiler_invocation_ap->setClangModuleCachePath(
@@ -2431,7 +2432,8 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
24312432
// If there is a target this may be a fallback scratch context.
24322433
std::shared_ptr<SwiftASTContext> swift_ast_sp(
24332434
static_cast<SwiftASTContext *>(new SwiftASTContextForModule(
2434-
m_description, typeref_typesystem.GetTypeSystemSwiftTypeRef())));
2435+
m_description, module.shared_from_this(),
2436+
typeref_typesystem.GetTypeSystemSwiftTypeRef())));
24352437
bool suppress_config_log = false;
24362438
auto defer_log =
24372439
llvm::make_scope_exit([swift_ast_sp, &suppress_config_log] {
@@ -2444,7 +2446,6 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
24442446

24452447
// This is a module AST context, mark it as such.
24462448
swift_ast_sp->m_is_scratch_context = false;
2447-
swift_ast_sp->m_module = &module;
24482449
swift_ast_sp->GetLanguageOptions().EnableAccessControl = false;
24492450
swift_ast_sp->GetLanguageOptions().EnableCXXInterop =
24502451
module.IsSwiftCxxInteropEnabled();
@@ -2781,7 +2782,8 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc,
27812782
return {};
27822783
}
27832784
swift_ast_sp.reset(new SwiftASTContextForExpressions(
2784-
m_description, typeref_typesystem.GetTypeSystemSwiftTypeRef()));
2785+
m_description, module_sp,
2786+
typeref_typesystem.GetTypeSystemSwiftTypeRef()));
27852787
// This is a scratch AST context, mark it as such.
27862788
swift_ast_sp->m_is_scratch_context = true;
27872789
auto &lang_opts = swift_ast_sp->GetLanguageOptions();
@@ -2796,10 +2798,10 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc,
27962798
}
27972799
swift_ast_sp.reset(
27982800
static_cast<SwiftASTContext *>(new SwiftASTContextForModule(
2799-
m_description, typeref_typesystem.GetTypeSystemSwiftTypeRef())));
2801+
m_description, module_sp,
2802+
typeref_typesystem.GetTypeSystemSwiftTypeRef())));
28002803
// This is a module AST context, mark it as such.
28012804
swift_ast_sp->m_is_scratch_context = false;
2802-
swift_ast_sp->m_module = module_sp.get();
28032805
auto &lang_opts = swift_ast_sp->GetLanguageOptions();
28042806
lang_opts.EnableAccessControl = false;
28052807
lang_opts.EnableCXXInterop = ShouldEnableCXXInterop(cu);
@@ -4695,14 +4697,10 @@ CompilerType SwiftASTContext::GetAsClangType(ConstString mangled_name) {
46954697
// that look like they might be come from Objective-C (or C) as
46964698
// Clang types. LLDB's Objective-C part is very robust against
46974699
// malformed object pointers, so this isn't very risky.
4698-
auto ts = GetTypeSystemSwiftTypeRef();
4699-
if (!ts)
4700-
return {};
4701-
Module *module = ts->GetModule();
4702-
if (!module)
4700+
if (!m_module)
47034701
return {};
47044702
auto type_system_or_err =
4705-
module->GetTypeSystemForLanguage(eLanguageTypeObjC);
4703+
m_module->GetTypeSystemForLanguage(eLanguageTypeObjC);
47064704
if (!type_system_or_err) {
47074705
llvm::consumeError(type_system_or_err.takeError());
47084706
return {};
@@ -4714,11 +4712,16 @@ CompilerType SwiftASTContext::GetAsClangType(ConstString mangled_name) {
47144712
return {};
47154713
DWARFASTParserClang *clang_ast_parser =
47164714
static_cast<DWARFASTParserClang *>(clang_ctx->GetDWARFParser());
4715+
4716+
SymbolContext sc;
4717+
m_module->CalculateSymbolContext(&sc);
47174718
CompilerType clang_type;
47184719
CompilerType imported_type = GetCompilerType(mangled_name);
4719-
if (auto ts =
4720-
imported_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>())
4721-
ts->IsImportedType(imported_type.GetOpaqueQualType(), &clang_type);
4720+
if (auto ts = imported_type.GetTypeSystem()
4721+
.dyn_cast_or_null<TypeSystemSwiftTypeRef>())
4722+
if (ts->IsImportedType(imported_type.GetOpaqueQualType(), nullptr))
4723+
if (TypeSP result = ts->LookupClangType(mangled_name, sc))
4724+
clang_type = result->GetForwardCompilerType();
47224725

47234726
// Import the Clang type into the Clang context.
47244727
if (!clang_type)
@@ -8930,8 +8933,9 @@ SwiftASTContext::GetASTVectorForModule(const Module *module) {
89308933
}
89318934

89328935
SwiftASTContextForExpressions::SwiftASTContextForExpressions(
8933-
std::string description, TypeSystemSwiftTypeRefSP typeref_typesystem)
8934-
: SwiftASTContext(std::move(description), typeref_typesystem) {
8936+
std::string description, ModuleSP module_sp,
8937+
TypeSystemSwiftTypeRefSP typeref_typesystem)
8938+
: SwiftASTContext(std::move(description), module_sp, typeref_typesystem) {
89358939
assert(llvm::isa<TypeSystemSwiftTypeRefForExpressions>(
89368940
m_typeref_typesystem.lock().get()));
89378941
}

0 commit comments

Comments
 (0)