[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