[cfe-dev] Better type-specifier representation

Argiris Kirtzidis akyrtzi at gmail.com
Fri Sep 12 09:34:59 PDT 2008

Hi Ted,

Ted Kremenek wrote:
> I think what is clear from this discussion is that we need "something 
> else" to represent the information that is missing from the ASTs.  
> Whether or not we call it a type-specifier, a DeclGroup, or something 
> else, I think we are fundamentally trying to recover some syntactic 
> information that we are now losing.
> That said, I think changing the semantics of Type and its subclasses 
> in order to accomplish this will have a variety of unpleasant 
> complications.  Right now, because types are uniqued, we can easily 
> tell whether or not two variables are of the same type or of 
> compatible types.  This is really an elegant design from the 
> perspective of clients (as well as Sema).  By introducing different 
> Type objects for what is conceptually speaking the same type (in the 
> type system) that clean representation of the concept of types is 
> discarded.  This will seriously complicate clients of the ASTs that 
> want to reason about types

I don't think it will complicate the clients, the clients that reason 
about types use 'canonical' types:

typedef int A;
int x;
A y;

if a client wants to see if the types of x,y are compatible it uses 
canonical types.
If it wants to see if they are exactly the same type, it uses the type 

struct S{} x;
struct S y;

if a client wants to see if the types of x,y are compatible it uses 
canonical types, no complication involved.
If it wants to see if they are exactly the same type, what should the 
answer be ? I think this the essential difference in discussion, is 
"struct S" and "struct S{}" exactly the same type ?

The parser knows the difference between a type reference and a type 
definition, shouldn't the type system know too ? What problems can we 
expect for clients caused by saying "struct S" is not exactly the same 
as "struct S{}" ?

(The memory ownership of RecordDecls, is a non-issue; we can have all 
RecordDecls owned by the translation unit and types don't have to do 
anything with this.)


> .  Changing the meaning of types in this way thus seems like a pyrrhic 
> victory; while we will recover some syntactic information, we will 
> lose a great deal of semantic information (which will ultimately 
> complicate the implementation of many clients of the ASTs).
> On Sep 12, 2008, at 7:38 AM, Argiris Kirtzidis wrote:
>> Here's a proposal, collecting the arguments into one post:
>> Modifying Type to better represent 'type-specifier' in the syntax:
>> As Ted mentioned, there's a problem on how we represent struct
>> declarations inside type-specifiers:
>> Example:
>> void f() {
>>  typedef struct x { int y; } foo;  // #1
>> }
>> Syntactically this is what we have for #1:
>> typedef struct x { int y; } foo; -> 'typedef' type-specifier 'foo' ';'
>> and we treat it as: 'typedef' ['struct x' reference] 'foo' ';'
>> There's no information that 'struct x' is defined inside the typedef
>> declaration. Also it's not clear who owns the RecordDecl.
>> I suggest that we treat it as:
>> 'typedef' ['struct x' definition] 'foo' ';'
>> resulting in a RecordTypeDef Type for the TypedefDecl. This gives us the
>> information that we have a 'struct x' definition inside the
>> type-specifier of #1.
>> 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