Skip to content

Commit 83a8378

Browse files
committed
[lldb] Use reflection metadata to find the value type of an existential
1 parent 8cf0600 commit 83a8378

File tree

2 files changed

+55
-28
lines changed

2 files changed

+55
-28
lines changed

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeDynamicTypeResolution.cpp

Lines changed: 54 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2433,9 +2433,12 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_IndirectEnumCase(
24332433
// because we aren't pointing to the LOCATION that stores the pointer to us,
24342434
// we're pointing to us..."
24352435
// See inlined comments for exceptions to this general rule.
2436-
Value::ValueType SwiftLanguageRuntimeImpl::GetValueType(
2437-
Value::ValueType static_value_type, CompilerType static_type,
2438-
CompilerType dynamic_type, bool is_indirect_enum_case) {
2436+
Value::ValueType
2437+
SwiftLanguageRuntimeImpl::GetValueType(ValueObject &in_value,
2438+
CompilerType dynamic_type,
2439+
bool is_indirect_enum_case) {
2440+
Value::ValueType static_value_type = in_value.GetValue().GetValueType();
2441+
CompilerType static_type = in_value.GetCompilerType();
24392442
Flags static_type_flags(static_type.GetTypeInfo());
24402443
Flags dynamic_type_flags(dynamic_type.GetTypeInfo());
24412444

@@ -2456,21 +2459,50 @@ Value::ValueType SwiftLanguageRuntimeImpl::GetValueType(
24562459
return Value::ValueType::LoadAddress;
24572460
}
24582461

2459-
if (auto *ts = llvm::dyn_cast_or_null<TypeSystemSwift>(
2460-
dynamic_type.GetTypeSystem()))
2461-
switch (ts->GetAllocationStrategy(dynamic_type.GetOpaqueQualType())) {
2462-
case SwiftASTContext::TypeAllocationStrategy::eDynamic:
2463-
case SwiftASTContext::TypeAllocationStrategy::eUnknown:
2464-
break;
2465-
case SwiftASTContext::TypeAllocationStrategy::eInline: // inline data;
2466-
// same as the
2467-
// static data
2468-
return static_value_type;
2469-
case SwiftASTContext::TypeAllocationStrategy::ePointer: // pointed-to;
2470-
// in the target
2471-
return Value::ValueType::LoadAddress;
2472-
}
2462+
lldb::addr_t existential_address;
2463+
bool use_local_buffer = false;
2464+
2465+
if (in_value.GetValueType() == eValueTypeConstResult &&
2466+
// We have a locally materialized value that is a host address;
2467+
// register it with MemoryReader so it does not treat it as a load
2468+
// address. Note that this assumes that any address at that host
2469+
// address is also a load address. If this assumption breaks there
2470+
// will be a crash in readBytes().
2471+
static_value_type == lldb_private::Value::ValueType::HostAddress) {
2472+
existential_address = in_value.GetValue().GetScalar().ULongLong();
2473+
use_local_buffer = true;
2474+
} else {
2475+
existential_address = in_value.GetAddressOf();
2476+
}
2477+
2478+
if (use_local_buffer)
2479+
PushLocalBuffer(existential_address,
2480+
in_value.GetByteSize().getValueOr(0));
2481+
2482+
// Read the value witness table and check if the data is inlined in
2483+
// the existential container or not.
2484+
swift::remote::RemoteAddress remote_existential(existential_address);
2485+
auto *reflection_ctx = GetReflectionContext();
2486+
llvm::Optional<bool> is_inlined =
2487+
reflection_ctx->isValueInlinedInExistentialContainer(
2488+
remote_existential);
2489+
2490+
if (use_local_buffer)
2491+
PopLocalBuffer();
2492+
2493+
// An error has occurred when trying to read value witness table,
2494+
// default to treating it as pointer.
2495+
if (!is_inlined.hasValue())
2496+
return Value::ValueType::LoadAddress;
2497+
2498+
// Inlined data, same as static data.
2499+
if (*is_inlined)
2500+
return static_value_type;
2501+
2502+
// If the data is not inlined, we have a pointer.
2503+
return Value::ValueType::LoadAddress;
24732504
}
2505+
24742506
if (static_type_flags.AllSet(eTypeIsSwift | eTypeIsGenericTypeParam)) {
24752507
// if I am handling a non-pointer Swift type obtained from an archetype,
24762508
// then the runtime vends the location
@@ -2497,8 +2529,7 @@ Value::ValueType SwiftLanguageRuntimeImpl::GetValueType(
24972529
dynamic_type_flags.AllSet(eTypeIsSwift) &&
24982530
dynamic_type_flags.AllClear(eTypeIsPointer | eTypeInstanceIsPointer))
24992531
return static_value_type;
2500-
else
2501-
return Value::ValueType::Scalar;
2532+
return Value::ValueType::Scalar;
25022533
}
25032534

25042535
bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
@@ -2575,9 +2606,7 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress_ClangType(
25752606
return false;
25762607
class_type_or_name = dyn_class_type_or_name;
25772608
class_type_or_name.SetCompilerType(swift_type);
2578-
value_type = GetValueType(in_value.GetValue().GetValueType(),
2579-
in_value.GetCompilerType(),
2580-
class_type_or_name.GetCompilerType(), false);
2609+
value_type = Value::ValueType::Scalar;
25812610
return true;
25822611
}
25832612

@@ -2611,7 +2640,7 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress(
26112640
return false;
26122641

26132642
LLDB_SCOPED_TIMER();
2614-
2643+
26152644
// Try to import a Clang type into Swift.
26162645
if (in_value.GetObjectRuntimeLanguage() == eLanguageTypeObjC)
26172646
return GetDynamicTypeAndAddress_ClangType(
@@ -2696,9 +2725,8 @@ bool SwiftLanguageRuntimeImpl::GetDynamicTypeAndAddress(
26962725
}
26972726

26982727
if (success)
2699-
value_type = GetValueType(
2700-
in_value.GetValue().GetValueType(), in_value.GetCompilerType(),
2701-
class_type_or_name.GetCompilerType(), is_indirect_enum_case);
2728+
value_type = GetValueType(in_value, class_type_or_name.GetCompilerType(),
2729+
is_indirect_enum_case);
27022730
else if (scratch_ctx->HasFatalErrors())
27032731
return retry_once();
27042732
return success;

lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntimeImpl.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,7 @@ class SwiftLanguageRuntimeImpl {
202202
std::function<bool(SuperClassType)> fn);
203203

204204
// Classes that inherit from SwiftLanguageRuntime can see and modify these
205-
Value::ValueType GetValueType(Value::ValueType static_value_type,
206-
CompilerType static_type,
205+
Value::ValueType GetValueType(ValueObject &in_value,
207206
CompilerType dynamic_type,
208207
bool is_indirect_enum_case);
209208

0 commit comments

Comments
 (0)