2424#include " lldb/ValueObject/ValueObject.h"
2525#include " lldb/ValueObject/ValueObjectConstResult.h"
2626
27+ #include " Plugins/Language/CPlusPlus/CxxStringTypes.h"
28+ #include " Plugins/Language/CPlusPlus/Generic.h"
2729#include " Plugins/LanguageRuntime/CPlusPlus/CPPLanguageRuntime.h"
2830#include " Plugins/TypeSystem/Clang/TypeSystemClang.h"
2931#include " lldb/lldb-enumerations.h"
@@ -156,39 +158,43 @@ bool lldb_private::formatters::LibcxxSmartPointerSummaryProvider(
156158 ValueObjectSP valobj_sp (valobj.GetNonSyntheticValue ());
157159 if (!valobj_sp)
158160 return false ;
159- ValueObjectSP ptr_sp (valobj_sp->GetChildMemberWithName (" __ptr_" ));
160- ValueObjectSP count_sp (
161- valobj_sp->GetChildAtNamePath ({" __cntrl_" , " __shared_owners_" }));
162- ValueObjectSP weakcount_sp (
163- valobj_sp->GetChildAtNamePath ({" __cntrl_" , " __shared_weak_owners_" }));
164161
165- if (!ptr_sp)
162+ ValueObjectSP ptr_sp (valobj_sp->GetChildMemberWithName (" __ptr_" ));
163+ ValueObjectSP ctrl_sp (valobj_sp->GetChildMemberWithName (" __cntrl_" ));
164+ if (!ctrl_sp || !ptr_sp)
166165 return false ;
167166
168- if (ptr_sp->GetValueAsUnsigned (0 ) == 0 ) {
169- stream.Printf (" nullptr" );
167+ DumpCxxSmartPtrPointerSummary (stream, *ptr_sp, options);
168+
169+ bool success;
170+ uint64_t ctrl_addr = ctrl_sp->GetValueAsUnsigned (0 , &success);
171+ // Empty control field. We're done.
172+ if (!success || ctrl_addr == 0 )
170173 return true ;
171- } else {
172- bool print_pointee = false ;
173- Status error;
174- ValueObjectSP pointee_sp = ptr_sp->Dereference (error);
175- if (pointee_sp && error.Success ()) {
176- if (pointee_sp->DumpPrintableRepresentation (
177- stream, ValueObject::eValueObjectRepresentationStyleSummary,
178- lldb::eFormatInvalid,
179- ValueObject::PrintableRepresentationSpecialCases::eDisable,
180- false ))
181- print_pointee = true ;
182- }
183- if (!print_pointee)
184- stream.Printf (" ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned (0 ));
174+
175+ if (auto count_sp = ctrl_sp->GetChildMemberWithName (" __shared_owners_" )) {
176+ bool success;
177+ uint64_t count = count_sp->GetValueAsUnsigned (0 , &success);
178+ if (!success)
179+ return false ;
180+
181+ // std::shared_ptr releases the underlying resource when the
182+ // __shared_owners_ count hits -1. So `__shared_owners_ == 0` indicates 1
183+ // owner. Hence add +1 here.
184+ stream.Printf (" strong=%" PRIu64, count + 1 );
185185 }
186186
187- if (count_sp)
188- stream.Printf (" strong=%" PRIu64, 1 + count_sp->GetValueAsUnsigned (0 ));
187+ if (auto weak_count_sp =
188+ ctrl_sp->GetChildMemberWithName (" __shared_weak_owners_" )) {
189+ bool success;
190+ uint64_t count = weak_count_sp->GetValueAsUnsigned (0 , &success);
191+ if (!success)
192+ return false ;
189193
190- if (weakcount_sp)
191- stream.Printf (" weak=%" PRIu64, 1 + weakcount_sp->GetValueAsUnsigned (0 ));
194+ // Unlike __shared_owners_, __shared_weak_owners_ indicates the exact
195+ // std::weak_ptr reference count.
196+ stream.Printf (" weak=%" PRIu64, count);
197+ }
192198
193199 return true ;
194200}
@@ -209,24 +215,7 @@ bool lldb_private::formatters::LibcxxUniquePointerSummaryProvider(
209215 if (!ptr_sp)
210216 return false ;
211217
212- if (ptr_sp->GetValueAsUnsigned (0 ) == 0 ) {
213- stream.Printf (" nullptr" );
214- return true ;
215- } else {
216- bool print_pointee = false ;
217- Status error;
218- ValueObjectSP pointee_sp = ptr_sp->Dereference (error);
219- if (pointee_sp && error.Success ()) {
220- if (pointee_sp->DumpPrintableRepresentation (
221- stream, ValueObject::eValueObjectRepresentationStyleSummary,
222- lldb::eFormatInvalid,
223- ValueObject::PrintableRepresentationSpecialCases::eDisable,
224- false ))
225- print_pointee = true ;
226- }
227- if (!print_pointee)
228- stream.Printf (" ptr = 0x%" PRIx64, ptr_sp->GetValueAsUnsigned (0 ));
229- }
218+ DumpCxxSmartPtrPointerSummary (stream, *ptr_sp, options);
230219
231220 return true ;
232221}
@@ -250,7 +239,8 @@ lldb_private::formatters::LibCxxVectorIteratorSyntheticFrontEndCreator(
250239
251240lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
252241 LibcxxSharedPtrSyntheticFrontEnd (lldb::ValueObjectSP valobj_sp)
253- : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr ) {
242+ : SyntheticChildrenFrontEnd(*valobj_sp), m_cntrl(nullptr ),
243+ m_ptr_obj(nullptr ) {
254244 if (valobj_sp)
255245 Update ();
256246}
@@ -263,28 +253,21 @@ llvm::Expected<uint32_t> lldb_private::formatters::
263253lldb::ValueObjectSP
264254lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex (
265255 uint32_t idx) {
266- if (!m_cntrl)
256+ if (!m_cntrl || !m_ptr_obj )
267257 return lldb::ValueObjectSP ();
268258
269259 ValueObjectSP valobj_sp = m_backend.GetSP ();
270260 if (!valobj_sp)
271261 return lldb::ValueObjectSP ();
272262
273263 if (idx == 0 )
274- return valobj_sp-> GetChildMemberWithName ( " __ptr_ " );
264+ return m_ptr_obj-> GetSP ( );
275265
276266 if (idx == 1 ) {
277- if (auto ptr_sp = valobj_sp->GetChildMemberWithName (" __ptr_" )) {
278- Status status;
279- auto value_type_sp =
280- valobj_sp->GetCompilerType ()
281- .GetTypeTemplateArgument (0 ).GetPointerType ();
282- ValueObjectSP cast_ptr_sp = ptr_sp->Cast (value_type_sp);
283- ValueObjectSP value_sp = cast_ptr_sp->Dereference (status);
284- if (status.Success ()) {
285- return value_sp;
286- }
287- }
267+ Status status;
268+ ValueObjectSP value_sp = m_ptr_obj->Dereference (status);
269+ if (status.Success ())
270+ return value_sp;
288271 }
289272
290273 return lldb::ValueObjectSP ();
@@ -293,6 +276,7 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::GetChildAtIndex(
293276lldb::ChildCacheState
294277lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update () {
295278 m_cntrl = nullptr ;
279+ m_ptr_obj = nullptr ;
296280
297281 ValueObjectSP valobj_sp = m_backend.GetSP ();
298282 if (!valobj_sp)
@@ -302,6 +286,16 @@ lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::Update() {
302286 if (!target_sp)
303287 return lldb::ChildCacheState::eRefetch;
304288
289+ auto ptr_obj_sp = valobj_sp->GetChildMemberWithName (" __ptr_" );
290+ if (!ptr_obj_sp)
291+ return lldb::ChildCacheState::eRefetch;
292+
293+ auto cast_ptr_sp = GetDesugaredSmartPointerValue (*ptr_obj_sp, *valobj_sp);
294+ if (!cast_ptr_sp)
295+ return lldb::ChildCacheState::eRefetch;
296+
297+ m_ptr_obj = cast_ptr_sp->Clone (ConstString (" pointer" )).get ();
298+
305299 lldb::ValueObjectSP cntrl_sp (valobj_sp->GetChildMemberWithName (" __cntrl_" ));
306300
307301 m_cntrl = cntrl_sp.get (); // need to store the raw pointer to avoid a circular
@@ -316,10 +310,12 @@ bool lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
316310
317311size_t lldb_private::formatters::LibcxxSharedPtrSyntheticFrontEnd::
318312 GetIndexOfChildWithName (ConstString name) {
319- if (name == " __ptr_ " )
313+ if (name == " pointer " )
320314 return 0 ;
321- if (name == " $$dereference$$" )
315+
316+ if (name == " object" || name == " $$dereference$$" )
322317 return 1 ;
318+
323319 return UINT32_MAX;
324320}
325321
@@ -423,7 +419,7 @@ size_t lldb_private::formatters::LibcxxUniquePtrSyntheticFrontEnd::
423419 return 0 ;
424420 if (name == " deleter" )
425421 return 1 ;
426- if (name == " $$dereference$$" )
422+ if (name == " obj " || name == " object " || name == " $$dereference$$" )
427423 return 2 ;
428424 return UINT32_MAX;
429425}
0 commit comments