[LLVMdev] Order of fiels and structure usage

Hendrik Boom hendrik at topoi.pooq.com
Sat Sep 13 11:09:28 PDT 2008


On Fri, 12 Sep 2008 11:06:30 -0700, Eli Friedman wrote:

> On Fri, Sep 12, 2008 at 9:35 AM, Hendrik Boom <hendrik at topoi.pooq.com>
> wrote:
>> I'd like to be able to make use of a structure type and its fields
>> before it is completely defined.  To be specific, let me ask detailed
>> questions at various stages in the construction of a recursive type.  I
>> copy from
>>
>> http://llvm.org/docs/ProgrammersManual.html#TypeResolve
>>
>>    // Create the initial outer struct
>>    PATypeHolder StructTy = OpaqueType::get();
>>
>> Is it possible to declare variables of type StructTy at this point?
> 
> I think you can, although you have to be careful; if you don't make sure
> the variable eventually has a computable size, the module won't be
> valid.

Of course, eventually they type will ba fully defined.

> 
> Declaring variables of type pointer to StructTy is completely safe.
> 
>>    std::vector<const Type*> Elts;
>>    Elts.push_back(PointerType::get(StructTy));
>>
>> Is it possible to build an expression that uses the newly generated Elt
>> as field-selector at this point?  I'm hoping yes, but I suspect No,
>> because the elments of Elts* are clearly Type* instead of being a
>> field. In particular, if I use the same type twice to make two fields,
>> the corresponding elements of Elts will be indistinguishable.
> 
> I'm not following; are you trying to access the first member of NewSTy
> here?  You can't use a type that hasn't been created yet.  You might be
> able to pull some tricks with incomplete types or casts, though.

What I want is to be able to use the fields that have already been 
defined, even though the type isn't complete yet.  The vector<const 
Type*> is all I have at that moment, and it isn't a type.  But by the 
time I have a type it's frozen and I can't add new fields to it.

Do I gather that I keep making new types, each slightly larger than the 
previous ones, cast each pointer to my growing type to the type-of-the-
moment, and field-select from it;  then finally complete the type when 
all is known?  That might just work, if field-allocation is independent 
of later fields, but it is ugly.

The trouble is that llvm won't believe in fields until the structure is 
complete, and then it believes in all of them.  While that's fine for 
semantics of the completed module, it makes less sense while the module 
is under construction.  I view type-declaration syntax as being syntax, 
and I'd like it to be as flexible and modifiable as syntax anywhere else 
in the parse tree.  The time to interpret type declarations as actually 
defining specific types with known semantics is after the syntax has been 
constructed, not before.  If it's possible to do some of it statically 
during parse tree construction, that's fine, but it shouldn't be 
*required*.  But it's evidently not the way llvm thinks.

> 
> http://llvm.org/docs/LangRef.html#i_getelementptr and
> http://llvm.org/docs/GetElementPtr.html might be useful here.

These operations also require a completed tyle.

> 
>>    Elts.push_back(Type::Int32Ty);
>>    StructType *NewSTy = StructType::get(Elts);
>>
>> Presumably at this point is is definitely possible to declare variables
>> of type NewsTy and use field-selectors from NewSTy.  But it's a little
>> too late for my purposes.
> 
> Basically, the rule for opaque types is that in a valid module, you can
> do anything you could do with a declaration like "struct S;" in C.

Which is, basically, nothing but point to it and statically know that 
it's the same or different from (possibly) other types.

>  And in a module under construction, I'm pretty sure you can pull some
> more tricks, like declaring variables with types of unknown size, or
> accessing structs with members of unknown size.

But not their fields, because llvm doesn't believe in fields of a 
structure until it has them all.  If the elements of Elts were fields of 
a yet-to-be-identified structure, I'd be able to use them; it would make 
sense then to use field explicitly in the getelementptr istruction 
instead of the integers which have to be indexed into a type to obtain 
them.

> 
> -Eli





More information about the llvm-dev mailing list