Skip to content

Commit 91fa63a

Browse files
Return a SwiftArrayEmptyBufferHandler if loc points to an EmptyArray Symbol.
If we have a ValueObjectSP who's storage_location points to a S_swiftEmptyArrayStorage symbol, return a SwiftArrayEmptyBufferHandler (cherry picked from commit 9ae5681)
1 parent 8b8af30 commit 91fa63a

File tree

4 files changed

+67
-0
lines changed

4 files changed

+67
-0
lines changed

lldb/source/Plugins/Language/Swift/SwiftArray.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
#include "Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.h"
1616
#include "Plugins/TypeSystem/Clang/TypeSystemClang.h"
17+
#include "Plugins/TypeSystem/Swift/SwiftDemangle.h"
1718
#include "Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.h"
19+
#include "lldb/Core/Address.h"
1820
#include "lldb/DataFormatters/FormattersHelpers.h"
1921
#include "lldb/Target/Process.h"
2022
#include "lldb/Target/Target.h"
@@ -23,6 +25,7 @@
2325
// FIXME: we should not need this
2426
#include "Plugins/Language/ObjC/Cocoa.h"
2527
#include "lldb/lldb-enumerations.h"
28+
#include "swift/Demangling/Demangler.h"
2629

2730
using namespace lldb;
2831
using namespace lldb_private;
@@ -460,6 +463,41 @@ SwiftArrayBufferHandler::CreateBufferHandler(ValueObject &static_valobj) {
460463
lldb::addr_t storage_location =
461464
buffer_sp->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
462465

466+
lldb_private::Address addr = Address();
467+
addr.SetLoadAddress(storage_location, exe_ctx.GetTargetPtr());
468+
469+
// If the storage_location points to a swiftEmptyArrayStorage symbol, return
470+
// a SwiftArrayEmptyBufferHandler.
471+
if (auto *symbol = addr.CalculateSymbolContextSymbol()) {
472+
auto mangledName = symbol->GetMangled().GetMangledName().GetStringRef();
473+
using namespace ::swift::Demangle;
474+
Demangler dem;
475+
NodePointer node = dem.demangleSymbol(mangledName);
476+
if (node && swift_demangle::NodeAtPath(node, Node::Kind::Global)) {
477+
auto *class_node = swift_demangle::ChildAtPath(
478+
node,
479+
{Node::Kind::TypeMetadata, Node::Kind::Type, Node::Kind::Class});
480+
if (class_node && class_node->getNumChildren() == 2) {
481+
auto *module_node = class_node->getFirstChild();
482+
auto *ident_node = class_node->getLastChild();
483+
if (module_node->getKind() == Node::Kind::Module &&
484+
module_node->hasText() &&
485+
ident_node->getKind() == Node::Kind::Identifier &&
486+
ident_node->hasText()) {
487+
auto module_name = module_node->getText();
488+
auto class_name = ident_node->getText();
489+
if (module_name == ::swift::STDLIB_NAME &&
490+
class_name == "__EmptyArrayStorage") {
491+
CompilerType elem_type(
492+
valobj.GetCompilerType().GetArrayElementType(exe_scope));
493+
return std::unique_ptr<SwiftArrayBufferHandler>(
494+
new SwiftArrayEmptyBufferHandler(elem_type));
495+
}
496+
}
497+
}
498+
}
499+
}
500+
463501
if (storage_location != LLDB_INVALID_ADDRESS) {
464502
ProcessSP process_sp(valobj.GetProcessSP());
465503
if (!process_sp)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
SWIFT_SOURCES := main.swift
2+
include Makefile.rules
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
import lldbsuite.test.lldbtest as lldbtest
4+
import lldbsuite.test.lldbutil as lldbutil
5+
6+
7+
class TestSwiftGlobalEmptyArray(lldbtest.TestBase):
8+
@swiftTest
9+
def test(self):
10+
"""Test that printing a global swift array of type SwiftEmptyArrayStorage uses the correct data formatter"""
11+
12+
self.build()
13+
filespec = lldb.SBFileSpec("main.swift")
14+
lldbutil.run_to_source_breakpoint(
15+
self, "break here", filespec
16+
)
17+
x = self.frame().FindVariable("x")
18+
self.assertEqual(x.GetSummary(), "0 values")
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
protocol P {}
2+
3+
func go() {
4+
let x: [any P] = []
5+
print("break here")
6+
print(x)
7+
}
8+
9+
go()

0 commit comments

Comments
 (0)