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