[cfe-dev] Hello

Sebastian Redl sebastian.redl at getdesigned.at
Sun Oct 5 05:20:36 PDT 2008


Argiris Kirtzidis wrote:
> Here's an initial discussion about nested-names:
> http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002417.html
>
> To be more specific about "the conditions", I'm talking about having 
> some kind of "annotation tokens" like I propose here:
> http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002664.html
>
> These will be useful for both nested-names and ambiguity resolution 
> (discussed here: 
> http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002594.html)
>
> Please let me know if you have some thoughts on the subject.
I had always thought that it was possible to parse the non-template part 
of nested name specifiers without having to refer to sema at all. In my 
opinion, C++ would have been better if the specification of nested-id 
simply used 'identifier' instead of 'class-or-namespace-name'.
But then, a lot of C++ would be a lot easier (not only to parse) if the 
designers had avoided semantically loaded terms in the grammar and 
actually looked out for and prevented syntactic ambiguities.

Anyway, I have thought about the old discussions a lot this last week, 
and most of my comments turned out to be already answered. Below is what 
remains.

I had some thoughts of parsing the entire thing ahead of time and then 
having the sema resolve all issues at once, but there is one test case 
that really makes this impractical:

typedef int foo;
namespace abc { foo bar(); }
foo::abc::bar()
{
  // ...
}

Thus, there is one statement of yours in the discussion that is wrong:
> Anyway, I don't think we need to worry about whether it should be 
> "A::B   ::C" or  "A  ::B::C" or whatever.
>   
We do have to worry. GCC parses the above example correctly as foo 
::abc::bar. It doesn't stumble if foo is in its own namespace or even 
template class either. (In my opinion, that's really a defect in the 
standard. Nor do I think that there is any program out there that really 
relies on this.)
Consider also:
> I think this is correct since the spec says nothing about "'::' 
> associativity".
>   
:: is part of productions further down the tree than anything else, so 
it binds more strongly than anything else. However, it only binds to 
left-hand identifiers that actually name a namespace or class. 
Otherwise, it's the global scope.

It probably could still be done, but it would be very complex code - the 
sema would have to report that there are two identifiers, it would have 
to report the split position, and the parser would have to adjust its 
state according to this new revelation. It would shift a job to the sema 
that really is the parser's problem, and all that for probably no 
performance gain at all.
(Hm, or is that what your patch does? I haven't actually looked at any 
code.)

Here's a nice pathological case. GCC is so confused by it that it aborts 
processing. It doesn't even take any instantiations - the definition is 
enough. (Of course, to actually be a definition of the second template 
function, there would have to be a typename before the B::A.)

namespace A { template <typename B> B f(); }
template <typename B> typename B::A f();

template <typename B>
B::A::f()
{
  return 0;
}

struct s { typedef int A; }
void foo()
{
        f<int>();
        f<s>();
}

It's not surprising that this confuses GCC. This matter is actually 
unspecified in the 2003 standard, see DR215. DR215 is in fact very 
important to this whole matter, as is DR125, because the resolutions to 
these issues render the first example I've given invalid. The resolution 
to 125 has been voted into the C++0x paper in 2004, the one to 215 in 
2007. Under these rules, the class-or-namespace-name production 
disappears and is replaced by the more sensible type-or-namespace-name, 
with qualified name lookup amended to fail if the type name doesn't 
denote a class. (A type template parameter is a type-name.)

The question is whether we want to follow the broken rules of C++03, as 
GCC does, or the updated rules of C++0x, which introduces a tiny 
incompatibility to GCC.

I think that we should forbid using anything but Sema as the C++ Action. 
At least when we get to implementing templates, implementing isTypeName 
and similar functions is such a burden that it just doesn't make sense 
to use a different action, and there is no heuristic that can guess at 
types vs non-types with any reasonable accuracy - at least not without 
parsing ahead, and an Action can't do that.
The alternative is moving all type analysis, including that from Sema, 
to MinimalAction, and deriving Sema from MinimalAction. That would 
seriously slow down MinimalAction for C, though, I think.

Parser::isTokenStreamTypeName() - if I understand its purpose correctly, 
eventually this function will have to distinguish between types, 
templates, perhaps even concepts, and objects/functions. This is a lot 
for a function whose name suggests a boolean distinction.

Does whatever final resolution to the name lookup issue has been chosen 
handle reentrancy? Does the inner lookup work here?
ns1::templname<ns2::typename>::objname

I don't have any comments on the recently committed disambiguation code.

Sebastian



More information about the cfe-dev mailing list