[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