@@ -331,9 +331,64 @@ bool ValueObjectVariable::UpdateValue() {
331
331
m_resolved_value.SetContext (Value::eContextTypeInvalid, nullptr );
332
332
}
333
333
}
334
+
334
335
return m_error.Success ();
335
336
}
336
337
338
+ void ValueObjectVariable::DoUpdateChildrenAddressType (ValueObject &valobj) {
339
+ Value::ValueType value_type = valobj.GetValue ().GetValueType ();
340
+ ExecutionContext exe_ctx (GetExecutionContextRef ());
341
+ Process *process = exe_ctx.GetProcessPtr ();
342
+ const bool process_is_alive = process && process->IsAlive ();
343
+ const uint32_t type_info = valobj.GetCompilerType ().GetTypeInfo ();
344
+ const bool is_pointer_or_ref =
345
+ (type_info & (lldb::eTypeIsPointer | lldb::eTypeIsReference)) != 0 ;
346
+
347
+ switch (value_type) {
348
+ case Value::eValueTypeFileAddress:
349
+ // If this type is a pointer, then its children will be considered load
350
+ // addresses if the pointer or reference is dereferenced, but only if
351
+ // the process is alive.
352
+ //
353
+ // There could be global variables like in the following code:
354
+ // struct LinkedListNode { Foo* foo; LinkedListNode* next; };
355
+ // Foo g_foo1;
356
+ // Foo g_foo2;
357
+ // LinkedListNode g_second_node = { &g_foo2, NULL };
358
+ // LinkedListNode g_first_node = { &g_foo1, &g_second_node };
359
+ //
360
+ // When we aren't running, we should be able to look at these variables
361
+ // using the "target variable" command. Children of the "g_first_node"
362
+ // always will be of the same address type as the parent. But children
363
+ // of the "next" member of LinkedListNode will become load addresses if
364
+ // we have a live process, or remain a file address if it was a file
365
+ // address.
366
+ if (process_is_alive && is_pointer_or_ref)
367
+ valobj.SetAddressTypeOfChildren (eAddressTypeLoad);
368
+ else
369
+ valobj.SetAddressTypeOfChildren (eAddressTypeFile);
370
+ break ;
371
+ case Value::eValueTypeHostAddress:
372
+ // Same as above for load addresses, except children of pointer or refs
373
+ // are always load addresses. Host addresses are used to store freeze
374
+ // dried variables. If this type is a struct, the entire struct
375
+ // contents will be copied into the heap of the
376
+ // LLDB process, but we do not currently follow any pointers.
377
+ if (is_pointer_or_ref)
378
+ valobj.SetAddressTypeOfChildren (eAddressTypeLoad);
379
+ else
380
+ valobj.SetAddressTypeOfChildren (eAddressTypeHost);
381
+ break ;
382
+ case Value::eValueTypeLoadAddress:
383
+ case Value::eValueTypeScalar:
384
+ case Value::eValueTypeVector:
385
+ valobj.SetAddressTypeOfChildren (eAddressTypeLoad);
386
+ break ;
387
+ }
388
+ }
389
+
390
+
391
+
337
392
bool ValueObjectVariable::IsInScope () {
338
393
const ExecutionContextRef &exe_ctx_ref = GetExecutionContextRef ();
339
394
if (exe_ctx_ref.HasFrameRef ()) {
0 commit comments