Skip to content

Commit 543f052

Browse files
authored
[lldb] Try Clang fallback in TSSwiftTypeRef::GetNumFields (#6671) (#6789)
For Clang types, avoid loading Swift ASTContexts in `TypeSystemSwiftTypeRef::GetNumFields`. This new logic checks if a type is an imported Clang type. If it's imported, but no type info is available (ex private/internal types), then zero is returned. If a Clang type is available, then, depending on the type class, return the Clang type's `GetNumFields`. Note that there's logic to avoid calling `GetNumFields` on ObjC types. This is to match the current behavior. (cherry picked from commit 80c77db)
1 parent 8f1b918 commit 543f052

File tree

2 files changed

+50
-25
lines changed

2 files changed

+50
-25
lines changed

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

Lines changed: 48 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2786,27 +2786,48 @@ uint32_t TypeSystemSwiftTypeRef::GetNumFields(opaque_compiler_type_t type,
27862786
ExecutionContext *exe_ctx) {
27872787
LLDB_SCOPED_TIMER();
27882788
FALLBACK(GetNumFields, (ReconstructType(type), exe_ctx));
2789-
if (exe_ctx)
2790-
if (auto *runtime = SwiftLanguageRuntime::Get(exe_ctx->GetProcessSP()))
2791-
if (auto num_fields =
2792-
runtime->GetNumFields(GetCanonicalType(type), exe_ctx))
2793-
// Use a lambda to intercept & unwrap the `Optional` return value from
2794-
// `SwiftLanguageRuntime::GetNumFields`.
2795-
// Optional<uint32_t> uses more lax equivalency function.
2796-
return [&]() -> llvm::Optional<uint32_t> {
2797-
auto impl = [&]() -> llvm::Optional<uint32_t> {
2798-
if (!type)
2799-
return 0;
2800-
return num_fields;
2801-
};
2802-
ExecutionContext exe_ctx_obj;
2803-
if (exe_ctx)
2804-
exe_ctx_obj = *exe_ctx;
2805-
VALIDATE_AND_RETURN(impl, GetNumFields, type, exe_ctx_obj,
2806-
(ReconstructType(type), exe_ctx),
2807-
(ReconstructType(type), exe_ctx));
2808-
}()
2809-
.value_or(0);
2789+
2790+
auto impl = [&]() -> llvm::Optional<uint32_t> {
2791+
if (exe_ctx)
2792+
if (auto *runtime = SwiftLanguageRuntime::Get(exe_ctx->GetProcessSP()))
2793+
if (auto num_fields =
2794+
runtime->GetNumFields(GetCanonicalType(type), exe_ctx))
2795+
return num_fields;
2796+
2797+
bool is_imported = false;
2798+
if (auto clang_type = GetAsClangTypeOrNull(type, &is_imported)) {
2799+
switch (clang_type.GetTypeClass()) {
2800+
case lldb::eTypeClassObjCObject:
2801+
case lldb::eTypeClassObjCInterface:
2802+
// Imported ObjC types are treated as having no fields.
2803+
return 0;
2804+
default:
2805+
return clang_type.GetNumFields(exe_ctx);
2806+
}
2807+
} else if (is_imported) {
2808+
// A known imported type, but where clang has no info. Return early to
2809+
// avoid loading Swift ASTContexts, only to return the same zero value.
2810+
LLDB_LOGF(GetLog(LLDBLog::Types),
2811+
"No CompilerType for imported Clang type %s",
2812+
AsMangledName(type));
2813+
return 0;
2814+
}
2815+
return {};
2816+
};
2817+
if (auto num_fields = impl()) {
2818+
// Use a lambda to intercept and unwrap the `Optional` return value.
2819+
// Optional<uint32_t> uses more lax equivalency function.
2820+
return [&]() -> llvm::Optional<uint32_t> {
2821+
auto impl = [&]() { return num_fields; };
2822+
ExecutionContext exe_ctx_obj;
2823+
if (exe_ctx)
2824+
exe_ctx_obj = *exe_ctx;
2825+
VALIDATE_AND_RETURN(impl, GetNumFields, type, exe_ctx_obj,
2826+
(ReconstructType(type), exe_ctx),
2827+
(ReconstructType(type), exe_ctx));
2828+
}()
2829+
.getValueOr(0);
2830+
}
28102831

28112832
LLDB_LOGF(GetLog(LLDBLog::Types),
28122833
"Using SwiftASTContext::GetNumFields fallback for type %s",
@@ -3243,8 +3264,9 @@ bool TypeSystemSwiftTypeRef::IsMeaninglessWithoutDynamicResolution(
32433264
(ReconstructType(type)));
32443265
}
32453266

3246-
CompilerType TypeSystemSwiftTypeRef::GetAsClangTypeOrNull(
3247-
lldb::opaque_compiler_type_t type) {
3267+
CompilerType
3268+
TypeSystemSwiftTypeRef::GetAsClangTypeOrNull(lldb::opaque_compiler_type_t type,
3269+
bool *is_imported) {
32483270
using namespace swift::Demangle;
32493271
Demangler dem;
32503272
NodePointer node = GetDemangledType(dem, AsMangledName(type));
@@ -3261,7 +3283,9 @@ CompilerType TypeSystemSwiftTypeRef::GetAsClangTypeOrNull(
32613283
return node_clangtype.second;
32623284
}
32633285
CompilerType clang_type;
3264-
IsImportedType(type, &clang_type);
3286+
bool imported = IsImportedType(type, &clang_type);
3287+
if (is_imported)
3288+
*is_imported = imported;
32653289
return clang_type;
32663290
}
32673291

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,8 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
265265
CompilerType *original_type) override;
266266
/// Like \p IsImportedType(), but even returns Clang types that are also Swift
267267
/// builtins (int <-> Swift.Int) as Clang types.
268-
CompilerType GetAsClangTypeOrNull(lldb::opaque_compiler_type_t type);
268+
CompilerType GetAsClangTypeOrNull(lldb::opaque_compiler_type_t type,
269+
bool *is_imported = nullptr);
269270
CompilerType GetErrorType() override;
270271
CompilerType GetReferentType(lldb::opaque_compiler_type_t type) override;
271272
CompilerType GetInstanceType(lldb::opaque_compiler_type_t type) override;

0 commit comments

Comments
 (0)