Skip to content

Commit e49951f

Browse files
Merge pull request #10548 from adrian-prantl/145253225
[lldb] Resolve Swift-implemented Objective-C classes using Swift runtime
2 parents 815013b + 8458d10 commit e49951f

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(
@@ -2441,7 +2442,8 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
24412442
// If there is a target this may be a fallback scratch context.
24422443
std::shared_ptr<SwiftASTContext> swift_ast_sp(
24432444
static_cast<SwiftASTContext *>(new SwiftASTContextForModule(
2444-
m_description, typeref_typesystem.GetTypeSystemSwiftTypeRef())));
2445+
m_description, module.shared_from_this(),
2446+
typeref_typesystem.GetTypeSystemSwiftTypeRef())));
24452447
bool suppress_config_log = false;
24462448
auto defer_log =
24472449
llvm::make_scope_exit([swift_ast_sp, &suppress_config_log] {
@@ -2454,7 +2456,6 @@ SwiftASTContext::CreateInstance(lldb::LanguageType language, Module &module,
24542456

24552457
// This is a module AST context, mark it as such.
24562458
swift_ast_sp->m_is_scratch_context = false;
2457-
swift_ast_sp->m_module = &module;
24582459
swift_ast_sp->GetLanguageOptions().EnableAccessControl = false;
24592460
swift_ast_sp->GetLanguageOptions().EnableCXXInterop =
24602461
module.IsSwiftCxxInteropEnabled();
@@ -2791,7 +2792,8 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc,
27912792
return {};
27922793
}
27932794
swift_ast_sp.reset(new SwiftASTContextForExpressions(
2794-
m_description, typeref_typesystem.GetTypeSystemSwiftTypeRef()));
2795+
m_description, module_sp,
2796+
typeref_typesystem.GetTypeSystemSwiftTypeRef()));
27952797
// This is a scratch AST context, mark it as such.
27962798
swift_ast_sp->m_is_scratch_context = true;
27972799
auto &lang_opts = swift_ast_sp->GetLanguageOptions();
@@ -2806,10 +2808,10 @@ SwiftASTContext::CreateInstance(const SymbolContext &sc,
28062808
}
28072809
swift_ast_sp.reset(
28082810
static_cast<SwiftASTContext *>(new SwiftASTContextForModule(
2809-
m_description, typeref_typesystem.GetTypeSystemSwiftTypeRef())));
2811+
m_description, module_sp,
2812+
typeref_typesystem.GetTypeSystemSwiftTypeRef())));
28102813
// This is a module AST context, mark it as such.
28112814
swift_ast_sp->m_is_scratch_context = false;
2812-
swift_ast_sp->m_module = module_sp.get();
28132815
auto &lang_opts = swift_ast_sp->GetLanguageOptions();
28142816
lang_opts.EnableAccessControl = false;
28152817
lang_opts.EnableCXXInterop = ShouldEnableCXXInterop(cu);
@@ -4705,14 +4707,10 @@ CompilerType SwiftASTContext::GetAsClangType(ConstString mangled_name) {
47054707
// that look like they might be come from Objective-C (or C) as
47064708
// Clang types. LLDB's Objective-C part is very robust against
47074709
// malformed object pointers, so this isn't very risky.
4708-
auto ts = GetTypeSystemSwiftTypeRef();
4709-
if (!ts)
4710-
return {};
4711-
Module *module = ts->GetModule();
4712-
if (!module)
4710+
if (!m_module)
47134711
return {};
47144712
auto type_system_or_err =
4715-
module->GetTypeSystemForLanguage(eLanguageTypeObjC);
4713+
m_module->GetTypeSystemForLanguage(eLanguageTypeObjC);
47164714
if (!type_system_or_err) {
47174715
llvm::consumeError(type_system_or_err.takeError());
47184716
return {};
@@ -4724,11 +4722,16 @@ CompilerType SwiftASTContext::GetAsClangType(ConstString mangled_name) {
47244722
return {};
47254723
DWARFASTParserClang *clang_ast_parser =
47264724
static_cast<DWARFASTParserClang *>(clang_ctx->GetDWARFParser());
4725+
4726+
SymbolContext sc;
4727+
m_module->CalculateSymbolContext(&sc);
47274728
CompilerType clang_type;
47284729
CompilerType imported_type = GetCompilerType(mangled_name);
4729-
if (auto ts =
4730-
imported_type.GetTypeSystem().dyn_cast_or_null<TypeSystemSwift>())
4731-
ts->IsImportedType(imported_type.GetOpaqueQualType(), &clang_type);
4730+
if (auto ts = imported_type.GetTypeSystem()
4731+
.dyn_cast_or_null<TypeSystemSwiftTypeRef>())
4732+
if (ts->IsImportedType(imported_type.GetOpaqueQualType(), nullptr))
4733+
if (TypeSP result = ts->LookupClangType(mangled_name, sc))
4734+
clang_type = result->GetForwardCompilerType();
47324735

47334736
// Import the Clang type into the Clang context.
47344737
if (!clang_type)
@@ -8940,8 +8943,9 @@ SwiftASTContext::GetASTVectorForModule(const Module *module) {
89408943
}
89418944

89428945
SwiftASTContextForExpressions::SwiftASTContextForExpressions(
8943-
std::string description, TypeSystemSwiftTypeRefSP typeref_typesystem)
8944-
: SwiftASTContext(std::move(description), typeref_typesystem) {
8946+
std::string description, ModuleSP module_sp,
8947+
TypeSystemSwiftTypeRefSP typeref_typesystem)
8948+
: SwiftASTContext(std::move(description), module_sp, typeref_typesystem) {
89458949
assert(llvm::isa<TypeSystemSwiftTypeRefForExpressions>(
89468950
m_typeref_typesystem.lock().get()));
89478951
}

0 commit comments

Comments
 (0)