<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Sep 17, 2008, at 3:52 PM, Ted Kremenek wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div><br>On Sep 17, 2008, at 12:19 PM, steve naroff wrote:<br><br><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">extern int x;<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">void foo() {<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">x++;<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">}<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">extern int x;<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">void bar() {<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">x++;<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">}<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">void baz() {<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"> extern int x;<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"> x++;<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">}<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">-----<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><blockquote type="cite">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.<br></blockquote></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">An "IdResolver" used beyond Sema would be very useful, but it may come with a memory cost.<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite">Could we get away with having all DeclRefExprs for 'x' refer to the same VarDecl ?<br></blockquote></blockquote><blockquote type="cite"><blockquote type="cite"><br></blockquote></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">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.<br></blockquote><blockquote type="cite"><br></blockquote><blockquote type="cite">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).<br></blockquote><br>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.<br></div></blockquote></div><br><div>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):</div><div><br></div><div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(0, 116, 0); "><span style="color: #000000">  </span>/// Instance/Factory Method Pools - allows efficient lookup when typechecking</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(0, 116, 0); "><span style="color: #000000">  </span>/// messages to "id". We need to maintain a list, since selectors can have</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(0, 116, 0); "><span style="color: #000000">  </span>/// differing signatures across classes. In Cocoa, this happens to be </div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(0, 116, 0); "><span style="color: #000000">  </span>/// extremely uncommon (only 1% of selectors are "overloaded").</div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(63, 110, 116); "><span style="color: #000000">  </span>llvm<span style="color: #000000">::</span><span style="color: #5c2699">DenseMap</span><span style="color: #000000"><</span>Selector<span style="color: #000000">, </span><span style="color: #26474b">ObjCMethodList</span><span style="color: #000000">> </span>InstanceMethodPool<span style="color: #000000">;</span></div><div style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; font: normal normal normal 10px/normal Monaco; color: rgb(63, 110, 116); "><span style="color: #000000">  </span>llvm<span style="color: #000000">::</span><span style="color: #5c2699">DenseMap</span><span style="color: #000000"><</span>Selector<span style="color: #000000">, </span><span style="color: #26474b">ObjCMethodList</span><span style="color: #000000">> </span>FactoryMethodPool<span style="color: #000000">;</span></div><div><font class="Apple-style-span" face="Monaco" size="2"><span class="Apple-style-span" style="font-size: 10px;"><br></span></font></div><div>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.</div><div><br></div><div>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 refactoring).</div><div><br></div><div>snaroff</div><div><br></div><div><br></div></div></body></html>