@@ -2786,27 +2786,48 @@ uint32_t TypeSystemSwiftTypeRef::GetNumFields(opaque_compiler_type_t type,
2786
2786
ExecutionContext *exe_ctx) {
2787
2787
LLDB_SCOPED_TIMER ();
2788
2788
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
+ }
2810
2831
2811
2832
LLDB_LOGF (GetLog (LLDBLog::Types),
2812
2833
" Using SwiftASTContext::GetNumFields fallback for type %s" ,
@@ -3243,8 +3264,9 @@ bool TypeSystemSwiftTypeRef::IsMeaninglessWithoutDynamicResolution(
3243
3264
(ReconstructType (type)));
3244
3265
}
3245
3266
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) {
3248
3270
using namespace swift ::Demangle;
3249
3271
Demangler dem;
3250
3272
NodePointer node = GetDemangledType (dem, AsMangledName (type));
@@ -3261,7 +3283,9 @@ CompilerType TypeSystemSwiftTypeRef::GetAsClangTypeOrNull(
3261
3283
return node_clangtype.second ;
3262
3284
}
3263
3285
CompilerType clang_type;
3264
- IsImportedType (type, &clang_type);
3286
+ bool imported = IsImportedType (type, &clang_type);
3287
+ if (is_imported)
3288
+ *is_imported = imported;
3265
3289
return clang_type;
3266
3290
}
3267
3291
0 commit comments