Skip to content

Commit 4ce054c

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 4ce054c

File tree

13 files changed

+190
-105
lines changed

13 files changed

+190
-105
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: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2090,15 +2090,40 @@ 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))
2126+
auto resolve_objc = [&]() {
21022127
if (auto *objc_runtime =
21032128
SwiftLanguageRuntime::GetObjCRuntime(GetProcess())) {
21042129
Value::ValueType value_type;
@@ -2124,11 +2149,12 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class(
21242149
});
21252150
return found;
21262151
}
2127-
return false;
21282152
}
2129-
Log *log(GetLog(LLDBLog::Types));
2130-
// Scope reflection_ctx to minimize its lock scope.
2131-
{
2153+
return false;
2154+
};
2155+
2156+
auto resolve_swift = [&]() {
2157+
// Scope reflection_ctx to minimize its lock scope.
21322158
ThreadSafeReflectionContext reflection_ctx = GetReflectionContext();
21332159
if (!reflection_ctx)
21342160
return false;
@@ -2172,10 +2198,20 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_Class(
21722198
return false;
21732199
}
21742200
}
2175-
2176-
LLDB_LOG(log, "dynamic type of instance_ptr {0:x} is {1}", instance_ptr,
2201+
LLDB_LOG(GetLog(LLDBLog::Types),
2202+
"dynamic type of instance_ptr {0:x} is {1}", instance_ptr,
21772203
class_type.GetMangledTypeName());
21782204
class_type_or_name.SetCompilerType(dynamic_type);
2205+
return true;
2206+
};
2207+
2208+
if (!resolve_swift()) {
2209+
// Ask the Objective-C runtime about Objective-C types.
2210+
if (is_clang_type ||
2211+
!tss->IsImportedType(class_type.GetOpaqueQualType(), nullptr))
2212+
if (resolve_objc())
2213+
return true;
2214+
return false;
21792215
}
21802216

21812217
#ifndef NDEBUG
@@ -2833,12 +2869,12 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress_IndirectEnumCase(
28332869

28342870
return GetDynamicTypeAndAddress(*valobj_sp, use_dynamic, class_type_or_name,
28352871
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;
28412872
}
2873+
2874+
// This is most likely a statically known type.
2875+
address.SetLoadAddress(box_value, &GetProcess().GetTarget());
2876+
value_type = Value::GetValueTypeFromAddressType(eAddressTypeLoad);
2877+
return true;
28422878
}
28432879

28442880
void SwiftLanguageRuntime::DumpTyperef(CompilerType type,
@@ -3156,22 +3192,27 @@ bool SwiftLanguageRuntime::GetDynamicTypeAndAddress(
31563192
return false;
31573193

31583194
LLDB_SCOPED_TIMER();
3195+
CompilerType val_type(in_value.GetCompilerType());
3196+
Value::ValueType static_value_type = Value::ValueType::Invalid;
31593197

31603198
// 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);
3199+
if (in_value.GetObjectRuntimeLanguage() == eLanguageTypeObjC) {
3200+
if (GetDynamicTypeAndAddress_ClangType(in_value, use_dynamic,
3201+
class_type_or_name, address,
3202+
value_type, local_buffer))
3203+
return true;
3204+
return GetDynamicTypeAndAddress_Class(in_value, val_type, use_dynamic,
3205+
class_type_or_name, address,
3206+
static_value_type, local_buffer);
3207+
}
31653208

31663209
if (!CouldHaveDynamicValue(in_value))
31673210
return false;
31683211

3169-
CompilerType val_type(in_value.GetCompilerType());
31703212
Flags type_info(val_type.GetTypeInfo());
31713213
if (!type_info.AnySet(eTypeIsSwift))
31723214
return false;
31733215

3174-
Value::ValueType static_value_type = Value::ValueType::Invalid;
31753216
bool success = false;
31763217
bool is_indirect_enum_case = IsIndirectEnumCase(in_value);
31773218
// 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)