sammccall added a comment.

TL;DR: I suspect this is valid but guarding `nested-name-specifier := :: 
[guard=PrevNotIdentifier]` may be equivalent and clearer.

In D130511#3678938 <https://reviews.llvm.org/D130511#3678938>, @hokein wrote:

> In D130511#3677423 <https://reviews.llvm.org/D130511#3677423>, @sammccall 
> wrote:
>
>> My main concern here is that this might reject valid code (and if it 
>> doesn't, it's not obvious why).
>> It does look like C++ forbids the cases I can come up with (e.g. trying to 
>> provide a definition for `::Foo` is rejected by clang with "definition or 
>> redeclaration of Foo cannot name the global scope).
>> But I'd be way more comfortable if we could connect the specific guard rules 
>> here with spec language.
>
> The qualified declarator is tricky (it was forbidden until 
> https://cplusplus.github.io/CWG/issues/482.html).
>
> The closest thing I can find in the standard is basic.lookup.qual.general 
> <https://eel.is/c++draft/basic.lookup.qual.general>:
>
>> If a name, template-id, or decltype-specifier is followed by a ​::​, it 
>> shall designate a namespace, class, enumeration, or dependent type, and the 
>> ​::​ is never interpreted as a complete nested-name-specifier.

OK, so just spelling this out so I don't get lost...

A `name` is an identifier or operator name.
From the grammar `nested-name-specifier` can have components preceding `::`:

- nothing (global scope)
- type-name, namespace-name: these are identifiers = names
- decltype-specifier,
- (simple)-template-id

So the rule is saying that if the `::` can bind to the thing on its left, it 
must (*all* the non-null components are either names, template IDs, or 
decltype-specifiers).

I think this is probably what you've implemented here, though it's not totally 
obvious to me.

It seems most natural/more obviously-correct to express this as a guard on 
`namespace-specifier := ::`, as that's what the rule directly restricts. It's 
not simple to decide in general (in `c < d > :: a`, `c<d>` can be a template-id 
or not), but we can rule out the cases where the preceding token is an 
identifier (which is a limitation of your patch, right?).

Does `nested-name-specifier := :: [guard=PrevTokenNotIdentifier]` work for your 
testcases?
I think this is easier to tie to the [basic.language.qual.general] language you 
quoted.
(If you *don't* find this clearer, please do push back)


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D130511/new/

https://reviews.llvm.org/D130511

_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to