Skip to content
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
32 changes: 32 additions & 0 deletions stdlib/public/core/DebuggerSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,38 @@ public enum _DebuggerSupport {

return target
}

// Print an object or value without the caller having a concrete type.
//
// For simplicity of data handling in LLDB avoids using an enum return type,
// using (Bool, String) instead of Optional<String>.
@available(SwiftStdlib 6.3, *)
public static func stringForPrintObject(_ pointer: UnsafeRawPointer?, mangledTypeName: String) -> (Bool, String) {
guard let pointer = unsafe pointer else {
return (false, "invalid pointer")
}

guard let type =
unsafe _getTypeByMangledNameInContext(
mangledTypeName,
UInt(mangledTypeName.count),
genericContext: nil,
genericArguments: nil)
else {
return (false, "type not found for mangled name: \(mangledTypeName)")
}

func loadPointer<T>(type: T.Type) -> Any {
if type is AnyObject.Type {
unsafe unsafeBitCast(pointer, to: T.self)
} else {
unsafe pointer.load(as: T.self)
}
}

let anyValue = _openExistential(type, do: loadPointer)
return (true, stringForPrintObject(anyValue))
}
}

public func _stringForPrintObject(_ value: Any) -> String {
Expand Down
1 change: 1 addition & 0 deletions test/abi/Inputs/macOS/arm64/stdlib/baseline
Original file line number Diff line number Diff line change
Expand Up @@ -6815,6 +6815,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF
_$ss16TextOutputStreamPsE5_lockyyF
_$ss16TextOutputStreamPsE7_unlockyyF
_$ss16TextOutputStreamTL
_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
_$ss16_DebuggerSupportOMa
_$ss16_DebuggerSupportOMn
Expand Down
1 change: 1 addition & 0 deletions test/abi/Inputs/macOS/arm64/stdlib/baseline-asserts
Original file line number Diff line number Diff line change
Expand Up @@ -6815,6 +6815,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF
_$ss16TextOutputStreamPsE5_lockyyF
_$ss16TextOutputStreamPsE7_unlockyyF
_$ss16TextOutputStreamTL
_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
_$ss16_DebuggerSupportOMa
_$ss16_DebuggerSupportOMn
Expand Down
1 change: 1 addition & 0 deletions test/abi/Inputs/macOS/x86_64/stdlib/baseline
Original file line number Diff line number Diff line change
Expand Up @@ -6836,6 +6836,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF
_$ss16TextOutputStreamPsE5_lockyyF
_$ss16TextOutputStreamPsE7_unlockyyF
_$ss16TextOutputStreamTL
_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
_$ss16_DebuggerSupportOMa
_$ss16_DebuggerSupportOMn
Expand Down
1 change: 1 addition & 0 deletions test/abi/Inputs/macOS/x86_64/stdlib/baseline-asserts
Original file line number Diff line number Diff line change
Expand Up @@ -6836,6 +6836,7 @@ _$ss16TextOutputStreamPsE11_writeASCIIyySRys5UInt8VGF
_$ss16TextOutputStreamPsE5_lockyyF
_$ss16TextOutputStreamPsE7_unlockyyF
_$ss16TextOutputStreamTL
_$ss16_DebuggerSupportO20stringForPrintObject_15mangledTypeNameSb_SStSVSg_SStFZ
_$ss16_DebuggerSupportO20stringForPrintObjectySSypFZ
_$ss16_DebuggerSupportOMa
_$ss16_DebuggerSupportOMn
Expand Down
63 changes: 63 additions & 0 deletions test/stdlib/DebuggerSupport.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ struct StructWithMembers {
var b = "Hello World"
}

struct StructIsNonCopyable: ~Copyable {
var a = 1
var b = "Hello World"
}

class ClassWithMembers {
var a = 1
var b = "Hello World"
Expand Down Expand Up @@ -108,6 +113,64 @@ if #available(SwiftStdlib 6.1, *) {
}
}

@available(SwiftStdlib 6.3, *)
func _expectStringForPrintObject<T>(_ pointer: UnsafePointer<T>, output: String) {
guard let mangledTypeName = _mangledTypeName(T.self) else {
expectTrue(false)
return
}
let (success, printed) =
_DebuggerSupport.stringForPrintObject(UnsafeRawPointer(pointer), mangledTypeName: mangledTypeName)
expectTrue(success)
expectEqual(printed, output)
}

if #available(SwiftStdlib 6.3, *) {
StringForPrintObjectTests.test("PointerWithMangledTypeName") {
var num = 33
_expectStringForPrintObject(&num, output: "33\n")

var val1 = StructWithMembers()
_expectStringForPrintObject(&val1, output: "▿ StructWithMembers\n - a : 1\n - b : \"Hello World\"\n")

var val2: StructWithMembers? = StructWithMembers()
_expectStringForPrintObject(&val2,
output: "▿ Optional<StructWithMembers>\n ▿ some : StructWithMembers\n - a : 1\n - b : \"Hello World\"\n")

do {
var val3 = StructIsNonCopyable()
if let mangledTypeName = _mangledTypeName(StructIsNonCopyable.self) {
withUnsafeBytes(of: &val3) { bytes in
guard let pointer = bytes.baseAddress else {
expectTrue(false)
return
}
let (success, printed) =
_DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName)
expectFalse(success)
expectEqual(printed, "type not found for mangled name: \(mangledTypeName)")
}
} else {
expectTrue(false)
}
}

do {
let obj = ClassWithMembers()
if let mangledTypeName = _mangledTypeName(ClassWithMembers.self) {
withExtendedLifetime(obj) { obj in
let pointer = unsafeBitCast(obj, to: UnsafeRawPointer.self)
let (success, printed) = _DebuggerSupport.stringForPrintObject(pointer, mangledTypeName: mangledTypeName)
expectTrue(success)
expectTrue(printed.hasPrefix("<ClassWithMembers: 0x"))
}
} else {
expectTrue(false)
}
}
}
}

class RefCountedObj {
var patatino : Int
init(_ p : Int) {
Expand Down