[cfe-dev] using declaration questions
Douglas Gregor
dgregor at apple.com
Fri Jun 19 17:53:10 PDT 2009
On Jun 19, 2009, at 12:48 PM, John Thompson wrote:
>
> Generally, I suggest that you post patches to the list, because
> there are others who might also provide reviews. Some comments follow.
>
> Sorry Doug, I copied both you and the list, which is redundant, so
> I'll just use the list from now on.
Thanks. All of the Clang developers follow this list closely.
> Index: tools/clang/include/clang/Basic/Builtins.h
>
> ===================================================================
> --- tools/clang/include/clang/Basic/Builtins.h (revision 73735)
> +++ tools/clang/include/clang/Basic/Builtins.h (working copy)
> @@ -31,6 +31,7 @@
>
> enum ID {
> NotBuiltin = 0, // This is not a builtin function.
> #define BUILTIN(ID, TYPE, ATTRS) BI##ID,
> +#undef alloca
> #include "clang/Basic/Builtins.def"
> FirstTSBuiltin
> };
>
> I thought this build issue was fixed. Do you still need this?
>
> Actually, I didn't see my prior change in the update, but for some
> reason, with my original change, I still was getting the error, even
> after a full rebuild. Perhaps it was a weirdness with Visual
> Studio. But moving the undefine up into the header fixed it,
> again. Do you think I should redefine it (#define abort _abort) for
> Windows after the Buildtins.def include?
Ugh. What a pain. If we need this to build on Windows, that's fine,
but I'd like to to have the appropriate #ifdef's to keep this a
Windows-only hack.
> Index: tools/clang/lib/AST/DeclBase.cpp
> ===================================================================
> --- tools/clang/lib/AST/DeclBase.cpp (revision 73735)
> +++ tools/clang/lib/AST/DeclBase.cpp (working copy)
> @@ -164,6 +164,7 @@
>
> case ParmVar:
> case OriginalParmVar:
> case NonTypeTemplateParm:
> + case Using:
> case ObjCMethod:
> case ObjCContainer:
> case ObjCCategory:
>
> This puts all using declarations into the ordinary namespace.
> However, what happens if the using declaration refers to something
> not in the ordinary namespace, e.g.,
>
> namespace N {
> struct X;
> }
>
> using N::X;
> void X(int); // okay
>
> struct X *x; // okay
>
> I guess my expectation was that UsingDecl would bitwise-OR the
> identifier namespace values of all of the things that it points to.
>
> Sorry, I blindly put that in not understanding it while searching
> for places where decl types were used. I'm afraid I still don't
> understand it, so I'll have to study it some more as part of working
> on the semantics, unless you have an easy fix. I've left what I had
> in for now, to keep the test file working.
>
The easy fix, which is good enough for now, is to get the target
declaration's identifier namespace. Eventually, we'll have to cope
with a using declaration that names both a tag and a value; then it'll
be more fun :)
>
> + // Parse namespace-name.
> + if (SS.isInvalid() || Tok.isNot(tok::identifier)) {
> + Diag(Tok, diag::err_expected_namespace_or_type_name);
> + // If there was invalid namespace name, skip to end of decl,
> and eat ';'.
> + SkipUntil(tok::semi);
> + return DeclPtrTy();
> + }
>
> "expected namespace or type name" seems like the wrong diagnostic. I
> think we should separate the two cases:
> - If the scope specifier is invalid, we've already emitted an
> error so we can just return.
>
> - If the token following the scope specifier is not an
> identifier, we can say something like "expected an identifier in
> using directive". It would also be really great if we detected the
> case of a template-id (e.g., "using std::vector<int>;") specifically
> (C++ [namespace.udecl]p5), because it's such an easy error to make.
> This is a case where we can provide a very specific diagnostic.
> I've taken a stab at fixing this in the new patch.
Looks good.
> + // Lookup target name.
> + LookupResult R = LookupParsedName(S, &SS, TargetName,
> + LookupOrdinaryName, false);
> +
> + if (NamedDecl *NS = R) {
> + if (IsTypeName && !isa<TypeDecl>(NS)) {
> + Diag(IdentLoc, diag::err_using_typename_non_type);
> + return DeclPtrTy();
> + }
>
> Good, good. Once we've emitted the error, I don't think we have to
> return, because we can recover from this particular error easily.
> So just delete the return statement? I've added that to the new
> patch.
That's fine.
> Thanks, Doug. I've enclosed a new patch, usingdecl3.patch. I've
> also added your examples to the test file, the last part of which is
> for later work. I left in a couple of the old changes to SemaDecl
> to keep the test file working, but you can ignore them if you want.
> Otherwise I'll take them out when I have the substitution working.
Did you run the Clang test suite with this patch? I'm seeing several
new failures with your patch:
/Volumes/Data/dgregor/Projects/llvm/tools/clang/test/Parser/cxx-using-
directive.cpp
/Volumes/Data/dgregor/Projects/llvm/tools/clang/test/SemaCXX/member-
name-lookup.cpp
/Volumes/Data/dgregor/Projects/llvm/tools/clang/test/SemaCXX/
namespace-alias.cpp
/Volumes/Data/dgregor/Projects/llvm/tools/clang/test/SemaCXX/using-
directive.cpp
I fixed the first one (it was just a changed error message) and the
non-semantic issue in the last one. However, I ended up removing the
new code in SemaLookup, which was causing the other failures. At a
minimum, all existing tests will have to pass before we can put in the
name-lookup part of your patch.
> I hope my working on Clang is working out for you guys, and not
> taking more hand-holding than it is worth. I fear I might be in a
> bit over my head, but I'd definitely like to and help out, if I can.
There's always a ramp-up, especially for C++. We know that :)
Some nit-picks follow. I've committed everything except the SemaLookup
part; thanks! The commit is here:
http://lists.cs.uiuc.edu/pipermail/cfe-commits/Week-of-Mon-20090615/018333.html
+def err_expected_ident_in_using : Error<"expected an identifier in
using directive">;
+def err_unexpected_template_inst_in_using : Error<"use of template
instantiation in using directive not allowed">;
Please keep lines to <= 80 columns.
And, to be *really* pedantic, the template-id refers to a template
specialization, not a template instantiation. I've fixed the wording.
Index: tools/clang/include/clang/Parse/Action.h
===================================================================
--- tools/clang/include/clang/Parse/Action.h (revision 73735)
+++ tools/clang/include/clang/Parse/Action.h (working copy)
@@ -912,7 +912,7 @@
/// ActOnNamespaceAliasDef - This is called when a namespace alias
definition
/// is parsed.
virtual DeclPtrTy ActOnNamespaceAliasDef(Scope *CurScope,
- SourceLocation NamespaceLoc,
+ SourceLocation TargetLoc,
SourceLocation AliasLoc,
IdentifierInfo *Alias,
const CXXScopeSpec &SS,
Why the name change here?
+ // Check nested-name specifier.
+ if (SS.isInvalid()) {
+ return DeclPtrTy();
+ }
Missing a:
SkipUntil(tok::semi);
before the return.
In the test case:
// Should have some errors here. Waiting for implementation.
void X(int);
struct X *x;
Our convention is to put "FIXME:" in the comment for anything that
needs to be fixed later.
- Doug
More information about the cfe-dev
mailing list