<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Jun 17, 2009, at 6:55 PM, John Thompson wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div>Hi Doug,</div> <div> </div> <div>I've been working on using declarations a bit over the last week, amidst continued fire-fighting elsewhere, butI thought I'd better address some parts of it in pieces, rather than in a big unwieldy chunk.  Rather than a patch, I'll just list relevent pieces to discuss, as I have questions about the code.  I hope it formats in a readable way here.</div> <div><br clear="all"> </div> <blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid"> <div>We'll probably want to store more location information, e.g., the source range covering the nested-name-specifier, (e.g., "N::M::"), the source location of the target declaration's name, and the source location of the "using" itself. Also, how about keeping track of the NestedNameSpecifier used to refer to the target declaration? It's good for pretty-printing, and will also be needed when the using directive occurs within a template and the nested-name-specifier is dependent.</div> </blockquote> <div> </div> <div>I was a litte fuzzy about the exact meaning of these, but here's my best guess.  First the new renamed UsingDecl:</div> <div> </div> <div><font color="#008000" size="2"><font color="#008000" size="2"><p>/// UsingDecl - Represents C++ using-directive. For example:<br>/// using someNameSpace::someIdentifier;<br></p></font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">class</font></font><font size="2"> UsingDecl : </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">public</font></font><font size="2"> NamedDecl {<br> </font><font size="2"><font color="#008000" size="2">    /// \brief The source range that covers the nested-name-specifier<br></font></font><font size="2"><font color="#008000" size="2">    /// preceding the namespace name.<br> </font></font><font size="2"><font color="#008000">    </font>SourceRange NestedNameRange;<br></font></div></blockquote><div><br></div><div>Typo: "preceding the *declaration* name."</div><br><blockquote type="cite"><div><font size="2"><font color="#008000" size="2">    /// \brief The source location of the target declaration name.<br></font></font><font size="2"><font color="#008000">    </font>SourceLocation TargetNameLocation;<br> </font><font size="2"><font color="#008000" size="2">    /// \brief The source location of the "using" location itself.<br></font></font><font size="2"><font color="#008000">    </font>SourceLocation UsingLocation;<br> </font><font size="2"><font color="#008000" size="2">    /// \brief Target declaration.<br></font></font><font size="2"><font color="#008000">    </font>NamedDecl* TargetDecl;<br></font><font size="2"><font color="#008000" size="2">    /// \brief Target declaration.<br> </font></font><font size="2"><font color="#008000">    </font>NestedNameSpecifier* TargetNestedNameDecl;<br></font></div></blockquote><div><br></div><div>This is often called the "qualifier" of  a qualified name (in the AST). </div><br><blockquote type="cite"><div><font size="2"><font color="#008000" size="2">    // Had 'typename' keyword.<br></font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2"><font color="#008000">    </font>bool</font></font><font size="2"> IsTypeName;<br> <font color="#008000">    </font>UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR,<br><font color="#008000">            </font>SourceLocation TargetNL, SourceLocation UL, NamedDecl* Target,<br><font color="#008000">            </font>NestedNameSpecifier* TargetNNS, </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">bool</font></font><font size="2"> IsTypeNameArg)<br> <font color="#008000">        </font>: NamedDecl(Decl::Using, DC, L, Target->getDeclName()),<br><font color="#008000">            </font>NestedNameRange(NNR), TargetNameLocation(TargetNL),<br><font color="#008000">            </font>UsingLocation(UL), TargetDecl(Target),<br> <font color="#008000">            </font>TargetNestedNameDecl(TargetNNS), IsTypeName(IsTypeNameArg) { }<br></font><font color="#0000ff" size="2"><font color="#0000ff" size="2">public</font></font><font size="2">:\<br></font><font size="2"><font color="#008000" size="2">    /// \brief Returns the source range that covers the nested-name-specifier<br> </font></font><font size="2"><font color="#008000" size="2">    /// preceding the namespace name.<br></font></font><font size="2"><font color="#008000">    </font>SourceRange getNestedNameRange() { </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">return</font></font><font size="2">(NestedNameRange); }<br> </font><font size="2"><font color="#008000" size="2">    /// \brief Returns the source location of the target declaration name.<br></font></font><font size="2"><font color="#008000">    </font>SourceLocation getTargetNameLocation() { </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">return</font></font><font size="2"><font color="#008000">    </font>(TargetNameLocation); }<br> </font><font size="2"><font color="#008000" size="2">    /// \brief Returns the source location of the "using" location itself.<br></font></font><font size="2"><font color="#008000">    </font>SourceLocation getUsingLocation() { </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">return</font></font><font size="2">(UsingLocation); }<br> </font><font size="2"><font color="#008000" size="2">    /// \brief getTargetDecl - Returns target specified by using-decl.<br></font></font><font size="2"><font color="#008000">    </font>NamedDecl *getTargetDecl() { </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">return</font></font><font size="2">(TargetDecl); }<br> </font><font size="2"><font color="#008000" size="2">    /// \brief Get target nested name declaration.<br></font></font><font size="2"><font color="#008000">    </font>NestedNameSpecifier* getTargetNestedNameDecl() { </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">return</font></font><font size="2">(TargetNestedNameDecl); }<br> </font><font size="2"><font color="#008000" size="2">    /// \brief isTypeName - Return true if using decl had 'typename'.<br></font></font><font color="#0000ff" size="2"><font color="#0000ff" size="2"><font color="#008000">    </font>bool</font></font><font size="2"> isTypeName() </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">const</font></font><font size="2"> { </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">return</font></font><font size="2">(IsTypeName); }<br> <br></font><font color="#0000ff" size="2"><font color="#0000ff" size="2"><font color="#008000">    </font>static</font></font><font size="2"> UsingDecl *Create(ASTContext &C, DeclContext *DC,<br><font color="#008000">        </font>SourceLocation L, SourceRange NNR, SourceLocation TargetNL,<br> <font color="#008000">        </font>SourceLocation UL, NamedDecl* Target,<br><font color="#008000">        </font>NestedNameSpecifier* TargetNNS, </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">bool</font></font><font size="2"> IsTypeNameArg);<br> <br></font><font color="#0000ff" size="2"><font color="#0000ff" size="2"><font color="#008000">    </font>static</font></font><font size="2"> </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">bool</font></font><font size="2"> classof(</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">const</font></font><font size="2"> Decl *D) {<br> </font><font color="#0000ff" size="2"><font color="#0000ff" size="2"><font color="#008000">            </font>return</font></font><font size="2"> D->getKind() == Decl::Using;<br><font color="#008000">        </font>}</font><font color="#0000ff" size="2"><font color="#0000ff" size="2"><font color="#008000"><br>     </font>static</font></font><font size="2"> </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">bool</font></font><font size="2"> classof(</font><font color="#0000ff" size="2"><font color="#0000ff" size="2">const</font></font><font size="2"> UsingDecl *D) { </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">return</font></font><font size="2"> </font><font color="#0000ff" size="2"><font color="#0000ff" size="2">true</font></font><font size="2">; }<br> };<br></font></div></blockquote><div><br></div><div>This looks right to me.</div><blockquote type="cite"><div><p>Regarding the later comment:</p> <blockquote class="gmail_quote" style="PADDING-LEFT: 1ex; MARGIN: 0px 0px 0px 0.8ex; BORDER-LEFT: #ccc 1px solid"><p>Oh, and we might even consider storing the list of declarations that the using declaration refers to, because we need to model the semantics of paragraph 11:</p><p>       The entity declared by a using-declaration shall be known in the context using it according to its definition<br>at the point of the using-declaration . Definitions added to the namespace after the using-declaration are not<br> considered when a use of the name is made.</p></blockquote><p>I'm not sure what list of declarations is needed.  If later definitions appear, it seems that a look up will find the using declaration first, and return the refered-to declaration.  Or does this have something to do with overloading?</p></div></blockquote><div>Yes, it's for overloading. It will work as-is, because TargetDecl can be an OverloadedFunctionDecl, but in the longer term I'd like to eliminate OverloadedFunctionDecl.</div><br><blockquote type="cite"><div><p>The additional source locations are handled in ActOnUsingDeclaration like:</p><font size="2"><div><br class="webkit-block-placeholder"></div></font><font size="2">    UsingAlias = UsingDecl::Create(Context, CurContext, IdentLoc, SS.getRange(),<br>        NS->getLocation(), UsingLoc, NS,<br>        <font color="#0000ff">static_cast</font><font size="2"><NestedNameSpecifier *>(SS.getScopeRep())</font></font><font size="2">,<br>    </font><font size="2">     IsTypeName); <p>Does this seem right?</p></font></div></blockquote><div>Yes.</div><div><br></div><blockquote type="cite"><div><font size="2"><p>Lastly, do you think Sema::LookupParsedName is the right place to do the substitution for non-redeclaration lookups?  Or should it be lower in LookupName, with more conditions to exclude certain lookup types?</p><p>I'll be experimenting with this next, as well as writing a bigger test, to ring out some of the trickier cases.</p></font></div></blockquote>Okay. If you'd like to submit a patch with just parsing + AST, then tackle semantic analysis as a separate step, that'd be fine.</div><div><br></div><div><span class="Apple-tab-span" style="white-space:pre"><span class="Apple-style-span" style="font-size: small;">      </span><span class="Apple-style-span" style="font-size: small;">-</span><span class="Apple-style-span" style="font-size: small;"> </span><span class="Apple-style-span" style="font-size: small;">D</span><span class="Apple-style-span" style="font-size: small;">o</span><span class="Apple-style-span" style="font-size: small;">u</span><span class="Apple-style-span" style="font-size: small;">g</span></span></div></body></html>