Skip to content

Commit 3799a3f

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.
1 parent 0a257a1 commit 3799a3f

File tree

13 files changed

+184
-132
lines changed

13 files changed

+184
-132
lines changed

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

Lines changed: 21 additions & 4 deletions
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

Lines changed: 20 additions & 10 deletions
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

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,45 +2090,42 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class(
20902090
if (!error.Success())
20912091
return false;
20922092

2093+
bool is_clang_type = false;
20932094
auto tss = class_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>();
2095+
if (!tss) {
2096+
is_clang_type = true;
2097+
if (auto module_sp = in_value.GetModule()) {
2098+
auto type_system_or_err =
2099+
module_sp->GetTypeSystemForLanguage(lldb::eLanguageTypeSwift);
2100+
if (!type_system_or_err) {
2101+
llvm::consumeError(type_system_or_err.takeError());
2102+
return false;
2103+
}
2104+
auto ts_sp = *type_system_or_err;
2105+
tss =
2106+
llvm::cast<TypeSystemSwift>(ts_sp.get())->GetTypeSystemSwiftTypeRef();
2107+
} else if (auto target_sp = in_value.GetTargetSP()) {
2108+
auto type_system_or_err =
2109+
target_sp->GetScratchTypeSystemForLanguage(lldb::eLanguageTypeSwift);
2110+
if (!type_system_or_err) {
2111+
llvm::consumeError(type_system_or_err.takeError());
2112+
return false;
2113+
}
2114+
auto ts_sp = *type_system_or_err;
2115+
tss =
2116+
llvm::cast<TypeSystemSwift>(ts_sp.get())->GetTypeSystemSwiftTypeRef();
2117+
}
2118+
}
20942119
if (!tss)
20952120
return false;
2121+
20962122
address.SetRawAddress(instance_ptr);
20972123
auto ts = tss->GetTypeSystemSwiftTypeRef();
20982124
if (!ts)
20992125
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-
{
2126+
2127+
auto resolve_swift = [&]() {
2128+
// Scope reflection_ctx to minimize its lock scope.
21322129
ThreadSafeReflectionContext reflection_ctx = GetReflectionContext();
21332130
if (!reflection_ctx)
21342131
return false;
@@ -2172,10 +2169,16 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class(
21722169
return false;
21732170
}
21742171
}
2175-
2176-
LLDB_LOG(log, "dynamic type of instance_ptr {0:x} is {1}", instance_ptr,
2177-
class_type.GetMangledTypeName());
21782172
class_type_or_name.SetCompilerType(dynamic_type);
2173+
LLDB_LOG(GetLog(LLDBLog::Types),
2174+
"dynamic type of instance_ptr {0:x} is {1}", instance_ptr,
2175+
class_type.GetMangledTypeName());
2176+
return true;
2177+
};
2178+
2179+
if (!resolve_swift()) {
2180+
// Ask the Objective-C runtime about Objective-C types.
2181+
return false;
21792182
}
21802183

21812184
#ifndef NDEBUG
@@ -2833,12 +2836,12 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_IndirectEnumCase(
28332836

28342837
return GetDynamicTypeAndAddress(*valobj_sp, use_dynamic, class_type_or_name,
28352838
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;
28412839
}
2840+
2841+
// This is most likely a statically known type.
2842+
address.SetLoadAddress(box_value, &GetProcess().GetTarget());
2843+
value_type = Value::GetValueTypeFromAddressType(eAddressTypeLoad);
2844+
return true;
28422845
}
28432846

28442847
void SwiftLanguageRuntime::DumpTyperef(CompilerType type,
@@ -3156,22 +3159,27 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
31563159
return false;
31573160

31583161
LLDB_SCOPED_TIMER();
3162+
CompilerType val_type(in_value.GetCompilerType());
3163+
Value::ValueType static_value_type = Value::ValueType::Invalid;
31593164

31603165
// 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);
3166+
if (in_value.GetObjectRuntimeLanguage() == eLanguageTypeObjC) {
3167+
if (GetDynamicTypeAndAddress_ClangType(in_value, use_dynamic,
3168+
class_type_or_name, address,
3169+
value_type, local_buffer))
3170+
return true;
3171+
return GetDynamicTypeAndAddress_Class(in_value, val_type, use_dynamic,
3172+
class_type_or_name, address,
3173+
static_value_type, local_buffer);
3174+
}
31653175

31663176
if (!CouldHaveDynamicValue(in_value))
31673177
return false;
31683178

3169-
CompilerType val_type(in_value.GetCompilerType());
31703179
Flags type_info(val_type.GetTypeInfo());
31713180
if (!type_info.AnySet(eTypeIsSwift))
31723181
return false;
31733182

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

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

Lines changed: 21 additions & 17 deletions
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)