>>! In D3653#10, @rsmith wrote:
>> Fixing this case is a bit trickier because declspec is parsed with colon
>> protection turned off, otherwise we cannot recover typos like:
>>
>>   A:B c;
> 
> With your patch, it's parsed with colon protection turned on, right? Or do we 
> also need to add colon protection to tentative parsing of member-declarations?
With this patch declspec is parsed with colon protection turned off, this 
allows make recover of errors like:


  struct S2b {
    C1:C2 f(C1::C2);
  };
  


or



  struct S6b {
    C1:C2 m1 : B1::B2; 
  };



Colon protection is turned on when parsing declarator, - when parser expects 
nested-name-specifier of pointer  to a member and when parsing 
direct-declarator.

> 
> If you want to detect and recover from the above case, you need more 
> lookahead than you're currently using: you need to check if the colon is 
> followed by *two* identifiers. If it is, you can temporarily turn off colon 
> protection.

The patch uses a bit different way. If parser parses declspec and sees 

  A:B

it may be one of two things:


  - It is unnamed bit field. In this case `A` must be a type suitable for bit 
field and `B` must be a value.
  - It is typo for `A::B`. In this case `A::B` must be a type.
 
In both cases parser must read type first. As there is no case when both `A` 
and `A::B` are types suitable for declaring bit fields, these cases can be 
distinguished unambiguously, just by trying to build longest nested name 
specifier, which is still used to refer to a type. If `A::B` is a type or 
namespace, `A` cannot be used as a type of a bit field and recovery `A:B` -> 
`A::B` is valid. Without scoped enums it would be enough to check if `A::B` 
exists, that is why we need to pass `NeedType` when analyzing C++ scope.

================
Comment at: lib/Parse/Parser.cpp:1692-1694
@@ +1691,5 @@
+///
+/// Setting NeedType influences error recovery. If it is set, parser avoids
+/// replacements ':' -> '::' if it produces non-type entity. With it we can
+/// parse correctly code like this:
+/// \code
----------------
Richard Smith wrote:
> This doesn't seem correct. Even if `A::B::C` is a type, we still should not 
> do the recovery here, because this may still be an unnamed bitfield.
> 
> Also, I'm concerned about whether this `NeedType` thing is correct, since we 
> use `TryAnnotateCXXScopeSpec` from tentative parsing when we don't know 
> whether we expect a type or not.
Whether the recovery is attempted is determined by `ColonIsSacred` field. 
`NeedType` only assists the recovering when  `ColonIsSacred` is false. By 
default `NeedType` is false and behavior is identical to the current one. In 
the patch it is set only when parsing declspec, to correctly handle case when 
`A` is scoped enum  and `A::B` is valid.

http://reviews.llvm.org/D3653



_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to