Skip to content

Commit bff4b06

Browse files
committed
[lldb] Add synthetic formatter for Swift.UnsafeContinuation
1 parent f6b6053 commit bff4b06

File tree

7 files changed

+120
-1
lines changed

7 files changed

+120
-1
lines changed

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

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,72 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
955955
ValueObjectSP m_is_running_sp;
956956
};
957957

958+
class UnsafeContinuationSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
959+
public:
960+
UnsafeContinuationSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
961+
: SyntheticChildrenFrontEnd(*valobj_sp.get()) {
962+
if (auto target_sp = m_backend.GetTargetSP()) {
963+
if (auto ts_or_err =
964+
target_sp->GetScratchTypeSystemForLanguage(eLanguageTypeSwift)) {
965+
if (auto *ts = llvm::dyn_cast_or_null<TypeSystemSwiftTypeRef>(
966+
ts_or_err->get()))
967+
// TypeMangling for "Swift.UnsafeCurrentTask"
968+
m_task_type = ts->GetTypeFromMangledTypename(ConstString("$sSctD"));
969+
} else {
970+
LLDB_LOG_ERROR(GetLog(LLDBLog::DataFormatters | LLDBLog::Types),
971+
ts_or_err.takeError(),
972+
"could not get Swift type system for UnsafeContinuation "
973+
"synthetic provider: {0}");
974+
}
975+
}
976+
}
977+
978+
llvm::Expected<uint32_t> CalculateNumChildren() override {
979+
if (!m_task_sp)
980+
return m_backend.GetNumChildren();
981+
982+
return 1;
983+
}
984+
985+
bool MightHaveChildren() override { return true; }
986+
987+
lldb::ValueObjectSP GetChildAtIndex(uint32_t idx) override {
988+
if (!m_task_sp)
989+
return m_backend.GetChildAtIndex(idx);
990+
991+
if (idx == 0)
992+
return m_task_sp;
993+
994+
return {};
995+
}
996+
997+
size_t GetIndexOfChildWithName(ConstString name) override {
998+
if (!m_task_sp)
999+
return m_backend.GetIndexOfChildWithName(name);
1000+
1001+
if (name == "task")
1002+
return 0;
1003+
1004+
return UINT32_MAX;
1005+
}
1006+
1007+
lldb::ChildCacheState Update() override {
1008+
if (auto context_sp = m_backend.GetChildMemberWithName("context"))
1009+
if (addr_t task_addr = context_sp->GetValueAsUnsigned(0)) {
1010+
m_task_sp = ValueObject::CreateValueObjectFromAddress(
1011+
"task", task_addr, m_backend.GetExecutionContextRef(), m_task_type,
1012+
false);
1013+
if (auto synthetic_sp = m_task_sp->GetSyntheticValue())
1014+
m_task_sp = synthetic_sp;
1015+
}
1016+
return ChildCacheState::eRefetch;
1017+
}
1018+
1019+
private:
1020+
CompilerType m_task_type;
1021+
ValueObjectSP m_task_sp;
1022+
};
1023+
9581024
class TaskGroupSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
9591025
public:
9601026
TaskGroupSyntheticFrontEnd(lldb::ValueObjectSP valobj_sp)
@@ -1202,6 +1268,14 @@ lldb_private::formatters::swift::TaskSyntheticFrontEndCreator(
12021268
return new TaskSyntheticFrontEnd(valobj_sp);
12031269
}
12041270

1271+
SyntheticChildrenFrontEnd *
1272+
lldb_private::formatters::swift::UnsafeContinuationSyntheticFrontEndCreator(
1273+
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {
1274+
if (!valobj_sp)
1275+
return nullptr;
1276+
return new UnsafeContinuationSyntheticFrontEnd(valobj_sp);
1277+
}
1278+
12051279
SyntheticChildrenFrontEnd *
12061280
lldb_private::formatters::swift::TaskGroupSyntheticFrontEndCreator(
12071281
CXXSyntheticChildren *, lldb::ValueObjectSP valobj_sp) {

lldb/source/Plugins/Language/Swift/SwiftFormatters.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ SyntheticChildrenFrontEnd *EnumSyntheticFrontEndCreator(CXXSyntheticChildren *,
120120
SyntheticChildrenFrontEnd *TaskSyntheticFrontEndCreator(CXXSyntheticChildren *,
121121
lldb::ValueObjectSP);
122122

123+
SyntheticChildrenFrontEnd *
124+
UnsafeContinuationSyntheticFrontEndCreator(CXXSyntheticChildren *,
125+
lldb::ValueObjectSP);
126+
123127
SyntheticChildrenFrontEnd *
124128
TaskGroupSyntheticFrontEndCreator(CXXSyntheticChildren *, lldb::ValueObjectSP);
125129
}

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,12 @@ static void LoadSwiftFormatters(lldb::TypeCategoryImplSP swift_category_sp) {
416416
lldb_private::formatters::swift::TaskSyntheticFrontEndCreator,
417417
"Swift.UnsafeCurrentTask synthetic children",
418418
ConstString("Swift.UnsafeCurrentTask"), synth_flags);
419+
AddCXXSynthetic(swift_category_sp,
420+
lldb_private::formatters::swift::
421+
UnsafeContinuationSyntheticFrontEndCreator,
422+
"Swift.UnsafeContinuation synthetic children",
423+
ConstString("^Swift\\.UnsafeContinuation<.+,.+>"),
424+
synth_flags, true);
419425
AddCXXSynthetic(
420426
swift_category_sp,
421427
lldb_private::formatters::swift::TaskGroupSyntheticFrontEndCreator,

lldb/source/Plugins/TypeSystem/Swift/TypeSystemSwiftTypeRef.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3671,7 +3671,8 @@ lldb::Encoding TypeSystemSwiftTypeRef::GetEncoding(opaque_compiler_type_t type,
36713671
if (node->getText() == swift::BUILTIN_TYPE_NAME_RAWPOINTER ||
36723672
node->getText() == swift::BUILTIN_TYPE_NAME_NATIVEOBJECT ||
36733673
node->getText() == swift::BUILTIN_TYPE_NAME_UNSAFEVALUEBUFFER ||
3674-
node->getText() == swift::BUILTIN_TYPE_NAME_BRIDGEOBJECT)
3674+
node->getText() == swift::BUILTIN_TYPE_NAME_BRIDGEOBJECT ||
3675+
node->getText() == swift::BUILTIN_TYPE_NAME_RAWUNSAFECONTINUATION)
36753676
return lldb::eEncodingUint;
36763677
if (node->getText().starts_with(swift::BUILTIN_TYPE_NAME_VEC)) {
36773678
count = 0;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
SWIFT_SOURCES := main.swift
2+
SWIFTFLAGS_EXTRAS := -parse-as-library
3+
include Makefile.rules
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import lldb
2+
from lldbsuite.test.decorators import *
3+
from lldbsuite.test.lldbtest import *
4+
from lldbsuite.test import lldbutil
5+
6+
7+
class TestCase(TestBase):
8+
9+
@swiftTest
10+
def test_value_printing(self):
11+
"""Print an UnsafeContinuation and verify its children."""
12+
self.build()
13+
lldbutil.run_to_source_breakpoint(
14+
self, "break here", lldb.SBFileSpec("main.swift")
15+
)
16+
self.expect(
17+
"v cont",
18+
substrs=[
19+
"(UnsafeContinuation<Void, Never>) cont = {",
20+
"task = {",
21+
"isFuture = true",
22+
],
23+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
@main struct Main {
2+
static func main() async {
3+
await withUnsafeContinuation { (cont: UnsafeContinuation<Void, Never>) in
4+
print("break here")
5+
cont.resume()
6+
}
7+
}
8+
}

0 commit comments

Comments
 (0)