Skip to content

Commit 2bca29b

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 2bca29b

File tree

6 files changed

+139
-81
lines changed

6 files changed

+139
-81
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/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
}

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

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ class SwiftASTContext : public TypeSystemSwift {
182182

183183
protected:
184184
// Constructors and destructors
185-
SwiftASTContext(std::string description,
185+
SwiftASTContext(std::string description, lldb::ModuleSP module_sp,
186186
TypeSystemSwiftTypeRefSP typeref_typesystem);
187187

188188
public:
@@ -923,6 +923,20 @@ class SwiftASTContext : public TypeSystemSwift {
923923

924924
CompilerType GetAsClangType(ConstString mangled_name);
925925

926+
/// Retrieve the stored properties for the given nominal type declaration.
927+
llvm::ArrayRef<swift::VarDecl *>
928+
GetStoredProperties(swift::NominalTypeDecl *nominal);
929+
930+
SwiftEnumDescriptor *GetCachedEnumInfo(lldb::opaque_compiler_type_t type);
931+
932+
friend class CompilerType;
933+
934+
void ApplyDiagnosticOptions();
935+
936+
/// Apply a PathMappingList dictionary on all search paths in the
937+
/// ClangImporterOptions.
938+
void RemapClangImporterOptions(const PathMappingList &path_map);
939+
926940
/// Data members.
927941
/// @{
928942
std::weak_ptr<TypeSystemSwiftTypeRef> m_typeref_typesystem;
@@ -993,8 +1007,6 @@ class SwiftASTContext : public TypeSystemSwift {
9931007
typedef ThreadSafeDenseSet<const char *> SwiftMangledNameSet;
9941008
SwiftMangledNameSet m_negative_type_cache;
9951009

996-
/// @}
997-
9981010
/// Record the set of stored properties for each nominal type declaration
9991011
/// for which we've asked this question.
10001012
///
@@ -1004,19 +1016,7 @@ class SwiftASTContext : public TypeSystemSwift {
10041016
llvm::DenseMap<swift::NominalTypeDecl *, std::vector<swift::VarDecl *>>
10051017
m_stored_properties;
10061018

1007-
/// Retrieve the stored properties for the given nominal type declaration.
1008-
llvm::ArrayRef<swift::VarDecl *>
1009-
GetStoredProperties(swift::NominalTypeDecl *nominal);
1010-
1011-
SwiftEnumDescriptor *GetCachedEnumInfo(lldb::opaque_compiler_type_t type);
1012-
1013-
friend class CompilerType;
1014-
1015-
void ApplyDiagnosticOptions();
1016-
1017-
/// Apply a PathMappingList dictionary on all search paths in the
1018-
/// ClangImporterOptions.
1019-
void RemapClangImporterOptions(const PathMappingList &path_map);
1019+
/// @}
10201020
};
10211021

10221022
/// Deprecated.
@@ -1033,9 +1033,9 @@ class SwiftASTContextForModule : public SwiftASTContext {
10331033
static bool classof(const TypeSystem *ts) { return ts->isA(&ID); }
10341034
/// \}
10351035

1036-
SwiftASTContextForModule(std::string description,
1036+
SwiftASTContextForModule(std::string description, lldb::ModuleSP module_sp,
10371037
TypeSystemSwiftTypeRefSP typeref_typesystem)
1038-
: SwiftASTContext(description, typeref_typesystem) {}
1038+
: SwiftASTContext(description, module_sp, typeref_typesystem) {}
10391039
virtual ~SwiftASTContextForModule();
10401040
};
10411041

@@ -1053,6 +1053,7 @@ class SwiftASTContextForExpressions : public SwiftASTContext {
10531053
/// \}
10541054

10551055
SwiftASTContextForExpressions(std::string description,
1056+
lldb::ModuleSP module_sp,
10561057
TypeSystemSwiftTypeRefSP typeref_typesystem);
10571058
virtual ~SwiftASTContextForExpressions();
10581059

0 commit comments

Comments
 (0)