+2004-09-21 Zack Weinberg <zack@codesourcery.com>
+
+ * parser.c (cp_lexer_peek_token, cp_lexer_consume_token):
+ Don't handle CPP_PRAGMA tokens specially.
+ (cp_lexer_handle_pragma): Use cp_lexer_consume_token. Don't
+ purge the token; do clear token->value after processing. Add
+ assertion at beginning that token->value is nonzero.
+ (cp_parser_statement, cp_parser_declaration_seq_opt): Handle
+ CPP_PRAGMA as a full statement or declaration in its own right.
+
2004-09-21 Matt Austern <austern@apple.com>
PR c++/15049
* decl.c (grokvardecl): Accept declarations of global variables
using anonymous types.
-
+
2004-09-21 Roger Sayle <roger@eyesopen.com>
PR c++/7503
if (lexer->next_token->type == CPP_PURGED)
cp_lexer_skip_purged_tokens (lexer);
- if (lexer->next_token->type == CPP_PRAGMA)
- cp_lexer_handle_pragma (lexer);
-
token = lexer->next_token;
/* Provide debugging output. */
if (lexer->next_token->type == CPP_PURGED)
cp_lexer_skip_purged_tokens (lexer);
- if (lexer->next_token->type == CPP_PRAGMA)
- cp_lexer_handle_pragma (lexer);
-
token = lexer->next_token++;
/* Provide debugging output. */
}
}
-/* Handle a pragma token and skip over it. We need the loop because
- the next token might also be a pragma token. */
+/* Consume and handle a pragma token. */
static void
cp_lexer_handle_pragma (cp_lexer *lexer)
{
- gcc_assert (lexer->next_token->type == CPP_PRAGMA);
+ cpp_string s;
+ cp_token *token = cp_lexer_consume_token (lexer);
+ gcc_assert (token->type == CPP_PRAGMA);
+ gcc_assert (token->value);
- while (lexer->next_token->type == CPP_PRAGMA)
- {
- tree t = lexer->next_token->value;
- cpp_string s;
- s.len = TREE_STRING_LENGTH (t);
- s.text = (const unsigned char *) TREE_STRING_POINTER (t);
+ s.len = TREE_STRING_LENGTH (token->value);
+ s.text = (const unsigned char *) TREE_STRING_POINTER (token->value);
- cp_lexer_set_source_position_from_token (lexer, lexer->next_token);
- cpp_handle_deferred_pragma (parse_in, &s);
+ cp_lexer_set_source_position_from_token (lexer, token);
+ cpp_handle_deferred_pragma (parse_in, &s);
- /* Make sure we don't run this pragma twice. */
- cp_lexer_purge_token (lexer);
- cp_lexer_skip_purged_tokens (lexer);
- }
+ /* Clearing token->value here means that we will get an ICE if we
+ try to process this #pragma again (which should be impossible). */
+ token->value = NULL;
}
/* Begin saving tokens. All tokens consumed after this point will be
/* Anything that starts with a `{' must be a compound-statement. */
else if (token->type == CPP_OPEN_BRACE)
statement = cp_parser_compound_statement (parser, NULL, false);
+ /* CPP_PRAGMA is a #pragma inside a function body, which constitutes
+ a statement all its own. */
+ else if (token->type == CPP_PRAGMA)
+ {
+ cp_lexer_handle_pragma (parser->lexer);
+ return;
+ }
/* Everything else must be a declaration-statement or an
expression-statement. Try for the declaration-statement
continue;
}
+ if (token->type == CPP_PRAGMA)
+ {
+ /* A top-level declaration can consist solely of a #pragma.
+ A nested declaration cannot, so this is done here and not
+ in cp_parser_declaration. (A #pragma at block scope is
+ handled in cp_parser_statement.) */
+ cp_lexer_handle_pragma (parser->lexer);
+ continue;
+ }
+
/* The C lexer modifies PENDING_LANG_CHANGE when it wants the
parser to enter or exit implicit `extern "C"' blocks. */
while (pending_lang_change > 0)