3
3
4
4
#include " Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h"
5
5
#include " lldb/DataFormatters/TypeSynthetic.h"
6
+ #include " lldb/Symbol/CompilerType.h"
6
7
#include " lldb/Utility/LLDBLog.h"
7
8
#include " lldb/Utility/Log.h"
9
+ #include " lldb/ValueObject/ValueObject.h"
8
10
#include " lldb/lldb-enumerations.h"
11
+ #include " llvm/ADT/StringRef.h"
9
12
10
13
#include < utility>
11
14
@@ -38,6 +41,8 @@ class SwiftUnsafeType {
38
41
protected:
39
42
SwiftUnsafeType (ValueObject &valobj, UnsafePointerKind kind);
40
43
addr_t GetAddress (llvm::StringRef child_name);
44
+ std::optional<size_t > GetCountValue (llvm::StringRef child_name);
45
+ CompilerType GetArgumentType ();
41
46
42
47
ValueObject &m_valobj;
43
48
const UnsafePointerKind m_kind;
@@ -133,6 +138,70 @@ lldb::addr_t SwiftUnsafeType::GetAddress(llvm::StringRef child_name) {
133
138
return pointer_value_sp->GetValueAsUnsigned (LLDB_INVALID_ADDRESS);
134
139
}
135
140
141
+ std::optional<size_t >
142
+ SwiftUnsafeType::GetCountValue (llvm::StringRef child_name) {
143
+ ValueObjectSP count_value_sp (
144
+ m_valobj.GetChildMemberWithName (child_name, true ));
145
+ if (!count_value_sp) {
146
+ LLDB_LOG (GetLog (LLDBLog::DataFormatters),
147
+ " {0}: Couldn't find ValueObject child member named '{1}'." ,
148
+ __FUNCTION__, child_name);
149
+ return std::nullopt;
150
+ }
151
+
152
+ ValueObjectSP value_provided_child_sp;
153
+
154
+ // Implement Swift's 'value-providing synthetic children' workaround.
155
+ // Depending on whether the ValueObject type is a primitive or a structure,
156
+ // lldb should prioritize the synthetic value children.
157
+ // If it has no synthetic children then fallback to non synthetic children.
158
+ ValueObjectSP synthetic = count_value_sp->GetSyntheticValue ();
159
+ if (synthetic)
160
+ value_provided_child_sp = synthetic->GetChildAtIndex (0 , true );
161
+ if (!value_provided_child_sp)
162
+ value_provided_child_sp = count_value_sp->GetChildAtIndex (0 , true );
163
+
164
+ // If neither child exists, fail.
165
+ if (!value_provided_child_sp) {
166
+ LLDB_LOG (GetLog (LLDBLog::DataFormatters),
167
+ " {0}: Couldn't extract 'value-providing synthetic children' from "
168
+ " ValueObject '{1}'." ,
169
+ __FUNCTION__, child_name);
170
+ return std::nullopt;
171
+ }
172
+
173
+ size_t count = value_provided_child_sp->GetValueAsUnsigned (UINT64_MAX);
174
+
175
+ if (count == UINT64_MAX) {
176
+ LLDB_LOG (GetLog (LLDBLog::DataFormatters),
177
+ " {0}: Couldn't get a valid value for ValueObject '{1}'." ,
178
+ __FUNCTION__, child_name);
179
+ return std::nullopt;
180
+ }
181
+
182
+ return count;
183
+ }
184
+
185
+ CompilerType SwiftUnsafeType::GetArgumentType () {
186
+ CompilerType type = m_valobj.GetCompilerType ();
187
+ if (!type.IsValid ()) {
188
+ LLDB_LOG (GetLog (LLDBLog::DataFormatters),
189
+ " {0}: Couldn't get the compiler type for the '{1}' ValueObject." ,
190
+ __FUNCTION__, type.GetTypeName ());
191
+ return {};
192
+ }
193
+
194
+ auto type_system = type.GetTypeSystem ().dyn_cast_or_null <TypeSystemSwift>();
195
+ if (!type_system) {
196
+ LLDB_LOG (GetLog (LLDBLog::DataFormatters),
197
+ " {0}: Couldn't get {1} type system." , __FUNCTION__,
198
+ type.GetTypeName ());
199
+ return {};
200
+ }
201
+
202
+ return type_system->GetGenericArgumentType (type.GetOpaqueQualType (), 0 );
203
+ }
204
+
136
205
class SwiftUnsafeBufferPointer final : public SwiftUnsafeType {
137
206
public:
138
207
SwiftUnsafeBufferPointer (ValueObject &valobj);
@@ -162,46 +231,10 @@ lldb::ChildCacheState SwiftUnsafeBufferPointer::Update() {
162
231
// pointer address, lldb unfolds every ValueObject child until reaching
163
232
// `pointerValue`.
164
233
165
- static ConstString g_count (" count" );
166
- ValueObjectSP count_value_sp (m_valobj.GetChildMemberWithName (g_count, true ));
167
- if (!count_value_sp) {
168
- LLDB_LOG (GetLog (LLDBLog::DataFormatters),
169
- " {0}: Couldn't find ValueObject child member named '{1}'." ,
170
- __FUNCTION__, g_count);
171
- return ChildCacheState::eRefetch;
172
- }
173
-
174
- ValueObjectSP value_provided_child_sp = nullptr ;
175
-
176
- // Implement Swift's 'value-providing synthetic children' workaround.
177
- // Depending on whether the ValueObject type is a primitive or a structure,
178
- // lldb should prioritize the synthetic value children.
179
- // If it has no synthetic children then fallback to non synthetic children.
180
- ValueObjectSP synthetic = count_value_sp->GetSyntheticValue ();
181
- if (synthetic)
182
- value_provided_child_sp = synthetic->GetChildAtIndex (0 , true );
183
- if (!value_provided_child_sp)
184
- value_provided_child_sp = count_value_sp->GetChildAtIndex (0 , true );
185
-
186
- // If neither child exists, fail.
187
- if (!value_provided_child_sp) {
188
- LLDB_LOG (GetLog (LLDBLog::DataFormatters),
189
- " {0}: Couldn't extract 'value-providing synthetic children' from "
190
- " ValueObject 'count'." ,
191
- __FUNCTION__);
192
- return lldb::ChildCacheState::eRefetch;
193
- }
194
-
195
- size_t count = value_provided_child_sp->GetValueAsUnsigned (UINT64_MAX);
196
-
197
- if (count == UINT64_MAX) {
198
- LLDB_LOG (GetLog (LLDBLog::DataFormatters),
199
- " {0}: Couldn't get a valid value for ValueObject 'count'." ,
200
- __FUNCTION__);
234
+ if (auto count = GetCountValue (" count" ))
235
+ m_count = *count;
236
+ else
201
237
return ChildCacheState::eRefetch;
202
- }
203
-
204
- m_count = count;
205
238
206
239
addr_t start_addr = GetAddress (" _position" );
207
240
@@ -332,35 +365,10 @@ lldb::ChildCacheState SwiftUnsafePointer::Update() {
332
365
// - pointerValue : Int
333
366
//
334
367
335
- CompilerType type = m_valobj.GetCompilerType ();
336
- if (!type.IsValid ()) {
337
- LLDB_LOG (GetLog (LLDBLog::DataFormatters),
338
- " {0}: Couldn't get the compiler type for the "
339
- " 'Swift.UnsafePointer' ValueObject." ,
340
- __FUNCTION__, type.GetTypeName ());
341
- return ChildCacheState::eRefetch;
342
- }
343
-
344
- auto type_system = type.GetTypeSystem ().dyn_cast_or_null <TypeSystemSwift>();
345
- if (!type_system) {
346
- LLDB_LOG (GetLog (LLDBLog::DataFormatters),
347
- " {0}: Couldn't get {1} type system." , __FUNCTION__,
348
- type.GetTypeName ());
349
- return ChildCacheState::eRefetch;
350
- }
351
-
352
- CompilerType argument_type =
353
- type_system->GetGenericArgumentType (type.GetOpaqueQualType (), 0 );
354
-
368
+ CompilerType argument_type = GetArgumentType ();
355
369
if (argument_type.IsValid ())
356
370
m_elem_type = argument_type;
357
371
358
- if (type.GetTypeInfo () & eTypeIsEnumeration) {
359
- CompilerType argument_type =
360
- type_system->GetGenericArgumentType (type.GetOpaqueQualType (), 0 );
361
- if (argument_type.IsValid ())
362
- m_elem_type = argument_type;
363
- }
364
372
assert (
365
373
!m_elem_type.GetTypeName ().GetStringRef ().starts_with (" Swift.Optional" ));
366
374
@@ -384,6 +392,40 @@ lldb::ChildCacheState SwiftUnsafePointer::Update() {
384
392
return ChildCacheState::eReuse;
385
393
}
386
394
395
+ class SwiftSpan final : public SwiftUnsafeType {
396
+ public:
397
+ SwiftSpan (ValueObject &valobj);
398
+ lldb::ChildCacheState Update () override ;
399
+ };
400
+
401
+ SwiftSpan::SwiftSpan (ValueObject &valobj)
402
+ : SwiftUnsafeType(valobj, UnsafePointerKind::eSwiftUnsafeRawBufferPointer) {
403
+ }
404
+
405
+ lldb::ChildCacheState SwiftSpan::Update () {
406
+ if (auto count = GetCountValue (" _count" ))
407
+ m_count = *count;
408
+ else
409
+ return ChildCacheState::eRefetch;
410
+
411
+ addr_t start_addr = GetAddress (" _pointer" );
412
+ if (!start_addr || start_addr == LLDB_INVALID_ADDRESS) {
413
+ LLDB_LOG (GetLog (LLDBLog::DataFormatters),
414
+ " {0}: Couldn't get a valid address for ValueObject '_pointer'." ,
415
+ __FUNCTION__);
416
+ return ChildCacheState::eRefetch;
417
+ }
418
+ m_start_addr = start_addr;
419
+
420
+ CompilerType argument_type = GetArgumentType ();
421
+ if (argument_type.IsValid ())
422
+ m_elem_type = argument_type;
423
+ else
424
+ return ChildCacheState::eRefetch;
425
+
426
+ return ChildCacheState::eReuse;
427
+ }
428
+
387
429
std::unique_ptr<SwiftUnsafeType> SwiftUnsafeType::Create (ValueObject &valobj) {
388
430
CompilerType type = valobj.GetCompilerType ();
389
431
if (!type.IsValid ()) {
@@ -424,8 +466,12 @@ std::unique_ptr<SwiftUnsafeType> SwiftUnsafeType::Create(ValueObject &valobj) {
424
466
425
467
llvm::StringRef valobj_type_name (type.GetTypeName ().GetCString ());
426
468
valobj_type_name.consume_front (" Swift." );
427
- valobj_type_name.consume_front (" Unsafe" );
469
+ bool is_unsafe = valobj_type_name.consume_front (" Unsafe" );
428
470
valobj_type_name.consume_front (" Mutable" );
471
+
472
+ if (!is_unsafe && valobj_type_name.consume_front (" Span" ))
473
+ return std::make_unique<SwiftSpan>(valobj);
474
+
429
475
bool is_raw = valobj_type_name.consume_front (" Raw" );
430
476
bool is_buffer_ptr = valobj_type_name.consume_front (" Buffer" );
431
477
UnsafePointerKind kind =
0 commit comments