On Tue, Nov 27, 2018 at 04:01:46PM -0500, Jason Merrill wrote:
> > > > if (cp_lexer_next_token_is (parser->lexer, CPP_NAME))
> > > > {
> > > > identifier = cp_parser_identifier (parser);
> > > > @@ -18904,7 +18916,12 @@ cp_parser_namespace_definition (cp_parser*
> > > > parser)
> > > > }
> > > > if (cp_lexer_next_token_is_not (parser->lexer, CPP_SCOPE))
> > > > - break;
> > > > + {
> > > > + /* Don't forget that the innermost namespace might have been
> > > > + marked as inline. */
> > > > + is_inline |= nested_inline_p;
> > >
> > > This looks wrong: an inline namespace does not make its nested namespaces
> > > inline as well.
>
> > A nested namespace definition cannot be inline. This is supposed to handle
> > cases such as
> > namespace A::B::inline C { ... }
> > because after 'C' we don't see :: so it breaks and we call push_namespace
> > outside the for loop.
>
> Ah, yes, I see. I was confused by the use of '|='; what is that for? Why
> not use '='? For that matter, why not modify is_inline in the loop instead
> of a new nested_inline_p variable?
|= is there to handle correctly this case:
inline namespace N { ... }
where we have to make sure that the call to push_namespace outside the for (;;)
is with is_inline=true. Using '=' would overwrite is_inline to false, because
there are no nested inlines. For the same reason I needed a second bool: to
not lose the information about the topmost inline. But since the second
push_namespace call also needs to handle the innermost namespace, it can't use
topmost_inline_p.
Marek