[cfe-dev] Better type-specifier representation

Argiris Kirtzidis akyrtzi at gmail.com
Fri Sep 12 08:36:09 PDT 2008

Hi Steve,

steve naroff wrote:
> I don't understand why this problem is specific to typedef's.
> Don't we have the same problem for the following...
> void f() {
>   struct bar;
>   struct bar { int a; } barVar1;
>   struct bar barVar2;
> }
> How would this be represented?

You are absolutely right, it's not specific to typedef's (I just took 
Ted's first example), thanks for pointing it out.

I suggest handling your example like this:

struct bar;  -> TypeSpecDecl of type RecordRefType (a incomplete 
RecordDecl will be created)
struct bar { int a; } barVar1;  -> DeclGroup with one VarDecl of type 
RecordDefType (the previous RecordDecl will be defined)
struct bar barVar2;  -> DeclGroup with one VarDecl of type RecordRefType 
(the previous RecordDecl will be referenced)

The RecordDecl will be owned by one RecordType. The 
RecordRefType/RecordDefType resolve to this one RecordType.
Or just have a RecordDefType, not RecordRefType (the RecordType could be 
used for reference).


> snaroff
>> What about ownership of RecordDecl ?
>> There will be a 1-to-1 mapping between RecordTypes and RecordDecls,
>> struct x;  -> A new incomplete RecordDecl is created here.
>> struct x {};  -> The previously created RecordDecl is fully defined.
>> and RecordType will own it. What is the advantage of that ? Ownership
>> matters when a client wants to modify the AST. When the client says "I
>> want to replace this RecordDecl with another one" it usually means
>> "Everywhere in this translation unit, if a Type references this
>> RecordDecl, I want it to reference this RecordDecl instead.". The client
>> will accomplish this by replacing the one RecordDecl owned by the
>> RecordType with another one.
>> The alternative would be replacing all the RecordDecls (forward decls
>> and defs) present, *and* replacing the RecordDecl that the RecordType
>> references.
>> Also, by having only one RecordDecl we avoid the overhead of creating
>> multiple RecordDecls.
>> If  the two constructs above are not RecordDecls owned by the
>> translation unit, how are they represented in the AST ?
>> Syntactically they look like this:
>> struct x; -> type-specifier ';'
>> struct x {}; -> type-specifier ';'
>> similar to this, which we currently ignore:
>> int;  -> type-specifier ';'
>> I suggest representing them with a kind of 'TypeSpecDecl' declaration
>> node. This will allow us to also capture "int;" in the AST:
>> int; -> TypeSpecDecl with type 'int'
>> struct x {}; -> TypeSpecDecl with type RecordTypeDef  defining
>> RecordDecl 'x'
>> struct x; -> TypeSpecDecl with type RecordTypeRef, referencing
>> RecordDecl 'x'
>> Other occurences of type-specifier are represented in a consistent way:
>> int foo(int x, struct { int a; } y);
>> 'y' gets a new RecordTypeDef type, which owns the RecordDecl. We avoid
>> the overhead of using multiple DeclGroups for the parameters.
>> sizeof (struct { int x;}) -> 'sizeof' '(' type-specifier ')' -> A new
>> RecordTypeDef type passed to sizeof.
>> This approach of handling records will also apply to enums, basically
>> it's about handling the tag declarations appearing inside
>> type-specifiers. Consequently, this approach does not apply to typedefs:
>> typedef int x; -> syntactically (and semantically) 'typedef'
>> type-specifier 'x' ';' -> a TypedefDecl 'x'
>> Typedefs don't have the complications of tag types, they will be handled
>> the same way as now.
>> Any thoughts?
>> -Argiris
>> _______________________________________________
>> cfe-dev mailing list
>> cfe-dev at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev

More information about the cfe-dev mailing list