[cfe-dev] [PATCH] C++ nested-name-specifier (Parser)
Argiris Kirtzidis
akyrtzi at gmail.com
Sat Aug 9 22:01:41 PDT 2008
Chris Lattner wrote:
>
>> Sema actions like isTypeName and ActOnIdentifier, check the
>> scope-spec to see whether it needs to lookup a name inside the
>> scope-spec decl, or do a normal lookup.
>
> This is interesting: doesn't this mean that everything else will have
> to check to make sure that this hasn't happened, in order to reject
> invalid code?
I didn't quite understand what you mean here, can you elaborate ?
>
>> Now, the questions is whether Sema should keep the scope-spec state,
>> or whether the Parser should keep the scope-spec state and pass it
>> along to the actions (isTypeName, etc.)
>> When I say passing the scope-spec to actions, I don't mean like the
>> CXXScopeSpec in my patch which contained only parsed tokens, I mean
>> passing the decl that represents the scope where names should be
>> looked up into.
>
> Ok.
>
>> If the Sema keeps the scope-spec state, it is cleaner, but how will
>> the scope-state be cleared in case of an error like "A:: ;" ?
>> Should the parser call an ActOnErrorAfterNestedName or something ?
>
> That is possible. I'm more concerned with the fact that Sema for ';'
> will have to check to make sure there is no current scope-spec that is
> active. This approach seems to make it so that *all* sema actions
> would have to check for an empty scope-spec :(
This is why I think that having Sema keep the scope-spec state is
awkward and a hassle. The parser knows when parsing errors occured, or
when it needed to backtrack, etc., so the parser can do a far better job
of keeping track of the scope-spec state (when to clear it, etc.).
Sema actions can receive the scope-spec as parameter, which brings me to
my next point, that a [scope specifier + identifier] is considered one
syntactic construct by the spec, like a qualified-id, or an
elaborated-type-specifier, thus it makes sense to pass it along to an
action that handles a construct that it may be a part of.
For example, we can consider that ActOnIdentifier receives a
qualified-id, and that ActOnTag receives a elaborated-type-specifier
("class A::B {};").
>
>>>> This also means that we can drop the rewinding part if the Parser
>>>> or Sema keep and look after a 'C++ scoping' state.
>>>> If the Parser keeps the state, it will build and pass
>>>> 'CXXScopeSpec' objects to action methods, (like in my patch).
>>>> If the Sema keeps the state, it will make error recovery awkward.
>>>
>>> I actually think that things are more awkward with having Sema work
>>> this out. Specifically, if you have: "A :: B :: C" you might have
>>> one reference or it might be "A::B ::C" which can occur in a few
>>> places in the grammar:
>>> http://www.cs.berkeley.edu/~smcpeak/elkhound/sources/elsa/doc/coloncolon.txt
>>>
>>>
>>> If the parser just passed all of A/B/C to Sema, I'm not sure how it
>>> would handle this. It seems really easy if you invoke actions for
>>> "A::" then "B" (which returns a type). When the parser got a type,
>>> it would naturally ratchet on and parse ::C as a qualified name.
>>
>> But "B" type could contain "C" as nested type, in which case you may
>> want "A::B::C".
>> Anyway, I don't think we need to worry about whether it should be
>> "A::B ::C" or "A ::B::C" or whatever.
>> GCC treats it as "A::B::C" always:
>>
>> struct S {};
>> namespace A { S f(); }
>> S ::A::f(); // error: 'S::A' has not been declared
>>
>> I think this is correct since the spec says nothing about "'::'
>> associativity".
>
> Sure, but this can apparently happen in the 'friend' case and some
> others, according to the Elsa doc. I confess to not being an expert
> on these matters though.
The Elsa doc also says:
> every C++ compiler I've experimented with regards "::" as binding
> very tightly, such that any occurrence of an identifier followed
> by "::" is always interpreted as an attempt to use the binary "::",
>
I think Clang can be one those pesky compilers too, at least for
compatibility's sake ;-)
-Argiris
More information about the cfe-dev
mailing list