Skip to content

Return a SwiftArrayEmptyBufferHandler if loc points to an EmptyArray Symbol. #10920

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

Open
wants to merge 1 commit into
base: next
Choose a base branch
from
Open
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
16 changes: 16 additions & 0 deletions lldb/source/Plugins/Language/Swift/SwiftArray.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h"
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
#include "Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h"
#include "lldb/Core/Address.h"
#include "lldb/DataFormatters/FormattersHelpers.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
Expand Down Expand Up @@ -460,6 +461,21 @@ SwiftArrayBufferHandler::CreateBufferHandler(ValueObject &static_valobj) {
lldb::addr_t storage_location =
buffer_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);

lldb_private::Address addr = Address();
addr.SetLoadAddress(storage_location, exe_ctx.GetTargetPtr());

// If the storage_location points to a swiftEmptyArrayStorage symbol, return
// a SwiftArrayEmptyBufferHandler.
if (auto *symbol = addr.CalculateSymbolContextSymbol()) {
auto mangledName = symbol->GetMangled().GetMangledName().GetStringRef();
if (mangledName == "$ss19__EmptyArrayStorageCN") {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should this be _swiftEmptyArrayStorage?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am checking the mangled name:

> xcrun swift-demangle ss19__EmptyArrayStorageCN 
$ss19__EmptyArrayStorageCN ---> type metadata for Swift.__EmptyArrayStorage

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I inspect an empty array, I see:

(lldb) v -R -T -d no-dynamic-values
(Swift.Array<main.P>) x = {
  (Swift._ArrayBuffer<main.P>) _buffer = {
    (Swift._BridgeStorage<Swift.__ContiguousArrayStorageBase>) _storage = {
      (Builtin.BridgeObject) rawValue = 0x00000001f52cd120 _swiftEmptyArrayStorage
    }
  }
}

I don't see where $ss19__EmptyArrayStorageCN comes into play. Also the PR description mentions _swiftEmptyArrayStorage but the changed code does not.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This mangled name is for the type metadata for Swift.__EmptyArrayStorage.

  1. You probably want to match against Swift.__EmptyArrayStorage itself.
  2. Instead of depending on the mangling it would be better to use the helpers in SwiftDemangling.h to make sure you have the expected demangle tree for a class with the right name in STDLIB_MODULENAME.

CompilerType elem_type(
valobj.GetCompilerType().GetArrayElementType(exe_scope));
return std::unique_ptr<SwiftArrayBufferHandler>(
new SwiftArrayEmptyBufferHandler(elem_type));
}
}

if (storage_location != LLDB_INVALID_ADDRESS) {
ProcessSP process_sp(valobj.GetProcessSP());
if (!process_sp)
Expand Down
3 changes: 3 additions & 0 deletions lldb/test/API/lang/swift/swift_empty_arr/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SWIFT_SOURCES := main.swift

include Makefile.rules
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import lldb
from lldbsuite.test.decorators import *
import lldbsuite.test.lldbtest as lldbtest
import lldbsuite.test.lldbutil as lldbutil


class TestSwiftGlobalEmptyArray(lldbtest.TestBase):
@swiftTest
def test(self):
"""Test that printing a global swift array of type SwiftEmptyArrayStorage uses the correct data formatter"""

self.build()
filespec = lldb.SBFileSpec("main.swift")
target, process, thread, breakpoint1 = lldbutil.run_to_source_breakpoint(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
target, process, thread, breakpoint1 = lldbutil.run_to_source_breakpoint(
lldbutil.run_to_source_breakpoint(

self, "break here", filespec

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
self, "break here", filespec
self, "break here", lldb.SBFileSpec("main.swift")

)
self.expect("p x", substrs=["([a.P]) 0 values {}"])

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

for tests we use frame var or expr to be explicit whether it's use expression evaluation or not.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even better would be

x = self.frame().FindVariable("x")
lldbutil.check_variable(self, x, summary="0 values")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or self.assertEqual(x.GetSummary(), "0 values")

8 changes: 8 additions & 0 deletions lldb/test/API/lang/swift/swift_empty_arr/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
protocol P {}

func go() {
let x: [any P] = []
print("break here")
}

go()