From 38f5709e6184aad376ca001e00ceea670f86d6d5 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 2 Dec 2025 15:54:51 -0800 Subject: [PATCH 01/14] [lldb] Adopt new pointer and mangled typename based stringForPrintObject Adopt `stringForPrintObject(_:mangledTypeName:)`, an overload added in https://github.com/swiftlang/swift/pull/84742. This new overload allows lldb to call `stringForPrintObject` using only a pointer referencing the value, and the mangled typename corresponding to the value. The resulting expression does not reference the concrete type. By not referencing a value's type, `po` can be performed on variables (and their nested stored properties) without loading the modules corresponding to the value's type. This will improve performance and reliability of `po`. --- lldb/include/lldb/Target/Target.h | 7 ++ .../Swift/SwiftExpressionSourceCode.cpp | 22 ++-- .../Swift/SwiftLanguageRuntime.cpp | 108 ++++++++++++++++-- .../TestSwiftExpressionErrorReporting.py | 6 +- 4 files changed, 125 insertions(+), 18 deletions(-) diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 476715ebb9ce1..fc5c58751a59d 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -566,6 +566,10 @@ class EvaluateExpressionOptions { bool GetPreparePlaygroundStubFunctions() const { return m_prepare_playground_stub_functions; } + void SetDisableAvailability() { m_disable_availability = true; } + + bool GetDisableAvailability() const { return m_disable_availability; } + private: ExecutionPolicy m_execution_policy = default_execution_policy; SourceLanguage m_language; @@ -607,6 +611,9 @@ class EvaluateExpressionOptions { mutable uint32_t m_pound_line_line = 0; bool m_prepare_playground_stub_functions = true; + /// Disable compiler availability checking. + bool m_disable_availability = false; + /// During expression evaluation, any SymbolContext in this list will be /// used for symbol/function lookup before any other context (except for /// the module corresponding to the current frame). diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp index 80f342d80e9b2..49e1a129188a6 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp @@ -640,15 +640,21 @@ Status SwiftExpressionSourceCode::GetText( if (triple.isOSDarwin()) { if (auto process_sp = exe_ctx.GetProcessSP()) { os_vers << getAvailabilityName(triple) << " "; - auto platform = target->GetPlatform(); - bool is_simulator = platform->GetPluginName().ends_with("-simulator"); - if (is_simulator) { - // The simulators look like the host OS to Process, but Platform - // can the version out of an environment variable. - os_vers << platform->GetOSVersion(process_sp.get()).getAsString(); + if (options.GetDisableAvailability()) { + // Disable availability by setting the OS version to 9999, the + // placeholder number used for future OS versions. + os_vers << "9999"; } else { - llvm::VersionTuple version = process_sp->GetHostOSVersion(); - os_vers << version.getAsString(); + auto platform = target->GetPlatform(); + bool is_simulator = platform->GetPluginName().ends_with("-simulator"); + if (is_simulator) { + // The simulators look like the host OS to Process, but Platform + // can the version out of an environment variable. + os_vers << platform->GetOSVersion(process_sp.get()).getAsString(); + } else { + llvm::VersionTuple version = process_sp->GetHostOSVersion(); + os_vers << version.getAsString(); + } } } } diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index 9ea5ae4b7411e..add3cf7187f2e 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -48,6 +48,7 @@ #include "lldb/Utility/Log.h" #include "lldb/Utility/OptionParsing.h" #include "lldb/Utility/Status.h" +#include "lldb/Utility/StreamString.h" #include "lldb/Utility/StructuredData.h" #include "lldb/Utility/Timer.h" #include "lldb/ValueObject/ValueObject.h" @@ -835,7 +836,7 @@ SwiftLanguageRuntime::GetObjectDescriptionExpr_Ref(ValueObject &object) { object.GetValueAsUnsigned(0)).str(); if (log) - log->Printf("[GetObjectDescriptionExpr_Result] expression: %s", + log->Printf("[GetObjectDescriptionExpr_Ref] expression: %s", expr_string.GetData()); return expr_str; } @@ -911,8 +912,9 @@ std::string SwiftLanguageRuntime::GetObjectDescriptionExpr_Copy( return expr_string; } -llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr( - ValueObject &object, std::string &expr_string, Stream &result) { +static llvm::Expected +runObjectDescription(ValueObject &object, std::string &expr_string, + Process &process, bool disable_availability = false) { Log *log(GetLog(LLDBLog::DataFormatters | LLDBLog::Expressions)); ValueObjectSP result_sp; EvaluateExpressionOptions eval_options; @@ -920,16 +922,17 @@ llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr( eval_options.SetLanguage(lldb::eLanguageTypeSwift); eval_options.SetSuppressPersistentResult(true); eval_options.SetIgnoreBreakpoints(true); - eval_options.SetTimeout(GetProcess().GetUtilityExpressionTimeout()); + eval_options.SetTimeout(process.GetUtilityExpressionTimeout()); + if (disable_availability) + eval_options.SetDisableAvailability(); StackFrameSP frame_sp = object.GetFrameSP(); if (!frame_sp) - frame_sp = - GetProcess().GetThreadList().GetSelectedThread()->GetSelectedFrame( - DoNoSelectMostRelevantFrame); + frame_sp = process.GetThreadList().GetSelectedThread()->GetSelectedFrame( + DoNoSelectMostRelevantFrame); if (!frame_sp) return llvm::createStringError("no execution context to run expression in"); - auto eval_result = GetProcess().GetTarget().EvaluateExpression( + auto eval_result = process.GetTarget().EvaluateExpression( expr_string, frame_sp.get(), result_sp, eval_options); LLDB_LOG(log, "[RunObjectDescriptionExpr] {0}", toString(eval_result)); @@ -952,12 +955,28 @@ llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr( return llvm::createStringError("expression produced invalid result type"); } + return result_sp; +} + +static llvm::Error dumpString(ValueObjectSP result_sp, Stream &strm); + +llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr( + ValueObject &object, std::string &expr_string, Stream &strm) { + auto result_or_err = runObjectDescription(object, expr_string, GetProcess()); + if (!result_or_err) + return result_or_err.takeError(); + + return dumpString(*result_or_err, strm); +} + +static llvm::Error dumpString(ValueObjectSP result_sp, Stream &strm) { + Log *log(GetLog(LLDBLog::DataFormatters | LLDBLog::Expressions)); formatters::StringPrinter::ReadStringAndDumpToStreamOptions dump_options; dump_options.SetEscapeNonPrintables(false); dump_options.SetQuote('\0'); dump_options.SetPrefixToken(nullptr); if (formatters::swift::String_SummaryProvider( - *result_sp.get(), result, + *result_sp, strm, TypeSummaryOptions() .SetLanguage(lldb::eLanguageTypeSwift) .SetCapping(eTypeSummaryUncapped), @@ -1002,11 +1021,82 @@ static bool IsSwiftReferenceType(ValueObject &object) { return false; } +static bool printObjectViaPointer(Stream &strm, ValueObject &object, + Process &process) { + Log *log = GetLog(LLDBLog::DataFormatters | LLDBLog::Expressions); + + Flags flags(object.GetCompilerType().GetTypeInfo()); + addr_t addr = LLDB_INVALID_ADDRESS; + if (flags.Test(eTypeInstanceIsPointer)) { + // Objects are pointers. + addr = object.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); + } else { + // Get the address of non-object values (structs, enums). + auto addr_and_type = object.GetAddressOf(false); + if (addr_and_type.type != eAddressTypeLoad) { + LLDB_LOG(log, "address-of value object failed, preventing use of " + "stringForPrintObject(_:mangledTypeName:)"); + return false; + } + addr = addr_and_type.address; + } + + if (addr == 0 || addr == LLDB_INVALID_ADDRESS) + return false; + + StringRef mangled_type_name = object.GetMangledTypeName(); + // Swift's APIs that accept mangled names require the "$s" prefix removed. + mangled_type_name.consume_front("$s"); + + std::string expr_string = + llvm::formatv( + "Swift._DebuggerSupport.stringForPrintObject(UnsafeRawPointer(" + "bitPattern: {0}), mangledTypeName: \"{1}\")", + addr, mangled_type_name) + .str(); + + auto result_or_err = runObjectDescription(object, expr_string, process, true); + if (!result_or_err) { + LLDB_LOG_ERROR(log, result_or_err.takeError(), + "stringForPrintObject(_:mangledTypeName:) failed: {0}"); + return false; + } + + // A `(Bool, String)` tuple, where the bool indicates success/failure. + auto result_sp = *result_or_err; + auto success_sp = result_sp->GetChildAtIndex(0); + auto description_sp = result_sp->GetChildAtIndex(1); + + StreamString dump_stream; + auto err = dumpString(description_sp, dump_stream); + if (err) { + LLDB_LOG_ERROR(log, std::move(err), + "decoding result of " + "stringForPrintObject(_:mangledTypeName:) failed: {0}"); + return false; + } + + Status status; + if (!success_sp->IsLogicalTrue(status)) { + LLDB_LOGF(log, + "stringForPrintObject(_:mangledTypeName:) produced error: %s", + dump_stream.GetData()); + return false; + } + + LLDB_LOG(log, "stringForPrintObject(_:mangledTypeName:) succeeded"); + strm.PutCString(dump_stream.GetString()); + return true; +} + llvm::Error SwiftLanguageRuntime::GetObjectDescription(Stream &str, ValueObject &object) { if (object.IsUninitializedReference()) return llvm::createStringError(""); + if (tryPointerPrintObject(str, object, GetProcess())) + return llvm::Error::success(); + std::string expr_string; if (::IsVariable(object) || ::IsSwiftResultVariable(object.GetName())) { diff --git a/lldb/test/API/lang/swift/expression/error_reporting/TestSwiftExpressionErrorReporting.py b/lldb/test/API/lang/swift/expression/error_reporting/TestSwiftExpressionErrorReporting.py index ca543525dc038..5485b783ce93d 100644 --- a/lldb/test/API/lang/swift/expression/error_reporting/TestSwiftExpressionErrorReporting.py +++ b/lldb/test/API/lang/swift/expression/error_reporting/TestSwiftExpressionErrorReporting.py @@ -81,9 +81,13 @@ def check(value): check(value) + # This succeeds using stringForPrintObject(_:mangledTypeName:), which + # doesn't require the type to be available. + # Note: (?s)^(?!.*) checks that the pattern is not found. + # self.runCmd("log enable lldb formatters") self.expect( "dwim-print -O -- strct", - substrs=["error: Missing type", "properties = true"], + patterns=["(?s)^(?!.*error: Missing type)", "properties : true"], ) process.Continue() From 9cd7c44bef841f037d83febeb27e8ed0a7cb787b Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 2 Dec 2025 16:05:42 -0800 Subject: [PATCH 02/14] Fix missing rename --- .../Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index add3cf7187f2e..6a4ae32630f97 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -1094,7 +1094,7 @@ llvm::Error SwiftLanguageRuntime::GetObjectDescription(Stream &str, if (object.IsUninitializedReference()) return llvm::createStringError(""); - if (tryPointerPrintObject(str, object, GetProcess())) + if (printObjectViaPointer(str, object, GetProcess())) return llvm::Error::success(); std::string expr_string; From 3c969d68c114bb8ecb2a9177425d060651166c3b Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 3 Dec 2025 10:48:54 -0800 Subject: [PATCH 03/14] Add setting gating the new po, initially disabled by default --- lldb/include/lldb/Target/Target.h | 2 ++ .../LanguageRuntime/Swift/SwiftLanguageRuntime.cpp | 5 +++-- lldb/source/Target/Target.cpp | 12 ++++++++++++ lldb/source/Target/TargetProperties.td | 3 +++ .../TestSwiftExpressionErrorReporting.py | 4 ++-- 5 files changed, 22 insertions(+), 4 deletions(-) diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index fc5c58751a59d..81e0634f5ddd6 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -215,6 +215,8 @@ class TargetProperties : public Properties { bool GetSwiftAutoImportFrameworks() const; + bool GetSwiftUseNewPrintObject() const; + bool GetEnableAutoImportClangModules() const; bool GetUseAllCompilerFlags() const; diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index 6a4ae32630f97..8b8ff7e1a0a14 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -1094,8 +1094,9 @@ llvm::Error SwiftLanguageRuntime::GetObjectDescription(Stream &str, if (object.IsUninitializedReference()) return llvm::createStringError(""); - if (printObjectViaPointer(str, object, GetProcess())) - return llvm::Error::success(); + if (GetProcess().GetTarget().GetSwiftUseNewPrintObject()) + if (printObjectViaPointer(str, object, GetProcess())) + return llvm::Error::success(); std::string expr_string; diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index cd977fcaeeedd..6728ed8bda520 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -4705,6 +4705,18 @@ bool TargetProperties::GetSwiftAutoImportFrameworks() const { idx, g_target_properties[idx].default_uint_value != 0); } +bool TargetProperties::GetSwiftUseNewPrintObject() const { + const Property *exp_property = + m_collection_sp->GetPropertyAtIndex(ePropertyExperimental); + OptionValueProperties *exp_values = + exp_property->GetValue()->GetAsProperties(); + if (exp_values) + return exp_values + ->GetPropertyAtIndexAs(ePropertySwiftUseNewPrintObject) + .value_or(false); + return false; +} + void TargetProperties::SetUseDIL(ExecutionContext *exe_ctx, bool b) { const Property *exp_property = m_collection_sp->GetPropertyAtIndex(ePropertyExperimental, exe_ctx); diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td index 62c8290847576..75a30cd7c05c4 100644 --- a/lldb/source/Target/TargetProperties.td +++ b/lldb/source/Target/TargetProperties.td @@ -37,6 +37,9 @@ let Definition = "target_experimental" in { def SwiftCacheTaskPointerLocation: Property<"swift-cache-task-pointer-location", "Boolean">, DefaultTrue, Desc<"Enables caching of task pointers inside the swift tasks plugin">; + def SwiftUseNewPrintObject: Property<"swift-use-new-po", "Boolean">, + DefaultFalse, + Desc<"If true, use the new Swift po implementation.">; def UseDIL : Property<"use-DIL", "Boolean">, Global, DefaultTrue, Desc<"If true, use the DIL implementation for frame variable evaluation.">; diff --git a/lldb/test/API/lang/swift/expression/error_reporting/TestSwiftExpressionErrorReporting.py b/lldb/test/API/lang/swift/expression/error_reporting/TestSwiftExpressionErrorReporting.py index 5485b783ce93d..af4f1102d7edd 100644 --- a/lldb/test/API/lang/swift/expression/error_reporting/TestSwiftExpressionErrorReporting.py +++ b/lldb/test/API/lang/swift/expression/error_reporting/TestSwiftExpressionErrorReporting.py @@ -68,6 +68,8 @@ def test_missing_type(self): target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( self, 'break here', lldb.SBFileSpec('main.swift')) + self.runCmd("settings set target.experimental.swift-use-new-po true") + options = lldb.SBExpressionOptions() value = self.frame().EvaluateExpression("strct", options) def check(value): @@ -84,7 +86,6 @@ def check(value): # This succeeds using stringForPrintObject(_:mangledTypeName:), which # doesn't require the type to be available. # Note: (?s)^(?!.*) checks that the pattern is not found. - # self.runCmd("log enable lldb formatters") self.expect( "dwim-print -O -- strct", patterns=["(?s)^(?!.*error: Missing type)", "properties : true"], @@ -93,4 +94,3 @@ def check(value): process.Continue() self.expect('expression -O -- number', error=True, substrs=['self', 'not', 'found']) - From caade2216c5aaf595ffc22a4a4c6f32e1fcbb540 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 3 Dec 2025 15:22:39 -0800 Subject: [PATCH 04/14] Add tests for new po --- .../po/pointer_and_mangled_typename/Makefile | 3 + .../TestSwiftPrintObjectPointerAndTypeName.py | 117 ++++++++++++++++++ .../pointer_and_mangled_typename/main.swift | 97 +++++++++++++++ 3 files changed, 217 insertions(+) create mode 100644 lldb/test/API/lang/swift/po/pointer_and_mangled_typename/Makefile create mode 100644 lldb/test/API/lang/swift/po/pointer_and_mangled_typename/TestSwiftPrintObjectPointerAndTypeName.py create mode 100644 lldb/test/API/lang/swift/po/pointer_and_mangled_typename/main.swift diff --git a/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/Makefile b/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/Makefile new file mode 100644 index 0000000000000..cca30b939e652 --- /dev/null +++ b/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/Makefile @@ -0,0 +1,3 @@ +SWIFT_SOURCES := main.swift +SWIFTFLAGS_EXTRAS := -parse-as-library +include Makefile.rules diff --git a/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/TestSwiftPrintObjectPointerAndTypeName.py b/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/TestSwiftPrintObjectPointerAndTypeName.py new file mode 100644 index 0000000000000..5ab0078ed0774 --- /dev/null +++ b/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/TestSwiftPrintObjectPointerAndTypeName.py @@ -0,0 +1,117 @@ +import lldb +import lldbsuite.test.lldbutil as lldbutil +from lldbsuite.test.lldbtest import * +from lldbsuite.test.decorators import * + + +class TestCase(TestBase): + + def setUp(self): + TestBase.setUp(self) + self.build() + self.runCmd("settings set target.experimental.swift-use-new-po true") + + self.log = self.getBuildArtifact("expr.log") + self.runCmd(f"log enable lldb expr -f {self.log}") + + def _filecheck(self, key): + self.filecheck(f"platform shell cat {self.log}", __file__, f"-check-prefix=CHECK-{key}") + + @swiftTest + def test_int(self): + lldbutil.run_to_source_breakpoint( + self, "break int", lldb.SBFileSpec("main.swift") + ) + self.expect("po value", substrs=["2025"]) + self._filecheck("INT") + # CHECK-INT: stringForPrintObject(UnsafeRawPointer(bitPattern: {{[0-9]+}}), mangledTypeName: "SiD") + + @swiftTest + def test_string(self): + lldbutil.run_to_source_breakpoint( + self, "break string", lldb.SBFileSpec("main.swift") + ) + self.expect("po value", substrs=["Po"]) + self._filecheck("STRING") + # CHECK-STRING: stringForPrintObject(UnsafeRawPointer(bitPattern: {{[0-9]+}}), mangledTypeName: "SSD") + + @swiftTest + def test_struct(self): + lldbutil.run_to_source_breakpoint( + self, "break struct", lldb.SBFileSpec("main.swift") + ) + self.expect("po value", substrs=["▿ Struct"]) + self._filecheck("STRUCT") + # CHECK-STRUCT: stringForPrintObject(UnsafeRawPointer(bitPattern: {{[0-9]+}}), mangledTypeName: "1a6StructVD") + + @swiftTest + def test_class(self): + lldbutil.run_to_source_breakpoint( + self, "break class", lldb.SBFileSpec("main.swift") + ) + self.expect("po value", substrs=[""]) + self._filecheck("GEN-STRUCT") + # CHECK-GEN-STRUCT: stringForPrintObject(UnsafeRawPointer(bitPattern: {{[0-9]+}}), mangledTypeName: "1a13GenericStructVySSGD") + + @swiftTest + def test_generic_class(self): + lldbutil.run_to_source_breakpoint( + self, "break generic class", lldb.SBFileSpec("main.swift") + ) + self.expect("po value", substrs=[": 0x"]) + self._filecheck("GEN-CLASS") + # CHECK-GEN-CLASS: stringForPrintObject(UnsafeRawPointer(bitPattern: {{[0-9]+}}), mangledTypeName: "1a12GenericClassCySSGD") + + @swiftTest + def test_generic_enum(self): + lldbutil.run_to_source_breakpoint( + self, "break generic enum", lldb.SBFileSpec("main.swift") + ) + self.expect("po value", substrs=["▿ GenericEnum"]) + self._filecheck("GEN-ENUM") + # CHECK-GEN-ENUM: stringForPrintObject(UnsafeRawPointer(bitPattern: {{.*}}), mangledTypeName: "1a11GenericEnumOySSGD") + + @swiftTest + def test_described_struct(self): + lldbutil.run_to_source_breakpoint( + self, "break described struct", lldb.SBFileSpec("main.swift") + ) + self.expect("po value", substrs=["DescribedStruct"]) + self._filecheck("DESC-STRUCT") + # CHECK-DESC-STRUCT: stringForPrintObject(UnsafeRawPointer(bitPattern: {{[0-9]+}}), mangledTypeName: "1a15DescribedStructVD") + + @swiftTest + def test_described_class(self): + lldbutil.run_to_source_breakpoint( + self, "break described class", lldb.SBFileSpec("main.swift") + ) + self.expect("po value", substrs=["DescribedClass"]) + self._filecheck("DESC-CLASS") + # CHECK-DESC-CLASS: stringForPrintObject(UnsafeRawPointer(bitPattern: {{[0-9]+}}), mangledTypeName: "1a14DescribedClassCD") + + @swiftTest + def test_described_enum(self): + lldbutil.run_to_source_breakpoint( + self, "break described enum", lldb.SBFileSpec("main.swift") + ) + self.expect("po value", substrs=["DescribedEnum"]) + self._filecheck("DESC-ENUM") + # CHECK-DESC-ENUM: stringForPrintObject(UnsafeRawPointer(bitPattern: {{.*}}), mangledTypeName: "1a13DescribedEnumOD") diff --git a/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/main.swift b/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/main.swift new file mode 100644 index 0000000000000..2a5c0fc198b45 --- /dev/null +++ b/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/main.swift @@ -0,0 +1,97 @@ +struct Struct { + var s = "Po" + var n = 2025 +} + +class Class { + var s = "Po" + var n = 2025 +} + +enum Enum { + case zero + case pair(String, Int) +} + +struct GenericStruct { + var s: T + var n = 2025 +} + +class GenericClass { + var s: T + var n = 2025 + init(s: T) { self.s = s } +} + +enum GenericEnum { + case zero + case pair(T, Int) +} + +struct DescribedStruct: CustomStringConvertible { + var s = "Po" + var n = 2025 + var description: String { "DescribedStruct" } +} + +class DescribedClass: CustomStringConvertible { + var s = "Po" + var n = 2025 + var description: String { "DescribedClass" } +} + +enum DescribedEnum: CustomStringConvertible { + case zero + case pair(String, Int) + var description: String { "DescribedEnum" } +} + +@main struct Entry { + static func main() { + do { + var value = 2025 + print("break int") + } + do { + var value = "Po" + print("break string") + } + do { + let value = Struct() + print("break struct") + } + do { + let value = Class() + print("break class") + } + do { + let value = Enum.pair("Po", 50) + print("break enum") + } + do { + let value = GenericStruct(s: "Po") + print("break generic struct") + } + do { + let value = GenericClass(s: "Po") + print("break generic class") + } + do { + let value = GenericEnum.pair("Po", 50) + print("break generic enum") + } + do { + let value = DescribedStruct() + print("break described struct") + } + do { + let value = DescribedClass() + print("break described class") + } + do { + let value = DescribedEnum.pair("Po", 50) + print("break described enum") + } + } +} From defe91509a23ced4aa46a3ecd519af45388bd99f Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 9 Dec 2025 10:21:09 -0800 Subject: [PATCH 05/14] Update names --- lldb/include/lldb/Target/Target.h | 2 +- .../Swift/SwiftLanguageRuntime.cpp | 34 +++++++++---------- lldb/source/Target/Target.cpp | 4 +-- lldb/source/Target/TargetProperties.td | 4 +-- .../TestSwiftExpressionErrorReporting.py | 2 +- .../TestSwiftPrintObjectPointerAndTypeName.py | 2 +- 6 files changed, 23 insertions(+), 25 deletions(-) diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 81e0634f5ddd6..8b56d4c7b7601 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -215,7 +215,7 @@ class TargetProperties : public Properties { bool GetSwiftAutoImportFrameworks() const; - bool GetSwiftUseNewPrintObject() const; + bool GetSwiftUseContextFreePrintObject() const; bool GetEnableAutoImportClangModules() const; diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index 8b8ff7e1a0a14..42e9af45fd753 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -913,7 +913,7 @@ std::string SwiftLanguageRuntime::GetObjectDescriptionExpr_Copy( } static llvm::Expected -runObjectDescription(ValueObject &object, std::string &expr_string, +RunObjectDescription(ValueObject &object, std::string &expr_string, Process &process, bool disable_availability = false) { Log *log(GetLog(LLDBLog::DataFormatters | LLDBLog::Expressions)); ValueObjectSP result_sp; @@ -958,18 +958,7 @@ runObjectDescription(ValueObject &object, std::string &expr_string, return result_sp; } -static llvm::Error dumpString(ValueObjectSP result_sp, Stream &strm); - -llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr( - ValueObject &object, std::string &expr_string, Stream &strm) { - auto result_or_err = runObjectDescription(object, expr_string, GetProcess()); - if (!result_or_err) - return result_or_err.takeError(); - - return dumpString(*result_or_err, strm); -} - -static llvm::Error dumpString(ValueObjectSP result_sp, Stream &strm) { +static llvm::Error DumpString(ValueObjectSP result_sp, Stream &strm) { Log *log(GetLog(LLDBLog::DataFormatters | LLDBLog::Expressions)); formatters::StringPrinter::ReadStringAndDumpToStreamOptions dump_options; dump_options.SetEscapeNonPrintables(false); @@ -992,6 +981,15 @@ static llvm::Error dumpString(ValueObjectSP result_sp, Stream &strm) { return llvm::createStringError("expression produced unprintable string"); } +llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr( + ValueObject &object, std::string &expr_string, Stream &strm) { + auto result_or_err = RunObjectDescription(object, expr_string, GetProcess()); + if (!result_or_err) + return result_or_err.takeError(); + + return DumpString(*result_or_err, strm); +} + static bool IsVariable(ValueObject &object) { if (object.IsSynthetic()) return IsVariable(*object.GetNonSyntheticValue()); @@ -1021,7 +1019,7 @@ static bool IsSwiftReferenceType(ValueObject &object) { return false; } -static bool printObjectViaPointer(Stream &strm, ValueObject &object, +static bool PrintObjectViaPointer(Stream &strm, ValueObject &object, Process &process) { Log *log = GetLog(LLDBLog::DataFormatters | LLDBLog::Expressions); @@ -1055,7 +1053,7 @@ static bool printObjectViaPointer(Stream &strm, ValueObject &object, addr, mangled_type_name) .str(); - auto result_or_err = runObjectDescription(object, expr_string, process, true); + auto result_or_err = RunObjectDescription(object, expr_string, process, true); if (!result_or_err) { LLDB_LOG_ERROR(log, result_or_err.takeError(), "stringForPrintObject(_:mangledTypeName:) failed: {0}"); @@ -1068,7 +1066,7 @@ static bool printObjectViaPointer(Stream &strm, ValueObject &object, auto description_sp = result_sp->GetChildAtIndex(1); StreamString dump_stream; - auto err = dumpString(description_sp, dump_stream); + auto err = DumpString(description_sp, dump_stream); if (err) { LLDB_LOG_ERROR(log, std::move(err), "decoding result of " @@ -1094,8 +1092,8 @@ llvm::Error SwiftLanguageRuntime::GetObjectDescription(Stream &str, if (object.IsUninitializedReference()) return llvm::createStringError(""); - if (GetProcess().GetTarget().GetSwiftUseNewPrintObject()) - if (printObjectViaPointer(str, object, GetProcess())) + if (GetProcess().GetTarget().GetSwiftUseContextFreePrintObject()) + if (PrintObjectViaPointer(str, object, GetProcess())) return llvm::Error::success(); std::string expr_string; diff --git a/lldb/source/Target/Target.cpp b/lldb/source/Target/Target.cpp index 6728ed8bda520..7bc75d664e8fc 100644 --- a/lldb/source/Target/Target.cpp +++ b/lldb/source/Target/Target.cpp @@ -4705,14 +4705,14 @@ bool TargetProperties::GetSwiftAutoImportFrameworks() const { idx, g_target_properties[idx].default_uint_value != 0); } -bool TargetProperties::GetSwiftUseNewPrintObject() const { +bool TargetProperties::GetSwiftUseContextFreePrintObject() const { const Property *exp_property = m_collection_sp->GetPropertyAtIndex(ePropertyExperimental); OptionValueProperties *exp_values = exp_property->GetValue()->GetAsProperties(); if (exp_values) return exp_values - ->GetPropertyAtIndexAs(ePropertySwiftUseNewPrintObject) + ->GetPropertyAtIndexAs(ePropertySwiftUseContextFreePrintObject) .value_or(false); return false; } diff --git a/lldb/source/Target/TargetProperties.td b/lldb/source/Target/TargetProperties.td index 75a30cd7c05c4..7d7263ece5c48 100644 --- a/lldb/source/Target/TargetProperties.td +++ b/lldb/source/Target/TargetProperties.td @@ -37,9 +37,9 @@ let Definition = "target_experimental" in { def SwiftCacheTaskPointerLocation: Property<"swift-cache-task-pointer-location", "Boolean">, DefaultTrue, Desc<"Enables caching of task pointers inside the swift tasks plugin">; - def SwiftUseNewPrintObject: Property<"swift-use-new-po", "Boolean">, + def SwiftUseContextFreePrintObject: Property<"swift-use-context-free-po", "Boolean">, DefaultFalse, - Desc<"If true, use the new Swift po implementation.">; + Desc<"If true, use the context-free po implementation for Swift.">; def UseDIL : Property<"use-DIL", "Boolean">, Global, DefaultTrue, Desc<"If true, use the DIL implementation for frame variable evaluation.">; diff --git a/lldb/test/API/lang/swift/expression/error_reporting/TestSwiftExpressionErrorReporting.py b/lldb/test/API/lang/swift/expression/error_reporting/TestSwiftExpressionErrorReporting.py index af4f1102d7edd..e665b77e9635e 100644 --- a/lldb/test/API/lang/swift/expression/error_reporting/TestSwiftExpressionErrorReporting.py +++ b/lldb/test/API/lang/swift/expression/error_reporting/TestSwiftExpressionErrorReporting.py @@ -68,7 +68,7 @@ def test_missing_type(self): target, process, thread, bkpt = lldbutil.run_to_source_breakpoint( self, 'break here', lldb.SBFileSpec('main.swift')) - self.runCmd("settings set target.experimental.swift-use-new-po true") + self.runCmd("settings set target.experimental.swift-use-context-free-po true") options = lldb.SBExpressionOptions() value = self.frame().EvaluateExpression("strct", options) diff --git a/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/TestSwiftPrintObjectPointerAndTypeName.py b/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/TestSwiftPrintObjectPointerAndTypeName.py index 5ab0078ed0774..478021528468c 100644 --- a/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/TestSwiftPrintObjectPointerAndTypeName.py +++ b/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/TestSwiftPrintObjectPointerAndTypeName.py @@ -9,7 +9,7 @@ class TestCase(TestBase): def setUp(self): TestBase.setUp(self) self.build() - self.runCmd("settings set target.experimental.swift-use-new-po true") + self.runCmd("settings set target.experimental.swift-use-context-free-po true") self.log = self.getBuildArtifact("expr.log") self.runCmd(f"log enable lldb expr -f {self.log}") From ff4b0666236e1476b1dcb50b1c830578cfbdf3f6 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 9 Dec 2025 10:23:19 -0800 Subject: [PATCH 06/14] Support embedded swift prefix --- .../Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index 42e9af45fd753..df7b85a4919c5 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -1043,8 +1043,9 @@ static bool PrintObjectViaPointer(Stream &strm, ValueObject &object, return false; StringRef mangled_type_name = object.GetMangledTypeName(); - // Swift's APIs that accept mangled names require the "$s" prefix removed. + // Swift APIs that receive mangled names require the prefix removed. mangled_type_name.consume_front("$s"); + mangled_type_name.consume_front("$e"); // Embedded Swift prefix std::string expr_string = llvm::formatv( From 714c3bb0dc0e60fcf7f483989ba85b4e97bf0a59 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Tue, 9 Dec 2025 10:26:43 -0800 Subject: [PATCH 07/14] Update comment about OS version 9999 --- .../ExpressionParser/Swift/SwiftExpressionSourceCode.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp index 49e1a129188a6..3bdbce6fa5399 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp @@ -641,8 +641,9 @@ Status SwiftExpressionSourceCode::GetText( if (auto process_sp = exe_ctx.GetProcessSP()) { os_vers << getAvailabilityName(triple) << " "; if (options.GetDisableAvailability()) { - // Disable availability by setting the OS version to 9999, the - // placeholder number used for future OS versions. + // Disable availability by setting the OS version to 9999. This + // placeholder OS version used for future OS versions when building + // the Swift standard library locally. os_vers << "9999"; } else { auto platform = target->GetPlatform(); From efa060f293b31fa9fffab1ac71c9f482d0657240 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 10 Dec 2025 10:06:49 -0800 Subject: [PATCH 08/14] Move self.build() out of setUp and into the test functions --- .../TestSwiftPrintObjectPointerAndTypeName.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/TestSwiftPrintObjectPointerAndTypeName.py b/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/TestSwiftPrintObjectPointerAndTypeName.py index 478021528468c..a3129e9779a53 100644 --- a/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/TestSwiftPrintObjectPointerAndTypeName.py +++ b/lldb/test/API/lang/swift/po/pointer_and_mangled_typename/TestSwiftPrintObjectPointerAndTypeName.py @@ -8,7 +8,6 @@ class TestCase(TestBase): def setUp(self): TestBase.setUp(self) - self.build() self.runCmd("settings set target.experimental.swift-use-context-free-po true") self.log = self.getBuildArtifact("expr.log") @@ -19,6 +18,7 @@ def _filecheck(self, key): @swiftTest def test_int(self): + self.build() lldbutil.run_to_source_breakpoint( self, "break int", lldb.SBFileSpec("main.swift") ) @@ -28,6 +28,7 @@ def test_int(self): @swiftTest def test_string(self): + self.build() lldbutil.run_to_source_breakpoint( self, "break string", lldb.SBFileSpec("main.swift") ) @@ -37,6 +38,7 @@ def test_string(self): @swiftTest def test_struct(self): + self.build() lldbutil.run_to_source_breakpoint( self, "break struct", lldb.SBFileSpec("main.swift") ) @@ -46,6 +48,7 @@ def test_struct(self): @swiftTest def test_class(self): + self.build() lldbutil.run_to_source_breakpoint( self, "break class", lldb.SBFileSpec("main.swift") ) @@ -55,6 +58,7 @@ def test_class(self): @swiftTest def test_enum(self): + self.build() lldbutil.run_to_source_breakpoint( self, "break enum", lldb.SBFileSpec("main.swift") ) @@ -64,6 +68,7 @@ def test_enum(self): @swiftTest def test_generic_struct(self): + self.build() lldbutil.run_to_source_breakpoint( self, "break generic struct", lldb.SBFileSpec("main.swift") ) @@ -73,6 +78,7 @@ def test_generic_struct(self): @swiftTest def test_generic_class(self): + self.build() lldbutil.run_to_source_breakpoint( self, "break generic class", lldb.SBFileSpec("main.swift") ) @@ -82,6 +88,7 @@ def test_generic_class(self): @swiftTest def test_generic_enum(self): + self.build() lldbutil.run_to_source_breakpoint( self, "break generic enum", lldb.SBFileSpec("main.swift") ) @@ -91,6 +98,7 @@ def test_generic_enum(self): @swiftTest def test_described_struct(self): + self.build() lldbutil.run_to_source_breakpoint( self, "break described struct", lldb.SBFileSpec("main.swift") ) @@ -100,6 +108,7 @@ def test_described_struct(self): @swiftTest def test_described_class(self): + self.build() lldbutil.run_to_source_breakpoint( self, "break described class", lldb.SBFileSpec("main.swift") ) @@ -109,6 +118,7 @@ def test_described_class(self): @swiftTest def test_described_enum(self): + self.build() lldbutil.run_to_source_breakpoint( self, "break described enum", lldb.SBFileSpec("main.swift") ) From f6bf6ddfab03fe3574d2dc5ed16ca4defc0c7260 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Wed, 10 Dec 2025 10:08:18 -0800 Subject: [PATCH 09/14] Refactor PrintObjectViaPointer to return Error instead of bool --- .../Swift/SwiftLanguageRuntime.cpp | 55 +++++++++---------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index df7b85a4919c5..f4121cd79b792 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -1019,10 +1019,8 @@ static bool IsSwiftReferenceType(ValueObject &object) { return false; } -static bool PrintObjectViaPointer(Stream &strm, ValueObject &object, - Process &process) { - Log *log = GetLog(LLDBLog::DataFormatters | LLDBLog::Expressions); - +static llvm::Error PrintObjectViaPointer(Stream &strm, ValueObject &object, + Process &process) { Flags flags(object.GetCompilerType().GetTypeInfo()); addr_t addr = LLDB_INVALID_ADDRESS; if (flags.Test(eTypeInstanceIsPointer)) { @@ -1032,15 +1030,13 @@ static bool PrintObjectViaPointer(Stream &strm, ValueObject &object, // Get the address of non-object values (structs, enums). auto addr_and_type = object.GetAddressOf(false); if (addr_and_type.type != eAddressTypeLoad) { - LLDB_LOG(log, "address-of value object failed, preventing use of " - "stringForPrintObject(_:mangledTypeName:)"); - return false; + return llvm::createStringError("address-of value object failed"); } addr = addr_and_type.address; } if (addr == 0 || addr == LLDB_INVALID_ADDRESS) - return false; + return llvm::createStringError("invalid address 0x%x", addr); StringRef mangled_type_name = object.GetMangledTypeName(); // Swift APIs that receive mangled names require the prefix removed. @@ -1055,37 +1051,29 @@ static bool PrintObjectViaPointer(Stream &strm, ValueObject &object, .str(); auto result_or_err = RunObjectDescription(object, expr_string, process, true); - if (!result_or_err) { - LLDB_LOG_ERROR(log, result_or_err.takeError(), - "stringForPrintObject(_:mangledTypeName:) failed: {0}"); - return false; - } + if (!result_or_err) + return result_or_err.takeError(); // A `(Bool, String)` tuple, where the bool indicates success/failure. auto result_sp = *result_or_err; auto success_sp = result_sp->GetChildAtIndex(0); auto description_sp = result_sp->GetChildAtIndex(1); - StreamString dump_stream; - auto err = DumpString(description_sp, dump_stream); + StreamString string_result; + auto err = DumpString(description_sp, string_result); if (err) { - LLDB_LOG_ERROR(log, std::move(err), - "decoding result of " - "stringForPrintObject(_:mangledTypeName:) failed: {0}"); - return false; + return llvm::joinErrors( + std::move(err), + llvm::createStringError("decoding of description String failed")); } Status status; - if (!success_sp->IsLogicalTrue(status)) { - LLDB_LOGF(log, - "stringForPrintObject(_:mangledTypeName:) produced error: %s", - dump_stream.GetData()); - return false; - } + if (!success_sp->IsLogicalTrue(status)) + // The Bool is false, which means the String is an error message. + return llvm::createStringError(string_result.GetData()); - LLDB_LOG(log, "stringForPrintObject(_:mangledTypeName:) succeeded"); - strm.PutCString(dump_stream.GetString()); - return true; + strm.PutCString(string_result.GetString()); + return llvm::Error::success(); } llvm::Error SwiftLanguageRuntime::GetObjectDescription(Stream &str, @@ -1093,9 +1081,16 @@ llvm::Error SwiftLanguageRuntime::GetObjectDescription(Stream &str, if (object.IsUninitializedReference()) return llvm::createStringError(""); - if (GetProcess().GetTarget().GetSwiftUseContextFreePrintObject()) - if (PrintObjectViaPointer(str, object, GetProcess())) + Log *log = GetLog(LLDBLog::DataFormatters | LLDBLog::Expressions); + if (GetProcess().GetTarget().GetSwiftUseContextFreePrintObject()) { + if (auto err = PrintObjectViaPointer(str, object, GetProcess())) { + LLDB_LOG_ERROR(log, std::move(err), + "stringForPrintObject(_:mangledTypeName) failed: {0}"); + } else { + LLDB_LOG(log, "stringForPrintObject(_:mangledTypeName:) succeeded"); return llvm::Error::success(); + } + } std::string expr_string; From d8f6faa455412efacde2bf20f6ec77896297ec35 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Thu, 11 Dec 2025 10:41:23 -0800 Subject: [PATCH 10/14] Take bool parameter in SetDisableAvailability --- lldb/include/lldb/Target/Target.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 8b56d4c7b7601..2c612c726c073 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -568,7 +568,9 @@ class EvaluateExpressionOptions { bool GetPreparePlaygroundStubFunctions() const { return m_prepare_playground_stub_functions; } - void SetDisableAvailability() { m_disable_availability = true; } + void SetDisableAvailability(bool disable = true) { + m_disable_availability = disable; + } bool GetDisableAvailability() const { return m_disable_availability; } From 5cb63c49556724f2320b1095054810466b3f1477 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Thu, 11 Dec 2025 10:41:51 -0800 Subject: [PATCH 11/14] Call FixDataAddress on object addresses --- .../Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index f4121cd79b792..ddac89b9d41d0 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -1026,6 +1026,7 @@ static llvm::Error PrintObjectViaPointer(Stream &strm, ValueObject &object, if (flags.Test(eTypeInstanceIsPointer)) { // Objects are pointers. addr = object.GetValueAsUnsigned(LLDB_INVALID_ADDRESS); + addr = process.FixDataAddress(addr); } else { // Get the address of non-object values (structs, enums). auto addr_and_type = object.GetAddressOf(false); From 9442b979a83995c2d5c088dd343771c4b1051691 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Thu, 11 Dec 2025 11:52:39 -0800 Subject: [PATCH 12/14] Rename new eval option to its abstraction not its implementation --- lldb/include/lldb/Target/Target.h | 14 +++++++++----- .../Swift/SwiftExpressionSourceCode.cpp | 2 +- .../LanguageRuntime/Swift/SwiftLanguageRuntime.cpp | 6 +++--- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/lldb/include/lldb/Target/Target.h b/lldb/include/lldb/Target/Target.h index 2c612c726c073..13daa7eb4e661 100644 --- a/lldb/include/lldb/Target/Target.h +++ b/lldb/include/lldb/Target/Target.h @@ -568,11 +568,13 @@ class EvaluateExpressionOptions { bool GetPreparePlaygroundStubFunctions() const { return m_prepare_playground_stub_functions; } - void SetDisableAvailability(bool disable = true) { - m_disable_availability = disable; + void SetUseContextFreeSwiftPrintObject(bool enable = true) { + m_use_context_free_swift_print_object = enable; } - bool GetDisableAvailability() const { return m_disable_availability; } + bool GetUseContextFreeSwiftPrintObject() const { + return m_use_context_free_swift_print_object; + } private: ExecutionPolicy m_execution_policy = default_execution_policy; @@ -615,8 +617,10 @@ class EvaluateExpressionOptions { mutable uint32_t m_pound_line_line = 0; bool m_prepare_playground_stub_functions = true; - /// Disable compiler availability checking. - bool m_disable_availability = false; + /// An evaluation mode that for swift. Has the following effects: + /// 1. Disables implicit module loading + /// 2. Disables compiler availability checking + bool m_use_context_free_swift_print_object = false; /// During expression evaluation, any SymbolContext in this list will be /// used for symbol/function lookup before any other context (except for diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp index 3bdbce6fa5399..fadf0b319f205 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp @@ -640,7 +640,7 @@ Status SwiftExpressionSourceCode::GetText( if (triple.isOSDarwin()) { if (auto process_sp = exe_ctx.GetProcessSP()) { os_vers << getAvailabilityName(triple) << " "; - if (options.GetDisableAvailability()) { + if (options.GetUseContextFreeSwiftPrintObject()) { // Disable availability by setting the OS version to 9999. This // placeholder OS version used for future OS versions when building // the Swift standard library locally. diff --git a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp index ddac89b9d41d0..cfec40d234093 100644 --- a/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp +++ b/lldb/source/Plugins/LanguageRuntime/Swift/SwiftLanguageRuntime.cpp @@ -914,7 +914,7 @@ std::string SwiftLanguageRuntime::GetObjectDescriptionExpr_Copy( static llvm::Expected RunObjectDescription(ValueObject &object, std::string &expr_string, - Process &process, bool disable_availability = false) { + Process &process, bool context_free = false) { Log *log(GetLog(LLDBLog::DataFormatters | LLDBLog::Expressions)); ValueObjectSP result_sp; EvaluateExpressionOptions eval_options; @@ -923,8 +923,8 @@ RunObjectDescription(ValueObject &object, std::string &expr_string, eval_options.SetSuppressPersistentResult(true); eval_options.SetIgnoreBreakpoints(true); eval_options.SetTimeout(process.GetUtilityExpressionTimeout()); - if (disable_availability) - eval_options.SetDisableAvailability(); + if (context_free) + eval_options.SetUseContextFreeSwiftPrintObject(); StackFrameSP frame_sp = object.GetFrameSP(); if (!frame_sp) From b9e07a3b06747fe9fcb2884bc572142f9c0aaba1 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Thu, 11 Dec 2025 11:53:20 -0800 Subject: [PATCH 13/14] Disable implicit module loading for context-free po --- .../Swift/SwiftExpressionParser.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp index cd42b0a3da8fd..1c2b8ca5c21d1 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionParser.cpp @@ -1317,13 +1317,14 @@ SwiftExpressionParser::ParseAndImport( if (lldb::StackFrameSP this_frame_sp = m_stack_frame_wp.lock()) process_sp = this_frame_sp->CalculateProcess(); m_swift_ast_ctx.LoadImplicitModules(m_sc.target_sp, process_sp, *m_exe_scope); - if (!m_swift_ast_ctx.GetImplicitImports(m_sc, process_sp, additional_imports, - implicit_import_error)) { - const char *msg = implicit_import_error.AsCString(); - if (!msg) - msg = "error status positive, but import still failed"; - return make_error(msg); - } + if (!m_options.GetUseContextFreeSwiftPrintObject()) + if (!m_swift_ast_ctx.GetImplicitImports( + m_sc, process_sp, additional_imports, implicit_import_error)) { + const char *msg = implicit_import_error.AsCString(); + if (!msg) + msg = "error status positive, but import still failed"; + return make_error(msg); + } swift::ImplicitImportInfo importInfo; importInfo.StdlibKind = swift::ImplicitStdlibKind::Stdlib; From 6f0d8fd23aabe79d73df23c7fb3c8cf451f7ee88 Mon Sep 17 00:00:00 2001 From: Dave Lee Date: Thu, 11 Dec 2025 11:54:49 -0800 Subject: [PATCH 14/14] Fix comment grammar mistake --- .../ExpressionParser/Swift/SwiftExpressionSourceCode.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp index fadf0b319f205..5ed2d89e9a25a 100644 --- a/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp +++ b/lldb/source/Plugins/ExpressionParser/Swift/SwiftExpressionSourceCode.cpp @@ -650,7 +650,7 @@ Status SwiftExpressionSourceCode::GetText( bool is_simulator = platform->GetPluginName().ends_with("-simulator"); if (is_simulator) { // The simulators look like the host OS to Process, but Platform - // can the version out of an environment variable. + // can get the version out of an environment variable. os_vers << platform->GetOSVersion(process_sp.get()).getAsString(); } else { llvm::VersionTuple version = process_sp->GetHostOSVersion();