[incremental] Patch: FYI: remove 2 lexer globals
Tom Tromey
tromey@redhat.com
Tue Aug 21 18:26:00 GMT 2007
I'm checking this in on the incremental-compiler branch.
This moves a couple lexer-related globals into a structure. I'm
(slowly) trying to remove global variables from the parser and lexer.
A coming patch will add a bit of state to the lexer, and this patch
lets us avoid making a new global.
Tom
Index: gcc/ChangeLog
from Tom Tromey <tromey@redhat.com>
* c-opts.c (cb_file_change): Update.
* c-lex.c (pending_lang_change, c_header_level): Removed.
(init_c_lex): Create a c_lex_state object.
(fe_file_change): Added c_lex_state argument.
(c_lex_get_state): New function.
* c-common.h (struct c_lex_state): New struct.
(pending_lang_change): Removed.
(fe_file_change): Update.
(c_lex_get_state): Declare.
Index: gcc/cp/ChangeLog
from Tom Tromey <tromey@redhat.com>
* parser.c (cp_lexer_get_preprocessor_token): Update. Added
'lstate' argument.
(cp_lexer_new_main): Update.
(cp_parser_initial_pragma): Likewise.
Index: libcpp/ChangeLog
from Tom Tromey <tromey@redhat.com>
* include/cpplib.h (struct cpp_callbacks) <user_data>: New field.
Index: gcc/c-lex.c
===================================================================
--- gcc/c-lex.c (revision 127651)
+++ gcc/c-lex.c (working copy)
@@ -46,9 +46,6 @@
static int header_time, body_time;
static splay_tree file_info_tree;
-int pending_lang_change; /* If we need to switch languages - C++ only */
-int c_header_level; /* depth in C headers - C++ only */
-
static tree interpret_integer (const cpp_token *, unsigned int);
static tree interpret_float (const cpp_token *, unsigned int);
static enum integer_type_kind narrowest_unsigned_type
@@ -70,6 +67,7 @@
{
struct cpp_callbacks *cb;
struct c_fileinfo *toplevel;
+ struct c_lex_state *lstate;
/* The get_fileinfo data structure must be initialized before
cpp_read_main_file is called. */
@@ -83,6 +81,15 @@
cb = cpp_get_callbacks (parse_in);
+ /* FIXME: pending_lang_change used to be GTY(())d in c-common.h. Do
+ we need this for PCH? If so we need a way for the PCH machinery
+ to see this struct. Are we allocating this too early? Also,
+ this is a memory leak right now. */
+ lstate = XNEW (struct c_lex_state);
+ lstate->pending_lang_change = 0;
+ lstate->c_header_level = 0;
+ cb->user_data = lstate;
+
cb->line_change = cb_line_change;
cb->ident = cb_ident;
cb->def_pragma = cb_def_pragma;
@@ -99,6 +106,13 @@
}
}
+struct c_lex_state *
+c_lex_get_state (cpp_reader *reader)
+{
+ struct cpp_callbacks *cb = cpp_get_callbacks (reader);
+ return (struct c_lex_state *) cb->user_data;
+}
+
struct c_fileinfo *
get_fileinfo (const char *name)
{
@@ -201,7 +215,8 @@
}
void
-fe_file_change (const struct line_map *new_map)
+fe_file_change (struct c_lex_state * ARG_UNUSED (lstate),
+ const struct line_map *new_map)
{
if (new_map == NULL)
return;
@@ -225,12 +240,12 @@
#endif
(*debug_hooks->start_source_file) (included_at, new_map->to_file);
#ifndef NO_IMPLICIT_EXTERN_C
- if (c_header_level)
- ++c_header_level;
+ if (lstate->c_header_level)
+ ++lstate->c_header_level;
else if (new_map->sysp == 2)
{
- c_header_level = 1;
- ++pending_lang_change;
+ lstate->c_header_level = 1;
+ ++lstate->pending_lang_change;
}
#endif
}
@@ -238,7 +253,7 @@
else if (new_map->reason == LC_LEAVE)
{
#ifndef NO_IMPLICIT_EXTERN_C
- if (c_header_level && --c_header_level == 0)
+ if (lstate->c_header_level && --lstate->c_header_level == 0)
{
if (new_map->sysp == 2)
warning (0, "badly nested C headers from preprocessor");
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c (revision 127651)
+++ gcc/cp/parser.c (working copy)
@@ -176,7 +176,7 @@
static cp_token *cp_lexer_token_at
(cp_lexer *, cp_token_position);
static void cp_lexer_get_preprocessor_token
- (cp_lexer *, cp_token *);
+ (cp_lexer *, struct c_lex_state *, cp_token *);
static inline cp_token *cp_lexer_peek_token
(cp_lexer *);
static cp_token *cp_lexer_peek_nth_token
@@ -271,6 +271,7 @@
size_t alloc;
size_t space;
cp_token *buffer;
+ struct c_lex_state *lstate;
/* It's possible that parsing the first pragma will load a PCH file,
which is a GC collection point. So we have to do that before
@@ -289,6 +290,8 @@
lexer->saved_tokens = VEC_alloc (cp_token_position, heap,
CP_SAVED_TOKEN_STACK);
+ lstate = c_lex_get_state (parse_in);
+
/* Create the buffer. */
alloc = CP_LEXER_BUFFER_SIZE;
buffer = GGC_NEWVEC (cp_token, alloc);
@@ -309,7 +312,7 @@
buffer = GGC_RESIZEVEC (cp_token, buffer, alloc);
pos = buffer + space;
}
- cp_lexer_get_preprocessor_token (lexer, pos);
+ cp_lexer_get_preprocessor_token (lexer, lstate, pos);
}
lexer->buffer = buffer;
lexer->buffer_length = alloc - space;
@@ -404,11 +407,12 @@
processed strings. */
static void
-cp_lexer_get_preprocessor_token (cp_lexer *lexer, cp_token *token)
+cp_lexer_get_preprocessor_token (cp_lexer *lexer, struct c_lex_state *lstate,
+ cp_token *token)
{
static int is_extern_c = 0;
- /* Get a new token from the preprocessor. */
+ /* Get a new token from the preprocessor. */
token->type
= c_lex_with_flags (&token->u.value, &token->location, &token->flags,
lexer == NULL ? 0 : C_LEX_RAW_STRINGS);
@@ -420,8 +424,8 @@
/* On some systems, some header files are surrounded by an
implicit extern "C" block. Set a flag in the token if it
comes from such a header. */
- is_extern_c += pending_lang_change;
- pending_lang_change = 0;
+ is_extern_c += lstate->pending_lang_change;
+ lstate->pending_lang_change = 0;
token->implicit_extern_c = is_extern_c > 0;
/* Check to see if this token is a keyword. */
@@ -20306,17 +20310,18 @@
cp_parser_initial_pragma (cp_token *first_token)
{
tree name = NULL;
+ struct c_lex_state *lstate = c_lex_get_state (parse_in);
- cp_lexer_get_preprocessor_token (NULL, first_token);
+ cp_lexer_get_preprocessor_token (NULL, lstate, first_token);
if (first_token->pragma_kind != PRAGMA_GCC_PCH_PREPROCESS)
return;
- cp_lexer_get_preprocessor_token (NULL, first_token);
+ cp_lexer_get_preprocessor_token (NULL, lstate, first_token);
if (first_token->type == CPP_STRING)
{
name = first_token->u.value;
- cp_lexer_get_preprocessor_token (NULL, first_token);
+ cp_lexer_get_preprocessor_token (NULL, lstate, first_token);
if (first_token->type != CPP_PRAGMA_EOL)
error ("junk at end of %<#pragma GCC pch_preprocess%>");
}
@@ -20325,7 +20330,7 @@
/* 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);
+ cp_lexer_get_preprocessor_token (NULL, lstate, first_token);
/* Now actually load the PCH file. */
if (name)
@@ -20334,7 +20339,7 @@
/* Read one more token to return to our caller. We have to do this
after reading the PCH file in, since its pointers have to be
live. */
- cp_lexer_get_preprocessor_token (NULL, first_token);
+ cp_lexer_get_preprocessor_token (NULL, lstate, first_token);
}
/* Normal parsing of a pragma token. Here we can (and must) use the
Index: gcc/c-opts.c
===================================================================
--- gcc/c-opts.c (revision 127650)
+++ gcc/c-opts.c (working copy)
@@ -1573,13 +1573,15 @@
/* File change callback. Has to handle -include files. */
static void
-cb_file_change (cpp_reader * ARG_UNUSED (pfile),
- const struct line_map *new_map)
+cb_file_change (cpp_reader *pfile, const struct line_map *new_map)
{
if (flag_preprocess_only)
pp_file_change (new_map);
else
- fe_file_change (new_map);
+ {
+ struct cpp_callbacks *cb = cpp_get_callbacks (pfile);
+ fe_file_change ((struct c_lex_state *) cb->user_data, new_map);
+ }
if (new_map == 0 || (new_map->reason == LC_LEAVE && MAIN_FILE_P (new_map)))
push_command_line_include ();
Index: gcc/c-common.h
===================================================================
--- gcc/c-common.h (revision 127650)
+++ gcc/c-common.h (working copy)
@@ -838,10 +838,21 @@
extern void c_cpp_builtins (cpp_reader *);
-/* Positive if an implicit `extern "C"' scope has just been entered;
- negative if such a scope has just been exited. */
-extern GTY(()) int pending_lang_change;
+/* State used by functions in c-lex.c. This is passed to the lexer
+ via the user-data field in the cpp_reader's callback structure. */
+struct c_lex_state
+{
+ /* Positive if an implicit `extern "C"' scope has just been entered;
+ negative if such a scope has just been exited. */
+ int pending_lang_change;
+ /* Depth in C headers - C++ only. */
+ int c_header_level;
+};
+
+/* Return the lexer state associated with a cppreader. */
+struct c_lex_state *c_lex_get_state (cpp_reader *);
+
/* Information recorded about each file examined during compilation. */
struct c_fileinfo
@@ -913,7 +924,7 @@
extern void builtin_define_with_value (const char *, const char *, int);
extern void c_stddef_cpp_builtins (void);
-extern void fe_file_change (const struct line_map *);
+extern void fe_file_change (struct c_lex_state *, const struct line_map *);
extern void c_parse_error (const char *, enum cpp_ttype, tree);
/* Objective-C / Objective-C++ entry points. */
Index: libcpp/include/cpplib.h
===================================================================
--- libcpp/include/cpplib.h (revision 127650)
+++ libcpp/include/cpplib.h (working copy)
@@ -1,6 +1,6 @@
/* Definitions for CPP library.
Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
- 2004, 2005
+ 2004, 2005, 2007
Free Software Foundation, Inc.
Written by Per Bothner, 1994-95.
@@ -456,6 +456,10 @@
/* Call backs to cpplib client. */
struct cpp_callbacks
{
+ /* The caller can associate some data with the reader and store a
+ pointer to it here. */
+ void *user_data;
+
/* Called when a new line of preprocessed output is started. */
void (*line_change) (cpp_reader *, const cpp_token *, int);
More information about the Gcc-patches
mailing list