[cfe-dev] Decls are not synonyms for the symbols they represent

steve naroff snaroff at apple.com
Wed Sep 17 13:09:29 PDT 2008

On Sep 17, 2008, at 3:52 PM, Ted Kremenek wrote:

> On Sep 17, 2008, at 12:19 PM, steve naroff wrote:
>>>> extern int x;
>>>> void foo() {
>>>> x++;
>>>> }
>>>> extern int x;
>>>> void bar() {
>>>> x++;
>>>> }
>>>> void baz() {
>>>> extern int x;
>>>> x++;
>>>> }
>>>> -----
>>>> If you do an AST dump of this, you will see that the DeclRefExprs  
>>>> for 'x' in foo(), bar(), and baz() respectively refer to separate  
>>>> VarDecls.  Right now a client of the ASTs has no way of knowing  
>>>> that these VarDecls refer to the same variable.  Certainly a  
>>>> higher-level API that resolves identifiers across translation  
>>>> units could do this, but it might have to do a lot of work to  
>>>> resolve situations like the one above.  By having a mechanism to  
>>>> resolve identifiers within a translation unit, this higher-level  
>>>> API would much easier to implement.
>>> An "IdResolver" used beyond Sema would be very useful, but it may  
>>> come with a memory cost.
>>> Could we get away with having all DeclRefExprs for 'x' refer to  
>>> the same VarDecl ?
>> I guess we could, however I'm still not sure it's the right thing  
>> to do (since it goes against our tenet of keeping the AST simple  
>> and reflective of the source). From the compiler's perspective, the  
>> 3 DeclRefExprs *should* bind to 3 different VarDecls.
>> For this example, I'd like to know why/when we care if all these  
>> VarDecls refer to the same variable? Since each VarDecl is  
>> "extern", it's the linkers job to bind the actual variable  
>> definition (which isn't in this particular translation unit).
> Another example would be a client that wanted to rename 'x'.  How  
> would it know all of the declarations for the same variable?  There  
> are lots of cases where clients, looking the AST for a translation  
> unit, want to know which declarations refer to the same thing.

Absolutely. Building a cross reference map of some kind is easy to do.  
For example, Sema has the following maps that track *all* declarations  
for a given method (within a particular translation unit):

   /// Instance/Factory Method Pools - allows efficient lookup when  
   /// messages to "id". We need to maintain a list, since selectors  
can have
   /// differing signatures across classes. In Cocoa, this happens to be
   /// extremely uncommon (only 1% of selectors are "overloaded").
   llvm::DenseMap<Selector, ObjCMethodList> InstanceMethodPool;
   llvm::DenseMap<Selector, ObjCMethodList> FactoryMethodPool;

If maps like this are of general interest, we might consider adding  
API to Sema to extract some of the knowledge prior to its death? As an  
alternative, we could also post-process the AST's and build whatever  
maps are needed. My gut says it will be a combination.

I think the point we are in violent agreement about is the need for  
"AST middleware" that sits between various clang AST clients and Sema.  
Some of this middleware may come directly from Sema (with a bit of  


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

More information about the cfe-dev mailing list