+\f
+/* Special handling for the first token or line in the file. The first
+ thing in the file might be #pragma GCC pch_preprocess, which loads a
+ PCH file, which is a GC collection point. So we need to handle this
+ first pragma without benefit of an existing lexer structure.
+
+ Always returns one token to the caller in *FIRST_TOKEN. This is
+ either the true first token of the file, or the first token after
+ the initial pragma. */
+
+static void
+cp_parser_initial_pragma (cp_token *first_token)
+{
+ tree name = NULL;
+
+ cp_lexer_get_preprocessor_token (NULL, first_token);
+ if (first_token->pragma_kind != PRAGMA_GCC_PCH_PREPROCESS)
+ return;
+
+ cp_lexer_get_preprocessor_token (NULL, first_token);
+ if (first_token->type == CPP_STRING)
+ {
+ name = first_token->value;
+
+ cp_lexer_get_preprocessor_token (NULL, first_token);
+ if (first_token->type != CPP_PRAGMA_EOL)
+ error ("junk at end of %<#pragma GCC pch_preprocess%>");
+ }
+ else
+ error ("expected string literal");
+
+ /* Skip to the end of the pragma. */
+ while (first_token->type != CPP_PRAGMA_EOL && first_token->type != CPP_EOF)
+ cp_lexer_get_preprocessor_token (NULL, first_token);
+
+ /* Read one more token to return to our caller. */
+ cp_lexer_get_preprocessor_token (NULL, first_token);
+
+ /* Now actually load the PCH file. */
+ if (name)
+ c_common_pch_pragma (parse_in, TREE_STRING_POINTER (name));
+}
+
+/* Normal parsing of a pragma token. Here we can (and must) use the
+ regular lexer. */
+
+static bool
+cp_parser_pragma (cp_parser *parser, enum pragma_context context ATTRIBUTE_UNUSED)
+{
+ cp_token *pragma_tok;
+ unsigned int id;
+
+ pragma_tok = cp_lexer_consume_token (parser->lexer);
+ gcc_assert (pragma_tok->type == CPP_PRAGMA);
+ parser->lexer->in_pragma = true;
+
+ id = pragma_tok->pragma_kind;
+ switch (id)
+ {
+ case PRAGMA_GCC_PCH_PREPROCESS:
+ error ("%<#pragma GCC pch_preprocess%> must be first");
+ break;
+
+ default:
+ gcc_assert (id >= PRAGMA_FIRST_EXTERNAL);
+ c_invoke_pragma_handler (id);
+ break;
+ }
+
+ cp_parser_skip_to_pragma_eol (parser, pragma_tok);
+ return false;
+}
+
+/* The interface the pragma parsers have to the lexer. */
+
+enum cpp_ttype
+pragma_lex (tree *value)
+{
+ cp_token *tok;
+ enum cpp_ttype ret;
+
+ tok = cp_lexer_peek_token (the_parser->lexer);
+
+ ret = tok->type;
+ *value = tok->value;
+
+ if (ret == CPP_PRAGMA_EOL || ret == CPP_EOF)
+ ret = CPP_EOF;
+ else if (ret == CPP_STRING)
+ *value = cp_parser_string_literal (the_parser, false, false);
+ else
+ {
+ cp_lexer_consume_token (the_parser->lexer);
+ if (ret == CPP_KEYWORD)
+ ret = CPP_NAME;
+ }
+
+ return ret;
+}
+
+\f