jingham added a comment.

In D88483#2339845 <https://reviews.llvm.org/D88483#2339845>, @fallkrum wrote:

> In D88483#2339256 <https://reviews.llvm.org/D88483#2339256>, @jingham wrote:
>
>> In D88483#2338408 <https://reviews.llvm.org/D88483#2338408>, @fallkrum wrote:
>>
>>> Can you please give me a couple of words on what m_static_type and 
>>> m_dynamic_type is in TypeImpl class, in what cases can it be initialized 
>>> with both of those types?
>>
>> ValueObjectDynamic value uses a TypeImpl to store its type, and it stores 
>> both the static type (the one returned by the parsed expression or was in 
>> the DWARF variable records for some local value) and the dynamic type it 
>> figured out by looking at the value in memory in this TypeImpl.  See for 
>> instance ValueObjectDynamicValue::UpdateValue.  ValueObjectDynamicValue 
>> could also get its static type from its parent.  I'm not sure why it doesn't 
>> do that and stores it in its TypeImpl instead; presumably this was more 
>> convenient somewhere.
>
> Thanks for explanation. 
> Could please tell if I understood you correctly: from the start we load into 
> some module’s type system some type for example from DWARF, but during 
> runtime it may be altered and as a consequence ‘original’ static type becomes 
> dynamic in-memory type? It still seems to me I do not completely understand 
> relation between static and it’s dynamic part, if it is correctly to say so. 
> Would like to understand the origin of this.

This is confusing, in part because TypeImpl is mixing two concepts, Types and 
Values.

A Type can really only have one type, itself...  Types may have base-class and 
derived class Types, but it is itself a definite type.

But a Value though originally known by its declared type, but can also have a 
more specific type based on how it was created.

The most common example of this is w.r.t. base & derived classes.  For 
instance, if you stopped are in a method of a base class in some class 
hierarchy, the Value representing the "this" pointer has a static type which is 
that of the base class.  That's pretty obvious.  But if a derived class object 
is the one actually calling the base class method at the point where you are 
stopped in that method, then the full (which in lldb we call the "dynamic") 
type of the "this" Value is the derived class.  In C++, the dynamic type is 
determined by looking at the vtable pointer in the object, which always points 
at the most specific class of the object.  In ObjC we look at the "isa" 
pointer, which again is always the most specific class.  As these examples 
show, to have a dynamic type you have to have a Value whose vtable or isa 
pointer you can look up.

And dynamic values can change over time:

  BaseClass *a = new BaseClass();
  ...
  free(a);
  a = new DerivedClass();

In this case, the static type of `a` is always `BaseClass *`, and at first it's 
dynamic type is also `BaseClass *`.  But after we free & re-initialize it, the 
dynamic type becomes `DerivedClass *`

I'm assuming TypeImpl picked up a "dynamic" type field because that allowed us 
to represent the Type of a ValueObject with static and dynamic types using one 
entity.  Then, for instance, if we failed to find the dynamic value for some 
reason, this would automatically fall back to the static type.  But dynamic 
types are really a concept that pertains to values not to types.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D88483/new/

https://reviews.llvm.org/D88483

_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to