[cfe-dev] Cleaning up the representation of Decls in the AST
Argiris Kirtzidis
akyrtzi at gmail.com
Thu Sep 11 05:53:58 PDT 2008
Ted Kremenek wrote:
> Note that this completely resolves the ownership issues with anonymous
> structs and similar constructs. It also means that Types no longer
> own Decls (a good thing).
>
There's an ownership issue that is not mentioned:
x = sizeof( struct { int z; } ); // who owns this RecordDecl ?
This may indicate that RecordDecls are fundamentally part of Type and
should be owned by a Type.
In a somewhat related note, consider this:
struct A {};
x = sizeof ( struct A ); #1
x = sizeof ( struct B {} ); #2
C++ Sema needs to know whether the Type passed to sizeof is a type
reference or a definition (the type definition would be illegal) and
currently it seems that there isn't a way to do that.
If we modify RecordType to own RecordDecls and be able to provide the
information of type reference or type definition, these examples would
be handled:
> [EXAMPLE 1]
>
> void f() {
> typedef struct x { int y; } foo;
> }
> struct x { int y; };
> void g() {
> typedef struct x foo;
> }
>
> clang -ast-print currently pretty-prints this as:
>
> void f() {
> typedef struct x foo;
> }
> ...
> void g() {
> typedef struct x foo;
> }
>
> Currently both f() and g() appear the same during printing because
> their is no reference from either the TypedefDecl or the DeclStmt to
> the RecordDecl for 'struct x'. Only the RecordType for 'struct x'
> refers to the RecordDecl, which means in this case the RecordType
> actually *owns* the RecordDecl. This is horrible, not only because a
> Type object should not own Decls, but that a RecordDecl can sometimes
> be owned by a DeclStmt or be a top-level declaration:
The semantics would be that RecordDecls are always owned by RecordTypes.
clang -ast-print would be able to print the above correctly because:
-Type of f()::foo would indicate a struct definition.
-Type of g()::foo would indicate a struct reference.
>
> [EXAMPLE 2]
>
> struct x { int y; }; // GOOD: The TranslationUnit owns the RecordDecl.
> struct z { int y; } z; // BAD: The RecordType owns the RecordDecl.
>
> The lack of clear ownership semantics, along with the loss of
> information that it implies, makes it very difficult to always
> faithfully pretty-print code that actually compiles, or compiles with
> the same semantics:
>
The ownership semantics would be that both RecordDecls are owned by
RecordTypes.
The first one can be a DeclGroup with no declarators.
> [EXAMPLE 3]
>
> void f() {
> struct { int x; } a, b, *c;
> }
>
> clang -ast-print:
>
> void f() {
> struct <anonymous> a;
> struct <anonymous> b;
> struct <anonymous> *c;
> }
>
> clang -ast-dump:
>
> void f()
> (CompoundStmt 0xc070f0 <<stdin>:3:12, line:5:3>
> (DeclStmt 0xc070d0 <line:4:5>
> 0xc06ff0 "struct <anonymous> a"
> 0xc07050 "struct <anonymous> b"
> 0xc070a0 "struct <anonymous> *c")
>
> As before, in this case the RecordType owns the RecordDecl. Not only
> that, but -ast-print pretty-prints the variable declaration in a
> completely broken way.
The above would be printed correctly since the RecordType would indicate
a struct definition.
Any thoughts ?
-Argiris
More information about the cfe-dev
mailing list