Skip to content

Conversation

@kastiglione
Copy link

@kastiglione kastiglione commented Dec 3, 2025

Adopt stringForPrintObject(_:mangledTypeName:), an overload added in swiftlang/swift#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.

rdar://158968103

Adopt `stringForPrintObject(_:mangledTypeName:)`, an overload added in
swiftlang/swift#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`.
@kastiglione kastiglione requested a review from a team as a code owner December 3, 2025 00:00
@kastiglione
Copy link
Author

@swift-ci test

@kastiglione kastiglione marked this pull request as draft December 3, 2025 00:00
@kastiglione
Copy link
Author

Draft mode: follow up will include experimental setting, and tests.

@kastiglione
Copy link
Author

@swift-ci test

@kastiglione
Copy link
Author

@swift-ci test macOS

@kastiglione
Copy link
Author

Existing tests all pass with new po.

@kastiglione kastiglione marked this pull request as ready for review December 3, 2025 23:38
@kastiglione
Copy link
Author

@swift-ci test

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">,

Choose a reason for hiding this comment

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

How about calling this swift-use-context-free-po or something else more specific than "new"?

Copy link
Author

@kastiglione kastiglione Dec 4, 2025

Choose a reason for hiding this comment

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

I can, though I intentionally didn't fret on the naming because the plan is to delete it, hopefully in weeks. I also don't expect to broadcast its existence.

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.

Choose a reason for hiding this comment

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

... when building the Swift standard library locally. ?

return false;
}

static bool printObjectViaPointer(Stream &strm, ValueObject &object,

Choose a reason for hiding this comment

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

Should this function return llvm::Error and return createStringError for the various failure modes for easier debugging?

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}");

Choose a reason for hiding this comment

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

then this could just be return result_or_err.takeError()

)
self.expect("po value", substrs=["2025"])
self._filecheck("INT")
# CHECK-INT: stringForPrintObject(UnsafeRawPointer(bitPattern: {{[0-9]+}}), mangledTypeName: "SiD")

Choose a reason for hiding this comment

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

Neat test, reusing filecheck this way!

llvm::Error SwiftLanguageRuntime::RunObjectDescriptionExpr(
ValueObject &object, std::string &expr_string, Stream &result) {
static llvm::Expected<ValueObjectSP>
runObjectDescription(ValueObject &object, std::string &expr_string,

Choose a reason for hiding this comment

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

Capitalize the function?

Choose a reason for hiding this comment

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

Yes.

return result_sp;
}

static llvm::Error dumpString(ValueObjectSP result_sp, Stream &strm);

Choose a reason for hiding this comment

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

Can you move the function up here instead of forward declaring it?


StringRef mangled_type_name = object.GetMangledTypeName();
// Swift's APIs that accept mangled names require the "$s" prefix removed.
mangled_type_name.consume_front("$s");

Choose a reason for hiding this comment

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

"$e" is also valid mangling for embedded Swift.

Also, when I see mangled names without the front "$s" omitted, I also see it with the last "D" omitted too (I think that's a "TypeMangling" node). I guess this isn't necessary here?

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.

Choose a reason for hiding this comment

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

"can the" -> "can get the"

llvm::VersionTuple version = process_sp->GetHostOSVersion();
os_vers << version.getAsString();
auto platform = target->GetPlatform();
bool is_simulator = platform->GetPluginName().ends_with("-simulator");

Choose a reason for hiding this comment

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

Do we really not have a nicer way to tell if a Platform is a simulator?


bool GetPreparePlaygroundStubFunctions() const { return m_prepare_playground_stub_functions; }

void SetDisableAvailability() { m_disable_availability = true; }

Choose a reason for hiding this comment

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

This is an odd set API. It only allows you to set it to true, which the name doesn't really imply?

We usually do:

SetWhatever(bool new_value)

return dumpString(*result_or_err, strm);
}

static llvm::Error dumpString(ValueObjectSP result_sp, Stream &strm) {

Choose a reason for hiding this comment

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

lldb doesn't do lower-case first letter functions for the most part. This should be DumpString.

addr_t addr = LLDB_INVALID_ADDRESS;
if (flags.Test(eTypeInstanceIsPointer)) {
// Objects are pointers.
addr = object.GetValueAsUnsigned(LLDB_INVALID_ADDRESS);

Choose a reason for hiding this comment

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

This should use GetValueAsAddress.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants