[cfe-dev] using declaration questions

John Thompson john.thompson.jtsoftware at gmail.com
Wed Jun 17 18:55:55 PDT 2009


Hi Doug,

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.



> 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.
>

I was a litte fuzzy about the exact meaning of these, but here's my best
guess.  First the new renamed UsingDecl:


/// UsingDecl - Represents C++ using-directive. For example:
/// using someNameSpace::someIdentifier;
class UsingDecl : public NamedDecl {
    /// \brief The source range that covers the nested-name-specifier
    /// preceding the namespace name.
    SourceRange NestedNameRange;
    /// \brief The source location of the target declaration name.
    SourceLocation TargetNameLocation;
    /// \brief The source location of the "using" location itself.
    SourceLocation UsingLocation;
    /// \brief Target declaration.
    NamedDecl* TargetDecl;
    /// \brief Target declaration.
    NestedNameSpecifier* TargetNestedNameDecl;
    // Had 'typename' keyword.
    bool IsTypeName;
    UsingDecl(DeclContext *DC, SourceLocation L, SourceRange NNR,
            SourceLocation TargetNL, SourceLocation UL, NamedDecl* Target,
            NestedNameSpecifier* TargetNNS, bool IsTypeNameArg)
        : NamedDecl(Decl::Using, DC, L, Target->getDeclName()),
            NestedNameRange(NNR), TargetNameLocation(TargetNL),
            UsingLocation(UL), TargetDecl(Target),
            TargetNestedNameDecl(TargetNNS), IsTypeName(IsTypeNameArg) { }
public:\
    /// \brief Returns the source range that covers the
nested-name-specifier
    /// preceding the namespace name.
    SourceRange getNestedNameRange() { return(NestedNameRange); }
    /// \brief Returns the source location of the target declaration name.
    SourceLocation getTargetNameLocation() { return    (TargetNameLocation);
}
    /// \brief Returns the source location of the "using" location itself.
    SourceLocation getUsingLocation() { return(UsingLocation); }
    /// \brief getTargetDecl - Returns target specified by using-decl.
    NamedDecl *getTargetDecl() { return(TargetDecl); }
    /// \brief Get target nested name declaration.
    NestedNameSpecifier* getTargetNestedNameDecl() {
return(TargetNestedNameDecl);
}
    /// \brief isTypeName - Return true if using decl had 'typename'.
    bool isTypeName() const { return(IsTypeName); }

    static UsingDecl *Create(ASTContext &C, DeclContext *DC,
        SourceLocation L, SourceRange NNR, SourceLocation TargetNL,
        SourceLocation UL, NamedDecl* Target,
        NestedNameSpecifier* TargetNNS, bool IsTypeNameArg);

    static bool classof(const Decl *D) {
            return D->getKind() == Decl::Using;
        }
    static bool classof(const UsingDecl *D) { return true; }
};

Regarding the later comment:

> 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:
>
>        The entity declared by a using-declaration shall be known in the
> context using it according to its definition
> at the point of the using-declaration . Definitions added to the namespace
> after the using-declaration are not
> considered when a use of the name is made.
>
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?

The additional source locations are handled in ActOnUsingDeclaration like:

    UsingAlias = UsingDecl::Create(Context, CurContext, IdentLoc,
SS.getRange(),
        NS->getLocation(), UsingLoc, NS,
        static_cast<NestedNameSpecifier *>(SS.getScopeRep()),
        IsTypeName);

Does this seem right?

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?

I'll be experimenting with this next, as well as writing a bigger test, to
ring out some of the trickier cases.

-John


-- 
John Thompson
John.Thompson.JTSoftware at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20090617/16e98356/attachment.html>


More information about the cfe-dev mailing list