Skip to content

Commit 0e9b212

Browse files
Merge pull request #10030 from adrian-prantl/142512839
TypeSystemSwiftTypeRef: Make SwiftASTContext fallback switchable
2 parents 21c7bb5 + a120b8e commit 0e9b212

File tree

8 files changed

+134
-49
lines changed

8 files changed

+134
-49
lines changed

lldb/include/lldb/Core/ModuleList.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ class ModuleListProperties : public Properties {
8282
bool GetUseSwiftDWARFImporter() const;
8383
bool SetUseSwiftDWARFImporter(bool new_value);
8484
bool GetSwiftValidateTypeSystem() const;
85+
bool GetSwiftTypeSystemFallback() const;
8586
bool GetSwiftLoadConformances() const;
8687
SwiftModuleLoadingMode GetSwiftModuleLoadingMode() const;
8788
bool SetSwiftModuleLoadingMode(SwiftModuleLoadingMode);

lldb/packages/Python/lldbsuite/test/lldbtest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -778,6 +778,7 @@ def setUpCommands(cls):
778778
),
779779
# Enable expensive validations in TypeSystemSwiftTypeRef.
780780
"settings set symbols.swift-validate-typesystem true",
781+
"settings set symbols.swift-typesystem-compiler-fallback true",
781782
"settings set use-color false",
782783
]
783784

lldb/source/Core/CoreProperties.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ let Definition = "modulelist" in {
2828
def SwiftValidateTypeSystem: Property<"swift-validate-typesystem", "Boolean">,
2929
DefaultFalse,
3030
Desc<"Validate all Swift typesystem queries. Used for testing an asserts-enabled LLDB only.">;
31+
def SwiftTypeSystemFallback
32+
: Property<"swift-typesystem-compiler-fallback", "Boolean">,
33+
DefaultTrue,
34+
Desc<"If a query against reflection metadata / debug info fails, retry "
35+
"using Swift modules.">;
3136
def SwiftLoadConformances: Property<"swift-load-conformances", "Boolean">,
3237
DefaultFalse,
3338
Desc<"Resolve type alias via the conformance section. Disabled for performance reasons">;

lldb/source/Core/ModuleList.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,12 @@ bool ModuleListProperties::GetSwiftValidateTypeSystem() const {
200200
idx, g_modulelist_properties[idx].default_uint_value != 0);
201201
}
202202

203+
bool ModuleListProperties::GetSwiftTypeSystemFallback() const {
204+
const uint32_t idx = ePropertySwiftTypeSystemFallback;
205+
return GetPropertyAtIndexAs<bool>(
206+
idx, g_modulelist_properties[idx].default_uint_value != 0);
207+
}
208+
203209
bool ModuleListProperties::GetSwiftLoadConformances() const {
204210
const uint32_t idx = ePropertySwiftLoadConformances;
205211
return GetPropertyAtIndexAs<bool>(

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

Lines changed: 108 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -2735,12 +2735,42 @@ constexpr ExecutionContextScope *g_no_exe_ctx = nullptr;
27352735
#define FORWARD_TO_EXPRAST_ONLY(FUNC, ARGS, DEFAULT_RETVAL) \
27362736
do { \
27372737
if (auto target_sp = GetTargetWP().lock()) \
2738-
if (auto swift_ast_ctx = GetSwiftASTContext( \
2738+
if (auto swift_ast_ctx = GetSwiftASTContext( \
27392739
SymbolContext(target_sp, target_sp->GetExecutableModule()))) \
27402740
return swift_ast_ctx->FUNC ARGS; \
27412741
return DEFAULT_RETVAL; \
27422742
} while (0)
27432743

2744+
bool TypeSystemSwiftTypeRef::UseSwiftASTContextFallback(
2745+
const char *func_name, lldb::opaque_compiler_type_t type) {
2746+
if (!ModuleList::GetGlobalModuleListProperties().GetSwiftTypeSystemFallback())
2747+
return false;
2748+
2749+
LLDB_LOGF(GetLog(LLDBLog::Types),
2750+
"TypeSystemSwiftTypeRef::%s(): Engaging SwiftASTContext fallback "
2751+
"for type %s",
2752+
func_name, AsMangledName(type));
2753+
return true;
2754+
}
2755+
2756+
bool TypeSystemSwiftTypeRef::DiagnoseSwiftASTContextFallback(
2757+
const char *func_name, lldb::opaque_compiler_type_t type) {
2758+
const char *type_name = AsMangledName(type);
2759+
2760+
std::optional<lldb::user_id_t> debugger_id;
2761+
if (auto target_sp = GetTargetWP().lock())
2762+
debugger_id = target_sp->GetDebugger().GetID();
2763+
2764+
std::string msg;
2765+
llvm::raw_string_ostream(msg)
2766+
<< "TypeSystemSwiftTypeRef::" << func_name
2767+
<< ": had to engage SwiftASTContext fallback for type " << type_name;
2768+
Debugger::ReportWarning(msg, debugger_id, &m_fallback_warning);
2769+
2770+
LLDB_LOGF(GetLog(LLDBLog::Types), "%s", msg.c_str());
2771+
return true;
2772+
}
2773+
27442774
CompilerType
27452775
TypeSystemSwiftTypeRef::RemangleAsType(swift::Demangle::Demangler &dem,
27462776
swift::Demangle::NodePointer node,
@@ -3453,14 +3483,16 @@ TypeSystemSwiftTypeRef::GetBitSize(opaque_compiler_type_t type,
34533483
if (auto result = runtime->GetBitSize({weak_from_this(), type}, exe_scope))
34543484
return result;
34553485
// Runtime failed, fallback to SwiftASTContext.
3456-
LLDB_LOGF(GetLog(LLDBLog::Types),
3457-
"Couldn't compute size of type %s using SwiftLanguageRuntime.",
3458-
AsMangledName(type));
3459-
3460-
if (auto swift_ast_context =
3461-
GetSwiftASTContext(GetSymbolContext(exe_scope)))
3462-
return swift_ast_context->GetBitSize(ReconstructType(type, exe_scope),
3463-
exe_scope);
3486+
if (UseSwiftASTContextFallback(__FUNCTION__, type)) {
3487+
if (auto swift_ast_context =
3488+
GetSwiftASTContext(GetSymbolContext(exe_scope))) {
3489+
auto result = swift_ast_context->GetBitSize(
3490+
ReconstructType(type, exe_scope), exe_scope);
3491+
if (result)
3492+
DiagnoseSwiftASTContextFallback(__FUNCTION__, type);
3493+
return result;
3494+
}
3495+
}
34643496
}
34653497

34663498
// FIXME: Move this to the top. Currently this causes VALIDATE
@@ -3501,12 +3533,16 @@ TypeSystemSwiftTypeRef::GetByteStride(opaque_compiler_type_t type,
35013533
return stride;
35023534
}
35033535
// Runtime failed, fallback to SwiftASTContext.
3504-
LLDB_LOGF(GetLog(LLDBLog::Types),
3505-
"Couldn't compute stride of type %s using SwiftLanguageRuntime.",
3506-
AsMangledName(type));
3507-
if (auto swift_ast_context =
3508-
GetSwiftASTContext(GetSymbolContext(exe_scope)))
3509-
return swift_ast_context->GetByteStride(ReconstructType(type), exe_scope);
3536+
if (UseSwiftASTContextFallback(__FUNCTION__, type)) {
3537+
if (auto swift_ast_context =
3538+
GetSwiftASTContext(GetSymbolContext(exe_scope))) {
3539+
auto result =
3540+
swift_ast_context->GetByteStride(ReconstructType(type), exe_scope);
3541+
if (result)
3542+
DiagnoseSwiftASTContextFallback(__FUNCTION__, type);
3543+
return result;
3544+
}
3545+
}
35103546
return {};
35113547
};
35123548
VALIDATE_AND_RETURN(impl, GetByteStride, type, exe_scope,
@@ -3624,19 +3660,19 @@ TypeSystemSwiftTypeRef::GetNumChildren(opaque_compiler_type_t type,
36243660
impl, GetNumChildren, type, exe_ctx_obj,
36253661
(ReconstructType(type, exe_ctx), omit_empty_base_classes, exe_ctx));
36263662
}
3627-
LLDB_LOGF(GetLog(LLDBLog::Types),
3628-
"Using SwiftASTContext::GetNumChildren fallback for type %s",
3629-
AsMangledName(type));
3630-
3631-
// Try SwiftASTContext.
3632-
if (auto swift_ast_context = GetSwiftASTContext(GetSymbolContext(exe_ctx)))
3633-
if (auto n = llvm::expectedToStdOptional(swift_ast_context->GetNumChildren(
3634-
ReconstructType(type, exe_ctx), omit_empty_base_classes,
3635-
exe_ctx))) {
3636-
LLDB_LOG_ERRORV(GetLog(LLDBLog::Types), num_children.takeError(),
3637-
"SwiftLanguageRuntime::GetNumChildren() failed: {0}");
3638-
return *n;
3639-
}
3663+
// Runtime failed, fallback to SwiftASTContext.
3664+
if (UseSwiftASTContextFallback(__FUNCTION__, type)) {
3665+
if (auto swift_ast_context = GetSwiftASTContext(GetSymbolContext(exe_ctx)))
3666+
if (auto n =
3667+
llvm::expectedToStdOptional(swift_ast_context->GetNumChildren(
3668+
ReconstructType(type, exe_ctx), omit_empty_base_classes,
3669+
exe_ctx))) {
3670+
LLDB_LOG_ERRORV(GetLog(LLDBLog::Types), num_children.takeError(),
3671+
"SwiftLanguageRuntime::GetNumChildren() failed: {0}");
3672+
DiagnoseSwiftASTContextFallback(__FUNCTION__, type);
3673+
return *n;
3674+
}
3675+
}
36403676

36413677
// Otherwise return the error from the runtime.
36423678
return num_children.takeError();
@@ -3686,12 +3722,16 @@ uint32_t TypeSystemSwiftTypeRef::GetNumFields(opaque_compiler_type_t type,
36863722
.value_or(0);
36873723
}
36883724

3689-
LLDB_LOGF(GetLog(LLDBLog::Types),
3690-
"Using SwiftASTContext::GetNumFields fallback for type %s",
3691-
AsMangledName(type));
3692-
3693-
if (auto swift_ast_context = GetSwiftASTContext(GetSymbolContext(exe_ctx)))
3694-
return swift_ast_context->GetNumFields(ReconstructType(type, exe_ctx), exe_ctx);
3725+
// Runtime failed, fallback to SwiftASTContext.
3726+
if (UseSwiftASTContextFallback(__FUNCTION__, type))
3727+
if (auto swift_ast_context =
3728+
GetSwiftASTContext(GetSymbolContext(exe_ctx))) {
3729+
auto result = swift_ast_context->GetNumFields(
3730+
ReconstructType(type, exe_ctx), exe_ctx);
3731+
if (result)
3732+
DiagnoseSwiftASTContextFallback(__FUNCTION__, type);
3733+
return result;
3734+
}
36953735
return {};
36963736
}
36973737

@@ -3787,6 +3827,7 @@ TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
37873827
return ast_num_children.value_or(0);
37883828
};
37893829
auto impl = [&]() -> llvm::Expected<CompilerType> {
3830+
std::string error = "unknown error";
37903831
ExecutionContextScope *exe_scope = nullptr;
37913832
if (exe_ctx)
37923833
exe_scope = exe_ctx->GetBestExecutionContextScope();
@@ -3809,7 +3850,7 @@ TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
38093850
return result;
38103851
}
38113852
if (!result)
3812-
llvm::consumeError(result.takeError());
3853+
error = llvm::toString(result.takeError());
38133854
}
38143855
// Clang types can be resolved even without a process.
38153856
bool is_signed;
@@ -3923,10 +3964,17 @@ TypeSystemSwiftTypeRef::GetChildCompilerTypeAtIndex(
39233964
"Couldn't compute size of type %s without a process.",
39243965
AsMangledName(type));
39253966

3926-
// FIXME: SwiftASTContext can sometimes find more Clang types because it
3927-
// imports Clang modules from source. We should be able to replicate this
3928-
// and remove this fallback.
3929-
return fallback();
3967+
// Runtime failed, fallback to SwiftASTContext.
3968+
if (UseSwiftASTContextFallback(__FUNCTION__, type)) {
3969+
// FIXME: SwiftASTContext can sometimes find more Clang types because it
3970+
// imports Clang modules from source. We should be able to replicate this
3971+
// and remove this fallback.
3972+
auto result = fallback();
3973+
if (result)
3974+
DiagnoseSwiftASTContextFallback(__FUNCTION__, type);
3975+
return result;
3976+
}
3977+
return llvm::createStringError(llvm::inconvertibleErrorCode(), error);
39303978
};
39313979
// Skip validation when there is no process, because then we also
39323980
// don't have a runtime.
@@ -4080,10 +4128,17 @@ size_t TypeSystemSwiftTypeRef::GetIndexOfChildMemberWithName(
40804128
"type %s",
40814129
AsMangledName(type));
40824130

4083-
if (auto swift_ast_context = GetSwiftASTContext(GetSymbolContext(exe_ctx)))
4084-
return swift_ast_context->GetIndexOfChildMemberWithName(
4085-
ReconstructType(type, exe_ctx), name, exe_ctx, omit_empty_base_classes,
4086-
child_indexes);
4131+
// Runtime failed, fallback to SwiftASTContext.
4132+
if (UseSwiftASTContextFallback(__FUNCTION__, type))
4133+
if (auto swift_ast_context =
4134+
GetSwiftASTContext(GetSymbolContext(exe_ctx))) {
4135+
auto result = swift_ast_context->GetIndexOfChildMemberWithName(
4136+
ReconstructType(type, exe_ctx), name, exe_ctx,
4137+
omit_empty_base_classes, child_indexes);
4138+
if (result)
4139+
DiagnoseSwiftASTContextFallback(__FUNCTION__, type);
4140+
return result;
4141+
}
40874142
return {};
40884143
}
40894144

@@ -4388,10 +4443,16 @@ TypeSystemSwiftTypeRef::GetInstanceType(opaque_compiler_type_t type,
43884443
// type alias isn't possible, or the user might have defined the
43894444
// type alias in the REPL. In these cases, fallback to asking the AST
43904445
// for the canonical type.
4391-
if (auto swift_ast_context =
4392-
GetSwiftASTContext(GetSymbolContext(exe_scope)))
4393-
return swift_ast_context->GetInstanceType(
4394-
ReconstructType(type, exe_scope), exe_scope);
4446+
// Runtime failed, fallback to SwiftASTContext.
4447+
if (UseSwiftASTContextFallback(__FUNCTION__, type))
4448+
if (auto swift_ast_context =
4449+
GetSwiftASTContext(GetSymbolContext(exe_scope))) {
4450+
auto result = swift_ast_context->GetInstanceType(
4451+
ReconstructType(type, exe_scope), exe_scope);
4452+
if (result)
4453+
DiagnoseSwiftASTContextFallback(__FUNCTION__, type);
4454+
return result;
4455+
}
43954456
return {};
43964457
}
43974458

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,13 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
441441
GetManglingFlavor(ExecutionContext *exe_ctx = nullptr);
442442

443443
protected:
444+
/// Determine whether the fallback is enabled via setting.
445+
bool UseSwiftASTContextFallback(const char *func_name,
446+
lldb::opaque_compiler_type_t type);
447+
/// Print a warning that a fallback was necessary.
448+
bool DiagnoseSwiftASTContextFallback(const char *func_name,
449+
lldb::opaque_compiler_type_t type);
450+
444451
/// Helper that creates an AST type from \p type.
445452
///
446453
/// FIXME: This API is dangerous, it would be better to return a
@@ -555,6 +562,7 @@ class TypeSystemSwiftTypeRef : public TypeSystemSwift {
555562
unsigned char retry_count = 0;
556563
};
557564

565+
std::once_flag m_fallback_warning;
558566
mutable std::mutex m_swift_ast_context_lock;
559567
/// The "precise" SwiftASTContexts managed by this scratch context. There
560568
/// exists one per Swift module. The keys in this map are module names.
Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
# REQUIRES: swift
22
# RUN: rm -rf %t && mkdir %t && cd %t
3-
# RUN: %target-swiftc -g %S/Inputs/main.swift -o a.out
4-
# RUN: %lldb a.out -b -s %s 2>&1 | FileCheck %s
3+
# RUN: %target-swiftc -g %S/Inputs/main.swift -o %t/a.out
4+
# RUN: %lldb %t/a.out -b -s %s 2>&1 | FileCheck %s
55

66
# CHECK-NOT: Stopped due to an error evaluating condition of breakpoint
7+
# CHECK: stop reason = breakpoint
78

89
# The parentheses surrounding the expression matter.
910
br s -n main -c '((nil == nil))'
1011
r
1112
c
13+
quit

lldb/test/Shell/lit-lldb-init.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@ settings set target.auto-apply-fixits false
99
settings set target.inherit-tcc true
1010
settings set target.detach-on-error false
1111
settings set symbols.swift-validate-typesystem true
12+
settings set symbols.swift-typesystem-compiler-fallback true

0 commit comments

Comments
 (0)