This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PCH] new-parser support
- From: Geoffrey Keating <gkeating at apple dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 9 Jan 2003 12:27:48 -0800 (PST)
- Subject: [PCH] new-parser support
For those interested, this is what I had to do to the new parser to
make PCH work for it. It's actually two intertwined changes, the
first part is the change to finish_file that ensures that we don't try
to save a 'struct cp_lexer'; we can't save those because of the use of
the skip option. The second part is the change to cp_lexer_new that
ensures that when a PCH file is loaded we aren't keeping any GC roots
on the stack.
Tested along with the rest of the merge.
--
- Geoffrey Keating <geoffk@apple.com>
===File ~/patches/pchbranch-newcpparser.patch===============
2003-01-09 Geoffrey Keating <geoffk@apple.com>
Merge to tag pch-merge-20030102:
* semantics.c (finish_translation_unit): Don't call finish_file.
* parser.c: Don't include ggc.h.
(cp_lexer_new_main): Rename from cp_lexer_new, only create main lexer,
read first token here. Don't allow PCH files after the first
token is read.
(cp_lexer_new_from_tokens): Duplicate functionality from cp_lexer_new.
(cp_lexer_get_preprocessor_token): Allow LEXER to be NULL.
(cp_parser_new): Call cp_lexer_new_main before allocating GCed memory.
(cp_parser_late_parsing_for_member): Don't duplicate call to
cp_lexer_set_source_position_from_token.
(cp_parser_late_parsing_default_args): Likewise.
(yyparse): Call finish_file after clearing the_parser.
--- parser.c.old Mon Jan 6 15:01:21 2003
+++ parser.c Tue Jan 7 18:27:37 2003
@@ -1,5 +1,5 @@
/* C++ Parser.
- Copyright (C) 2000, 2001, 2002 Free Software Foundation, Inc.
+ Copyright (C) 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
Written by Mark Mitchell <mark@codesourcery.com>.
This file is part of GCC.
@@ -32,7 +32,6 @@
#include "decl.h"
#include "flags.h"
#include "diagnostic.h"
-#include "ggc.h"
#include "toplev.h"
#include "output.h"
@@ -213,8 +212,8 @@ typedef struct cp_lexer GTY (())
/* Prototypes. */
-static cp_lexer *cp_lexer_new
- PARAMS ((bool));
+static cp_lexer *cp_lexer_new_main
+ PARAMS ((void));
static cp_lexer *cp_lexer_new_from_tokens
PARAMS ((struct cp_token_cache *));
static int cp_lexer_saving_tokens
@@ -292,29 +291,37 @@ static void cp_lexer_stop_debugging
/* The stream to which debugging output should be written. */
static FILE *cp_lexer_debug_stream;
-/* Create a new C++ lexer. If MAIN_LEXER_P is true the new lexer is
- the main lexer -- i.e, the lexer that gets tokens from the
- preprocessor. Otherwise, it is a lexer that uses a cache of stored
- tokens. */
+/* Create a new main C++ lexer, the lexer that gets tokens from the
+ preprocessor. */
static cp_lexer *
-cp_lexer_new (bool main_lexer_p)
+cp_lexer_new_main (void)
{
cp_lexer *lexer;
+ cp_token first_token;
+
+ /* It's possible that lexing the first token will load a PCH file,
+ which is a GC collection point. So we have to grab the first
+ token before allocating any memory. */
+ cp_lexer_get_preprocessor_token (NULL, &first_token);
+ cpp_get_callbacks (parse_in)->valid_pch = NULL;
/* Allocate the memory. */
lexer = (cp_lexer *) ggc_alloc_cleared (sizeof (cp_lexer));
/* Create the circular buffer. */
lexer->buffer = ((cp_token *)
- ggc_alloc (CP_TOKEN_BUFFER_SIZE * sizeof (cp_token)));
+ ggc_calloc (CP_TOKEN_BUFFER_SIZE, sizeof (cp_token)));
lexer->buffer_end = lexer->buffer + CP_TOKEN_BUFFER_SIZE;
- /* There are no tokens in the buffer. */
- lexer->last_token = lexer->buffer;
+ /* There is one token in the buffer. */
+ lexer->last_token = lexer->buffer + 1;
+ lexer->first_token = lexer->buffer;
+ lexer->next_token = lexer->buffer;
+ memcpy (lexer->buffer, &first_token, sizeof (cp_token));
/* This lexer obtains more tokens by calling c_lex. */
- lexer->main_lexer_p = main_lexer_p;
+ lexer->main_lexer_p = true;
/* Create the SAVED_TOKENS stack. */
VARRAY_INT_INIT (lexer->saved_tokens, CP_SAVED_TOKENS_SIZE, "saved_tokens");
@@ -339,15 +346,14 @@ cp_lexer_new_from_tokens (cp_token_cache
cp_token_block *block;
ptrdiff_t num_tokens;
- /* Create the lexer. */
- lexer = cp_lexer_new (/*main_lexer_p=*/false);
+ /* Allocate the memory. */
+ lexer = (cp_lexer *) ggc_alloc_cleared (sizeof (cp_lexer));
/* Create a new buffer, appropriately sized. */
num_tokens = 0;
for (block = tokens->first; block != NULL; block = block->next)
num_tokens += block->num_tokens;
- lexer->buffer = ((cp_token *)
- ggc_alloc (num_tokens * sizeof (cp_token)));
+ lexer->buffer = ((cp_token *) ggc_alloc (num_tokens * sizeof (cp_token)));
lexer->buffer_end = lexer->buffer + num_tokens;
/* Install the tokens. */
@@ -365,6 +371,18 @@ cp_lexer_new_from_tokens (cp_token_cache
/* The buffer is full. */
lexer->last_token = lexer->first_token;
+ /* This lexer doesn't obtain more tokens. */
+ lexer->main_lexer_p = false;
+
+ /* Create the SAVED_TOKENS stack. */
+ VARRAY_INT_INIT (lexer->saved_tokens, CP_SAVED_TOKENS_SIZE, "saved_tokens");
+
+ /* Create the STRINGS array. */
+ VARRAY_TREE_INIT (lexer->string_tokens, 32, "strings");
+
+ /* Assume we are not debugging. */
+ lexer->debugging_p = false;
+
return lexer;
}
@@ -583,7 +601,7 @@ cp_lexer_get_preprocessor_token (lexer,
bool done;
/* If this not the main lexer, return a terminating CPP_EOF token. */
- if (!lexer->main_lexer_p)
+ if (lexer != NULL && !lexer->main_lexer_p)
{
token->type = CPP_EOF;
token->line_number = 0;
@@ -2454,9 +2472,14 @@ static cp_parser *
cp_parser_new ()
{
cp_parser *parser;
+ cp_lexer *lexer;
+
+ /* cp_lexer_new_main is called before calling ggc_alloc because
+ cp_lexer_new_main might load a PCH file. */
+ lexer = cp_lexer_new_main ();
parser = (cp_parser *) ggc_alloc_cleared (sizeof (cp_parser));
- parser->lexer = cp_lexer_new (/*main_lexer_p=*/true);
+ parser->lexer = lexer;
parser->context = cp_parser_context_new (NULL);
/* For now, we always accept GNU extensions. */
@@ -14319,9 +14342,7 @@ cp_parser_late_parsing_for_member (parse
/* Set the current source position to be the location of the first
token in the saved inline body. */
- cp_lexer_set_source_position_from_token
- (parser->lexer,
- cp_lexer_peek_token (parser->lexer));
+ (void) cp_lexer_peek_token (parser->lexer);
/* Let the front end know that we going to be defining this
function. */
@@ -14376,8 +14397,7 @@ cp_parser_late_parsing_default_args (cp_
/* Set the current source position to be the location of the
first token in the default argument. */
- cp_lexer_set_source_position_from_token
- (parser->lexer, cp_lexer_peek_token (parser->lexer));
+ (void) cp_lexer_peek_token (parser->lexer);
/* Local variable names (and the `this' keyword) may not appear
in a default argument. */
@@ -14900,6 +14920,8 @@ yyparse ()
the_parser = cp_parser_new ();
error_occurred = cp_parser_translation_unit (the_parser);
the_parser = NULL;
+
+ finish_file ();
return error_occurred;
}
============================================================