33
44#include " Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h"
55#include " lldb/DataFormatters/TypeSynthetic.h"
6+ #include " lldb/Symbol/CompilerType.h"
67#include " lldb/Utility/LLDBLog.h"
78#include " lldb/Utility/Log.h"
9+ #include " lldb/ValueObject/ValueObject.h"
810#include " lldb/lldb-enumerations.h"
11+ #include " llvm/ADT/StringRef.h"
912
1013#include < utility>
1114
@@ -38,6 +41,8 @@ class SwiftUnsafeType {
3841protected:
3942 SwiftUnsafeType (ValueObject &valobj, UnsafePointerKind kind);
4043 addr_t GetAddress (llvm::StringRef child_name);
44+ std::optional<size_t > GetCountValue (llvm::StringRef child_name);
45+ CompilerType GetArgumentType ();
4146
4247 ValueObject &m_valobj;
4348 const UnsafePointerKind m_kind;
@@ -133,6 +138,70 @@ lldb::addr_t SwiftUnsafeType::GetAddress(llvm::StringRef child_name) {
133138 return pointer_value_sp->GetValueAsUnsigned (LLDB_INVALID_ADDRESS);
134139}
135140
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+
136205class SwiftUnsafeBufferPointer final : public SwiftUnsafeType {
137206public:
138207 SwiftUnsafeBufferPointer (ValueObject &valobj);
@@ -162,46 +231,10 @@ lldb::ChildCacheState SwiftUnsafeBufferPointer::Update() {
162231 // pointer address, lldb unfolds every ValueObject child until reaching
163232 // `pointerValue`.
164233
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
201237 return ChildCacheState::eRefetch;
202- }
203-
204- m_count = count;
205238
206239 addr_t start_addr = GetAddress (" _position" );
207240
@@ -332,35 +365,10 @@ lldb::ChildCacheState SwiftUnsafePointer::Update() {
332365 // - pointerValue : Int
333366 //
334367
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 ();
355369 if (argument_type.IsValid ())
356370 m_elem_type = argument_type;
357371
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- }
364372 assert (
365373 !m_elem_type.GetTypeName ().GetStringRef ().starts_with (" Swift.Optional" ));
366374
@@ -384,6 +392,40 @@ lldb::ChildCacheState SwiftUnsafePointer::Update() {
384392 return ChildCacheState::eReuse;
385393}
386394
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+
387429std::unique_ptr<SwiftUnsafeType> SwiftUnsafeType::Create (ValueObject &valobj) {
388430 CompilerType type = valobj.GetCompilerType ();
389431 if (!type.IsValid ()) {
@@ -424,6 +466,9 @@ std::unique_ptr<SwiftUnsafeType> SwiftUnsafeType::Create(ValueObject &valobj) {
424466
425467 llvm::StringRef valobj_type_name (type.GetTypeName ().GetCString ());
426468 valobj_type_name.consume_front (" Swift." );
469+ if (valobj_type_name.consume_front (" Span" ))
470+ return std::make_unique<SwiftSpan>(valobj);
471+
427472 valobj_type_name.consume_front (" Unsafe" );
428473 valobj_type_name.consume_front (" Mutable" );
429474 bool is_raw = valobj_type_name.consume_front (" Raw" );
0 commit comments