[cfe-dev] Better type-specifier representation

steve naroff snaroff at apple.com
Fri Sep 12 10:46:37 PDT 2008

All good points...

Sometimes it's useful to consult the spec to help weigh various design  

That said, C99 says...

All declarations of structure, union, or enumerated types that have  
the same scope and
use the same tag declare the same type. The type is incomplete109)  
until the closing brace
of the list deļ¬ning the content, and complete thereafter.

Since both x and y have the same type, I don't see any compelling  
reason to alter the type system.

struct S{} x;
struct S y;

 From my perspective, we need to have a compelling reason to fold this  
into the type system.

If not, I think the DeclGroup solution will work fine (and appears  


On Sep 12, 2008, at 1:07 PM, Daniel Dunbar wrote:

> Hi Argiris,
> To start, let me just say that I think there are a few different
> things going on in this
> thread, and its a bit hard to discuss any of them (especially over
> email), so it would
> be good to break them up into separate problems where possible.
> A few comments:
> First, I am not clear exactly what problem you are solving here. Are
> you proposing
> this as an alternative to DeclGroups? And what are the problems you
> are addressing?
> Second, it would be nice to conceptually separate the solutions to  
> the multiple
> RecordDecl issue and the DeclGroup proposal. They overlap to some  
> extent, it
> is true, but I think they are separate issues and should be solved  
> as such.
> Third, in my mind encoding any part of the AST using Types is not a
> good design. Having
> them be related to one another is ok, but having things embedded in
> the Type should
> be an implementation detail, not something forced by the Parser or
> even Sema. I am
> especially wary of a design which has Types owning part of the AST.
> Fourth, the main idea of DeclGroup was simply to capture the
> "declarator-list" part of the
> C grammar. I think this is what Ted meant about begin more faithful to
> the grammer.
> Fifth, if the problem you are solving is the ambiguity in whether a
> structure use is a
> definition or a declaration, then I agree that this should be solved,
> but I do not think
> it should be solved by introducing new types. I argued with Ted that
> we should introduce
> additional Decls to capture the syntactic (and semantic) distinction  
> between:
>   a. Introducing a new structure definition (which may be incomplete)
> into scope.
>   b. Referring to a previously declared structure.
> However, in the end I decided that the introduction of this could be
> delayed until after
> the other changes to RecordDecl and the introduction of DeclGroup.
> Those are more
> important for solving ownership issues, which are in turn blocking
> serialization.
> More concretely, I believe there are some issues with your proposal:
> (1) What is the representation of
>  typedef struct x { ... } a, b, d, e ..., z;
> Representing this, and capturing ownership, was really the key part of
> DeclGroup.
> (2) Re:
>> 'y' gets a new RecordTypeDef type, which owns the RecordDecl. We  
>> avoid
>> the overhead of using multiple DeclGroups for the parameters.
> This is a bit misleading, for all the common important cases  
> DeclGroup can be
> encoded in a way that doesn't have any additional memory overhead  
> (and the
> performance overhead of access through a smart pointer should be  
> negligible).
> Actually by my calculations we were going to save memory using  
> DeclGroup.
> I'd like to make sure we are all on the same page about what  
> problems we
> are solving (and break them down as much as possible) before going  
> into to
> many specifics about the solution.
> - Daniel
> On Fri, Sep 12, 2008 at 7:38 AM, Argiris Kirtzidis  
> <akyrtzi at gmail.com> 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
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20080912/d5b98959/attachment.html>

More information about the cfe-dev mailing list