Skip to content

[Cherry-pick into next] Add a data formatter for Swift.InlineArray<> #10652

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 45 additions & 0 deletions lldb/source/Plugins/Language/Swift/SwiftArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,29 @@ bool SwiftArraySliceBufferHandler::IsValid() {
return m_first_elem_ptr != LLDB_INVALID_ADDRESS && m_elem_type.IsValid();
}

size_t SwiftArrayInlineBufferHandler::GetCount() { return m_size; }

size_t SwiftArrayInlineBufferHandler::GetCapacity() { return GetCount(); }

lldb_private::CompilerType SwiftArrayInlineBufferHandler::GetElementType() {
return m_elem_type;
}

ValueObjectSP SwiftArrayInlineBufferHandler::GetElementAtIndex(size_t idx) {
if (idx >= m_size)
return {};
return m_valobj_sp->GetChildAtIndex(idx);
}

SwiftArrayInlineBufferHandler::SwiftArrayInlineBufferHandler(
ValueObjectSP valobj, lldb::addr_t native_ptr, CompilerType elem_type)
: m_valobj_sp(valobj),
m_size(
llvm::expectedToOptional(m_valobj_sp->GetNumChildren()).value_or(0)) {
}

bool SwiftArrayInlineBufferHandler::IsValid() { return m_valobj_sp.get(); }

size_t SwiftSyntheticFrontEndBufferHandler::GetCount() {
return m_frontend->CalculateNumChildrenIgnoringErrors();
}
Expand Down Expand Up @@ -395,6 +418,28 @@ SwiftArrayBufferHandler::CreateBufferHandler(ValueObject &static_valobj) {
if (handler && handler->IsValid())
return handler;
return nullptr;
} else if (valobj_typename.starts_with("Swift.InlineArray<")) {
CompilerType elem_type(
valobj.GetCompilerType().GetArrayElementType(exe_scope));
if (!elem_type)
return nullptr;

static ConstString g__storage("_storage");
auto nonsynth_sp = valobj.GetNonSyntheticValue();
if (!nonsynth_sp)
return nullptr;
ValueObjectSP storage_sp(nonsynth_sp->GetChildMemberWithName(g__storage));

lldb::addr_t storage_location =
storage_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
if (auto process_sp = valobj.GetProcessSP())
if (auto *swift_runtime = SwiftLanguageRuntime::Get(process_sp))
storage_location =
swift_runtime->MaskMaybeBridgedPointer(storage_location);
std::unique_ptr<SwiftArrayBufferHandler> handler;
handler.reset(new SwiftArrayInlineBufferHandler(
storage_sp, storage_location, elem_type));
return handler;
} else {
// Swift.Array
static ConstString g_buffer("_buffer");
Expand Down
20 changes: 20 additions & 0 deletions lldb/source/Plugins/Language/Swift/SwiftArray.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,26 @@ class SwiftArraySliceBufferHandler : public SwiftArrayBufferHandler {
uint64_t m_start_index;
};

/// Handles Swift.InlineArray<>
class SwiftArrayInlineBufferHandler : public SwiftArrayBufferHandler {
public:
size_t GetCount() override;
size_t GetCapacity() override;
lldb_private::CompilerType GetElementType() override;
lldb::ValueObjectSP GetElementAtIndex(size_t) override;
bool IsValid() override;

protected:
SwiftArrayInlineBufferHandler(lldb::ValueObjectSP, lldb::addr_t,
CompilerType);
friend class SwiftArrayBufferHandler;

private:
CompilerType m_elem_type;
lldb::ValueObjectSP m_valobj_sp;
unsigned m_size;
};

class SwiftSyntheticFrontEndBufferHandler : public SwiftArrayBufferHandler {
public:
size_t GetCount() override;
Expand Down
16 changes: 4 additions & 12 deletions lldb/source/Plugins/Language/Swift/SwiftLanguage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,11 +309,8 @@ static void LoadSwiftFormatters(lldb::TypeCategoryImplSP swift_category_sp) {
AddCXXSummary(swift_category_sp,
lldb_private::formatters::swift::Array_SummaryProvider,
"Swift.Array summary provider",
ConstString("^Swift.Array<.+>$"), summary_flags, true);
AddCXXSummary(
swift_category_sp, lldb_private::formatters::swift::Array_SummaryProvider,
"Swift.ContiguousArray summary provider",
ConstString("^Swift.ContiguousArray<.+>$"), summary_flags, true);
ConstString("^Swift.(Contiguous|Inline)?Array<.+>$"),
summary_flags, true);
AddCXXSummary(swift_category_sp,
lldb_private::formatters::swift::Array_SummaryProvider,
"Swift.ArraySlice summary provider",
Expand Down Expand Up @@ -357,13 +354,8 @@ static void LoadSwiftFormatters(lldb::TypeCategoryImplSP swift_category_sp) {
AddCXXSynthetic(
swift_category_sp,
lldb_private::formatters::swift::ArraySyntheticFrontEndCreator,
"Swift.Array synthetic children", ConstString("^Swift.Array<.+>$"),
synth_flags, true);
AddCXXSynthetic(
swift_category_sp,
lldb_private::formatters::swift::ArraySyntheticFrontEndCreator,
"Swift.ContiguousArray synthetic children",
ConstString("^Swift.ContiguousArray<.+>$"), synth_flags, true);
"Swift.Array synthetic children",
ConstString("^Swift.(Contiguous|Inline)?Array<.+>$"), synth_flags, true);
AddCXXSynthetic(
swift_category_sp,
lldb_private::formatters::swift::ArraySyntheticFrontEndCreator,
Expand Down
14 changes: 11 additions & 3 deletions lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2989,13 +2989,21 @@ bool TypeSystemSwiftTypeRef::IsArrayType(opaque_compiler_type_t type,
!node->getChild(1)->hasText() ||
(node->getChild(1)->getText() != "Array" &&
node->getChild(1)->getText() != "ContiguousArray" &&
node->getChild(1)->getText() != "InlineArray" &&
node->getChild(1)->getText() != "ArraySlice"))
return false;

if (elem_node->getNumChildren() != 1 ||
elem_node->getKind() != Node::Kind::TypeList)
if (elem_node->getKind() != Node::Kind::TypeList)
return false;
elem_node = elem_node->getFirstChild();
if (node->getChild(1)->getText() == "InlineArray") {
if (elem_node->getNumChildren() != 2)
return false;
elem_node = elem_node->getChild(1);
} else {
if (elem_node->getNumChildren() != 1)
return false;
elem_node = elem_node->getFirstChild();
}
if (element_type)
// FIXME: This expensive canonicalization is only there for
// SwiftASTContext compatibility.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -212,8 +212,7 @@ def implementation(self):
lldbutil.check_variable(self, innerFuncField, False, value='8479')

array = frame.FindVariable("array")
arrayStorage = array.GetChildMemberWithName("_storage")
lldbutil.check_variable(self, arrayStorage, False, num_children=4)
lldbutil.check_variable(self, array, False, num_children=4)
for i in range(4):
lldbutil.check_variable(self, arrayStorage.GetChildAtIndex(i),
lldbutil.check_variable(self, array.GetChildAtIndex(i),
False, value=str(i+1))
4 changes: 4 additions & 0 deletions lldb/test/API/lang/swift/inline_array/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
SWIFT_SOURCES := main.swift
SWIFT_EMBEDDED_MODE := 1

include Makefile.rules
25 changes: 25 additions & 0 deletions lldb/test/API/lang/swift/inline_array/TestSwiftInlineArray.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import lldb
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbtest as lldbtest
import lldbsuite.test.lldbutil as lldbutil


class TestSwiftInlineArray(lldbtest.TestBase):

NO_DEBUG_INFO_TESTCASE = True

@swiftTest
def test(self):
"""Test the inline array synthetic child provider and summary"""
self.build()
lldbutil.run_to_source_breakpoint(
self, 'break here', lldb.SBFileSpec('main.swift'))

var_a = self.frame().FindVariable("a")
self.assertEqual(var_a.GetSummary(), "4 values")
synth_a = var_a.GetSyntheticValue()
self.assertEqual(synth_a.GetNumChildren(), 4)
self.assertEqual(synth_a.GetChildAtIndex(0).GetValue(), '4')
self.assertEqual(synth_a.GetChildAtIndex(1).GetValue(), '3')
self.assertEqual(synth_a.GetChildAtIndex(2).GetValue(), '2')
self.assertEqual(synth_a.GetChildAtIndex(3).GetValue(), '1')
7 changes: 7 additions & 0 deletions lldb/test/API/lang/swift/inline_array/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
func main() {
let a : InlineArray<4, Int> = [4,3,2,1]
print("break here \(a)")
}

main()