[cfe-dev] Better type-specifier representation

Ted Kremenek kremenek at apple.com
Fri Sep 12 09:09:23 PDT 2008

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.  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