<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">A few weeks ago I had a conversation with Daniel about the fact that the ASTs (or other clang data structures) have no notion of the "entity" (for lack of a better word) that a declaration represents.<div><br></div><div>Here are a couple examples of what I mean:</div><div><br></div><div>(example 1)</div><div><br></div><div>  extern double x;</div><div>  extern double x;</div><div><br></div><div>Both of these are variable declarations that reference the same variable.  There is no notion of the variable itself other than the declarations, which is conflated, particularly since we have multiple declarations in this case (i.e., there is no unique "entity" for the variable).</div><div><br></div><div>(incidentally, clang crashes on this input: <a href="http://llvm.org/bugs/show_bug.cgi?id=2760)">http://llvm.org/bugs/show_bug.cgi?id=2760)</a></div><div><br></div><div><br></div><div>(example 2)</div><div><br></div><div>  struct s;</div><div>  struct s { int a; };</div><div>  struct s;</div><div><br></div><div>Until a few weeks ago, these struct declarations were represented by a single RecordDecl with a unique RecordType.  Now they are represented by three separate RecordDecls with a shared, unique RecordType.</div><div><br></div><div>With structures, the unique RecordType indeed can be treated as representing the "struct" itself, which seems fine since the given declarations are just type declarations.  So in this case, we *do* have a unique "entity" in the ASTs to represent what the declarations refer to.  There are still some issues with this representation, but I will delay mentioning them until after the next example.</div><div><br></div><div><br></div><div>(example 3)</div><div><br></div><div>int f();</div><div>int f();</div><div>int f() { return 0; }</div><div><br></div><div>int g();</div><div>int g() { return 1; }</div><div><br></div><div>For this example, we have separate FunctionDecls for each one of these declarations.  In this example, all of the declarations both 'f' and 'g' share the same type (note that this is different from the case with structs).  For the case of 'f', all of its FunctionDecls are chained together, and the same goes for 'g'.  There is, however, no notion of an entity or concept in the ASTs or other clang data structures that represent 'f' itself.</div><div><br></div><div>Here is an example of why not having an explicit concept for 'f', 'g', or any symbol is problematic.</div><div><br></div><div>Consider:</div><div><br></div><div>  extern int h(int* x) <span class="Apple-style-span" style="font-family: -webkit-monospace; font-size: 11px; white-space: pre; "><font class="Apple-style-span" face="Helvetica" size="4"><span class="Apple-style-span" style="font-size: 14px; white-space: normal;">__attribute__((nonnull));</span></font><span class="Apple-style-span" style="font-family: Helvetica; font-size: 14px; white-space: normal; "> </span></span></div><div>  extern int h(int *x);</div><div><div>  extern int h(int* x) <span class="Apple-style-span" style="font-family: -webkit-monospace; font-size: 11px; white-space: pre; "><font class="Apple-style-span" face="Helvetica" size="4"><span class="Apple-style-span" style="font-size: 14px; white-space: normal; ">__attribute__((noreturn));</span></font><span class="Apple-style-span" style="font-family: Helvetica; font-size: 14px; white-space: normal; "> </span></span></div><div><br></div><div>This code is completely valid.  In the ASTs we create three FunctionDecls, the first having the attribute "nonnull" attached to it (and object of type NonNullAttr) and the third having the attribute "noreturn" attached to it (an object of type NoReturnAttr).</div><div><br></div><div>Suppose I had a client (e.g., code generation, static analysis) that wanted to know all the attributes attached to a given function.  How would I go about doing this?  Given one of these FunctionDecls, I would have to iterate the chain of FunctionDecls and query each one of its attributes.  This seems a little cumbersome, and causes separate clients to have to implement their own logic for querying information about "symbols" in a translation unit.  It also causes clients to think about internal representations such as the fact that FunctionDecls are chained, something we may wish to change at any moment in the future.</div><div><br></div><div>This email isn't really a proposal of a solution; I'm just raising an issue to see if anyone has any comments.  After the last few weeks I've been excited by our discussions of DeclGroups and TypeSpecifiers that will solve many of the remaining issues with faithfully representing syntax in the ASTs.  At the same time, I think we need to pay a little more attention to the semantics, and providing infrastructure that would be useful for many clients.</div><div><br></div><div>Indeed, some of our changes to improve our capturing of syntax have actually weakened some of our clients reasoning about semantics.  For example, by splitting separate struct declarations into multiple RecordDecls we actually (initally) broke CodeGen because the CodeGen library assumed that there was a direct 1-1 mapping between a RecordDecl and the concept it represented.  That particular case was easily resolved by using the RecordType instead of the RecordDecl to represent the 'struct', but I'd be willing to wager that there are other issues that haven't surfaced yet because RecordTypes are being used in this way (by all clients).</div><div><br></div><div>Thoughts?</div></div></body></html>