[cfe-dev] using declaration questions
Douglas Gregor
dgregor at apple.com
Thu Jun 18 07:56:23 PDT 2009
On Jun 17, 2009, at 6:55 PM, John Thompson wrote:
> 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;
Typo: "preceding the *declaration* name."
> /// \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;
This is often called the "qualifier" of a qualified name (in the AST).
> // 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; }
> };
This looks right to me.
> 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?
>
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.
> 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?
>
Yes.
> 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.
>
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.
- Doug
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20090618/a78bd8bd/attachment.html>
More information about the cfe-dev
mailing list