[cfe-dev] using declaration questions

AlisdairM(public) public at alisdairm.net
Thu Jun 18 07:02:07 PDT 2009


Not sure how forward-looking you want to be with this, but I have recently taken a look at using declarations myself with a view to the C++0x grammar.

 

Putting aside the concept related bits that Doug might explain better, the two main new constructs are alias declarations and inheriting constructors.

 

You can distinguish an alias declaration because it is *not* allowed a nested-name-specifier, and the identifier will be followed by an ‘=’.

 

   using my_type = typename some_template<T>::type;

 

Inheriting constructor declarations are only allowed inside class (or class template) definitions, and simply name a direct base-class twice:

 

    using base::base;

 

The effect here, though, is not to make a name available for name lookup but to declare a family of similar constructors directly in the derived class.

 

I suspect there is little to cater for in terms of supporting inheriting constructors in the future, but it might be useful to plan for the alias declaration.

 

AlisdairM

 

From: cfe-dev-bounces at cs.uiuc.edu [mailto:cfe-dev-bounces at cs.uiuc.edu] On Behalf Of John Thompson
Sent: 18 June 2009 02:56
To: cfe-dev at cs.uiuc.edu
Subject: [cfe-dev] using declaration questions

 

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/20090618/14256dda/attachment.html>


More information about the cfe-dev mailing list