@@ -734,6 +734,13 @@ namespace lldb_private {
734734namespace formatters {
735735namespace swift {
736736
737+ namespace {
738+ // / The size of Swift Tasks. Fragments are tail allocated.
739+ static constexpr size_t AsyncTaskSize = sizeof (::swift::AsyncTask);
740+ // / The offset of ChildFragment, which is the first fragment of an AsyncTask.
741+ static constexpr offset_t ChildFragmentOffset = AsyncTaskSize;
742+ } // namespace
743+
737744class EnumSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
738745public:
739746 EnumSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp);
@@ -806,6 +813,7 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
806813 " address" ,
807814 " id" ,
808815 " enqueuePriority" ,
816+ " parent" ,
809817 " children" ,
810818
811819 // Children below this point are hidden.
@@ -873,6 +881,33 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
873881 RETURN_CHILD (m_enqueue_priority_sp, enqueuePriority, priority_type);
874882 }
875883 case 3 : {
884+ if (!m_parent_task_sp) {
885+ // TypeMangling for "Swift.UnsafeRawPointer"
886+ CompilerType raw_pointer_type =
887+ m_ts->GetTypeFromMangledTypename (ConstString (" $sSVD" ));
888+
889+ addr_t parent_addr = 0 ;
890+ if (m_task_info.isChildTask ) {
891+ if (auto process_sp = m_backend.GetProcessSP ()) {
892+ Status status;
893+ // Read ChildFragment::Parent, the first field of the ChildFragment.
894+ parent_addr = process_sp->ReadPointerFromMemory (
895+ m_task_ptr + ChildFragmentOffset, status);
896+ if (status.Fail () || parent_addr == LLDB_INVALID_ADDRESS)
897+ parent_addr = 0 ;
898+ }
899+ }
900+ addr_t value = parent_addr;
901+ DataExtractor data{reinterpret_cast <const void *>(&value),
902+ sizeof (value), endian::InlHostByteOrder (),
903+ sizeof (void *)};
904+ m_parent_task_sp = ValueObject::CreateValueObjectFromData (
905+ " parent" , data, m_backend.GetExecutionContextRef (),
906+ raw_pointer_type);
907+ }
908+ return m_parent_task_sp;
909+ }
910+ case 4 : {
876911 if (!m_child_tasks_sp) {
877912 using task_type = decltype (m_task_info.childTasks )::value_type;
878913 std::vector<task_type> tasks = m_task_info.childTasks ;
@@ -901,26 +936,26 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
901936 }
902937 return m_child_tasks_sp;
903938 }
904- case 4 :
905- RETURN_CHILD (m_is_child_task_sp, isChildTask, bool_type);
906939 case 5 :
907- RETURN_CHILD (m_is_future_sp, isFuture , bool_type);
940+ RETURN_CHILD (m_is_child_task_sp, isChildTask , bool_type);
908941 case 6 :
909- RETURN_CHILD (m_is_group_child_task_sp, isGroupChildTask , bool_type);
942+ RETURN_CHILD (m_is_future_sp, isFuture , bool_type);
910943 case 7 :
911- RETURN_CHILD (m_is_async_let_task_sp, isAsyncLetTask , bool_type);
944+ RETURN_CHILD (m_is_group_child_task_sp, isGroupChildTask , bool_type);
912945 case 8 :
913- RETURN_CHILD (m_is_cancelled_sp, isCancelled , bool_type);
946+ RETURN_CHILD (m_is_async_let_task_sp, isAsyncLetTask , bool_type);
914947 case 9 :
948+ RETURN_CHILD (m_is_cancelled_sp, isCancelled, bool_type);
949+ case 10 :
915950 RETURN_CHILD (m_is_status_record_locked_sp, isStatusRecordLocked,
916951 bool_type);
917- case 10 :
918- RETURN_CHILD (m_is_escalated_sp, isEscalated, bool_type);
919952 case 11 :
920- RETURN_CHILD (m_is_enqueued_sp, isEnqueued , bool_type);
953+ RETURN_CHILD (m_is_escalated_sp, isEscalated , bool_type);
921954 case 12 :
955+ RETURN_CHILD (m_is_enqueued_sp, isEnqueued, bool_type);
956+ case 13 :
922957 RETURN_CHILD (m_is_complete_sp, isComplete, bool_type);
923- case 13 : {
958+ case 14 : {
924959 if (m_task_info.hasIsRunning )
925960 RETURN_CHILD (m_is_running_sp, isRunning, bool_type);
926961 return {};
@@ -953,8 +988,8 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
953988 m_is_child_task_sp, m_is_future_sp, m_is_group_child_task_sp,
954989 m_is_async_let_task_sp, m_is_cancelled_sp,
955990 m_is_status_record_locked_sp, m_is_escalated_sp,
956- m_is_enqueued_sp, m_is_complete_sp, m_child_tasks_sp ,
957- m_is_running_sp})
991+ m_is_enqueued_sp, m_is_complete_sp, m_parent_task_sp ,
992+ m_child_tasks_sp, m_is_running_sp})
958993 child.reset ();
959994 }
960995 }
@@ -990,6 +1025,7 @@ class TaskSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
9901025 ValueObjectSP m_is_escalated_sp;
9911026 ValueObjectSP m_is_enqueued_sp;
9921027 ValueObjectSP m_is_complete_sp;
1028+ ValueObjectSP m_parent_task_sp;
9931029 ValueObjectSP m_child_tasks_sp;
9941030 ValueObjectSP m_is_running_sp;
9951031};
@@ -1280,8 +1316,6 @@ class TaskGroupSyntheticFrontEnd : public SyntheticChildrenFrontEnd {
12801316 bool operator ==(const Task &other) const { return addr == other.addr ; }
12811317 bool operator !=(const Task &other) const { return !(*this == other); }
12821318
1283- static constexpr offset_t AsyncTaskSize = sizeof (::swift::AsyncTask);
1284- static constexpr offset_t ChildFragmentOffset = AsyncTaskSize;
12851319 static constexpr offset_t NextChildOffset = ChildFragmentOffset + 0x8 ;
12861320
12871321 Task getNextChild (Status &status) {
0 commit comments