diff mbox series

langhooks: preprocessor hooks for c++ modules

Message ID 14a16659-82f2-39f9-7e8f-fdf29435fb1d@acm.org
State New
Headers show
Series langhooks: preprocessor hooks for c++ modules | expand

Commit Message

Nathan Sidwell Nov. 17, 2020, 2:10 p.m. UTC
This is	a slightly modified version of 01-langhooks.def.  I realized I
didn't need the	deferred macro langhook	-- that	can be directly
installed into the preprocessor callbacks via preprocess_options lang
hook.

	gcc/
	* langhooks-def.h (LANG_HOOKS_PREPROCESS_MAIN_FILE)
	(LANG_HOOKS_PREPROCESS_OPTIONS, LANG_HOOKS_PREPROCESS_UNDEF)
	(LANG_HOOKS_PREPROCESS_TOKEN): New.
	(LANG_HOOKS_INITIALIZER): Add them.
	* langhooks.h (struct lang_hooks): Add preprocess_main_file,
	preprocess_options, preprocess_undef, preprocess_token hooks.  Add
	enum PT_flags.
	gcc/c-family.
	* c-lex.c: #include "langhooks.h".
	(cb_undef): Maybe call preprocess_undef lang hook.
	* c-opts.c (c_common_post_options): Maybe call preprocess_options
	lang hook.
	(push_command_line_include): Maybe call preprocess_main_file lang
	hook.
	(cb_file_change): Likewise.
	* c-ppoutput.c: #include "langhooks.h.
	(scan_translation_unit): Maybe call preprocess_token lang hook.
	(class do_streamer): New, derive from token_streamer.
	(directives_only_cb): Data pointer is do_streamer, call
	preprocess_token lang hook.
	(scan_translation_unit_directives_only): Use do_streamer.
	(print_line_1): Move src_line recording to after string output.
	(cb_undef): Maybe call preprocess_undef lang hook.

pushing to trunk
diff mbox series

Patch

diff --git i/gcc/c-family/c-lex.c w/gcc/c-family/c-lex.c
index 6cd3df7c96f..8dd1420d10d 100644
--- i/gcc/c-family/c-lex.c
+++ w/gcc/c-family/c-lex.c
@@ -28,7 +28,7 @@  along with GCC; see the file COPYING3.  If not see
 #include "c-pragma.h"
 #include "debug.h"
 #include "file-prefix-map.h" /* remap_macro_filename()  */
-
+#include "langhooks.h"
 #include "attribs.h"
 
 /* We may keep statistics about how long which files took to compile.  */
@@ -274,9 +274,11 @@  cb_define (cpp_reader *pfile, location_t loc, cpp_hashnode *node)
 
 /* #undef callback for DWARF and DWARF2 debug info.  */
 static void
-cb_undef (cpp_reader * ARG_UNUSED (pfile), location_t loc,
-	  cpp_hashnode *node)
+cb_undef (cpp_reader *pfile, location_t loc, cpp_hashnode *node)
 {
+  if (lang_hooks.preprocess_undef)
+    lang_hooks.preprocess_undef (pfile, loc, node);
+
   const struct line_map *map = linemap_lookup (line_table, loc);
   (*debug_hooks->undef) (SOURCE_LINE (linemap_check_ordinary (map), loc),
 			 (const char *) NODE_NAME (node));
diff --git i/gcc/c-family/c-opts.c w/gcc/c-family/c-opts.c
index 40e92229d8a..77844d7daf1 100644
--- i/gcc/c-family/c-opts.c
+++ w/gcc/c-family/c-opts.c
@@ -1106,6 +1106,8 @@  c_common_post_options (const char **pfilename)
   struct cpp_callbacks *cb = cpp_get_callbacks (parse_in);
   cb->file_change = cb_file_change;
   cb->dir_change = cb_dir_change;
+  if (lang_hooks.preprocess_options)
+    lang_hooks.preprocess_options (parse_in);
   cpp_post_options (parse_in);
   init_global_opts_from_cpp (&global_options, cpp_get_options (parse_in));
 
@@ -1548,7 +1550,13 @@  push_command_line_include (void)
       cpp_opts->warn_unused_macros = cpp_warn_unused_macros;
       /* Restore the line map back to the main file.  */
       if (!cpp_opts->preprocessed)
-	cpp_change_file (parse_in, LC_RENAME, this_input_filename);
+	{
+	  cpp_change_file (parse_in, LC_RENAME, this_input_filename);
+	  if (lang_hooks.preprocess_main_file)
+	    /* We're starting the main file.  Inform the FE of that.  */
+	    lang_hooks.preprocess_main_file
+	      (parse_in, line_table, LINEMAPS_LAST_ORDINARY_MAP (line_table));
+	}
 
       /* Set this here so the client can change the option if it wishes,
 	 and after stacking the main file so we don't trace the main file.  */
@@ -1558,14 +1566,19 @@  push_command_line_include (void)
 
 /* File change callback.  Has to handle -include files.  */
 static void
-cb_file_change (cpp_reader * ARG_UNUSED (pfile),
-		const line_map_ordinary *new_map)
+cb_file_change (cpp_reader *reader, const line_map_ordinary *new_map)
 {
   if (flag_preprocess_only)
     pp_file_change (new_map);
   else
     fe_file_change (new_map);
 
+  if (new_map && cpp_opts->preprocessed
+      && lang_hooks.preprocess_main_file && MAIN_FILE_P (new_map)
+      && ORDINARY_MAP_STARTING_LINE_NUMBER (new_map))
+    /* We're starting the main file.  Inform the FE of that.  */
+    lang_hooks.preprocess_main_file (reader, line_table, new_map);
+
   if (new_map 
       && (new_map->reason == LC_ENTER || new_map->reason == LC_RENAME))
     {
diff --git i/gcc/c-family/c-ppoutput.c w/gcc/c-family/c-ppoutput.c
index 517de15d97c..e3e0e59fcc7 100644
--- i/gcc/c-family/c-ppoutput.c
+++ w/gcc/c-family/c-ppoutput.c
@@ -21,6 +21,7 @@ 
 #include "coretypes.h"
 #include "c-common.h"		/* For flags.  */
 #include "../libcpp/internal.h"
+#include "langhooks.h"
 #include "c-pragma.h"		/* For parse_in.  */
 #include "file-prefix-map.h"    /* remap_macro_filename()  */
 
@@ -301,10 +302,15 @@  token_streamer::stream (cpp_reader *pfile, const cpp_token *token,
 
 /* Writes out the preprocessed file, handling spacing and paste
    avoidance issues.  */
+
 static void
 scan_translation_unit (cpp_reader *pfile)
 {
   token_streamer streamer (pfile);
+  uintptr_t filter = 0;
+
+  if (lang_hooks.preprocess_token)
+    filter = lang_hooks.preprocess_token (pfile, NULL, filter);
 
   print.source = NULL;
   for (;;)
@@ -314,18 +320,38 @@  scan_translation_unit (cpp_reader *pfile)
 	= cpp_get_token_with_location (pfile, &spelling_loc);
 
       streamer.stream (pfile, token, spelling_loc);
+      if (filter)
+	{
+	  unsigned flags = lang_hooks.preprocess_token (pfile, token, filter);
+	  if (flags & lang_hooks::PT_begin_pragma)
+	    streamer.begin_pragma ();
+	}
       if (token->type == CPP_EOF)
 	break;
     }
+
+  if (filter)
+    lang_hooks.preprocess_token (pfile, NULL, filter);
 }
 
+class do_streamer : public token_streamer
+{
+ public:
+  uintptr_t filter;
+
+  do_streamer (cpp_reader *pfile, uintptr_t filter)
+    :token_streamer (pfile), filter (filter)
+    {
+    }
+};
+
 static void
 directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
 {
   va_list args;
   va_start (args, data_);
 
-  token_streamer *streamer = reinterpret_cast <token_streamer *> (data_);
+  do_streamer *streamer = reinterpret_cast <do_streamer *> (data_);
   switch (task)
     {
     default:
@@ -350,6 +376,13 @@  directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
 	const cpp_token *token = va_arg (args, const cpp_token *);
 	location_t spelling_loc = va_arg (args, location_t);
 	streamer->stream (pfile, token, spelling_loc);
+	if (streamer->filter)
+	  {
+	    unsigned flags = lang_hooks.preprocess_token
+	      (pfile, token, streamer->filter);
+	    if (flags & lang_hooks::PT_begin_pragma)
+	      streamer->begin_pragma ();
+	  }
       }
       break;
     }
@@ -362,8 +395,13 @@  directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
 static void
 scan_translation_unit_directives_only (cpp_reader *pfile)
 {
-  token_streamer streamer (pfile);
+  uintptr_t filter = 0;
+  if (lang_hooks.preprocess_token)
+    filter = lang_hooks.preprocess_token (pfile, NULL, filter);
+  do_streamer streamer (pfile, filter);
   cpp_directive_only_process (pfile, &streamer, directives_only_cb);
+  if (streamer.filter)
+    lang_hooks.preprocess_token (pfile, NULL, streamer.filter);
 }
 
 /* Adjust print.src_line for newlines embedded in output.  */
@@ -462,15 +500,16 @@  print_line_1 (location_t src_loc, const char *special_flags, FILE *stream)
       unsigned char *to_file_quoted =
          (unsigned char *) alloca (to_file_len * 4 + 1);
 
-      print.src_line = LOCATION_LINE (src_loc);
-      print.src_file = file_path;
-
       /* cpp_quote_string does not nul-terminate, so we have to do it
 	 ourselves.  */
       unsigned char *p = cpp_quote_string (to_file_quoted,
 					   (const unsigned char *) file_path,
 					   to_file_len);
       *p = '\0';
+
+      print.src_line = LOCATION_LINE (src_loc);
+      print.src_file = file_path;
+
       fprintf (stream, "# %u \"%s\"%s",
 	       print.src_line, to_file_quoted, special_flags);
 
@@ -576,9 +615,10 @@  cb_define (cpp_reader *pfile, location_t line, cpp_hashnode *node)
 }
 
 static void
-cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
-	  cpp_hashnode *node)
+cb_undef (cpp_reader *pfile, location_t line, cpp_hashnode *node)
 {
+  if (lang_hooks.preprocess_undef)
+    lang_hooks.preprocess_undef (pfile, line, node);
   maybe_print_line (line);
   fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
   print.src_line++;
diff --git i/gcc/langhooks-def.h w/gcc/langhooks-def.h
index a909915d018..2f66f5eb161 100644
--- i/gcc/langhooks-def.h
+++ w/gcc/langhooks-def.h
@@ -103,6 +103,10 @@  extern void lhd_finalize_early_debug (void);
 #define LANG_HOOKS_INIT_OPTIONS_STRUCT	hook_void_gcc_optionsp
 #define LANG_HOOKS_INIT_OPTIONS		lhd_init_options
 #define LANG_HOOKS_INITIALIZE_DIAGNOSTICS lhd_initialize_diagnostics
+#define LANG_HOOKS_PREPROCESS_MAIN_FILE NULL
+#define LANG_HOOKS_PREPROCESS_OPTIONS NULL
+#define LANG_HOOKS_PREPROCESS_UNDEF NULL
+#define LANG_HOOKS_PREPROCESS_TOKEN NULL
 #define LANG_HOOKS_REGISTER_DUMPS	lhd_register_dumps
 #define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lhd_complain_wrong_lang_p
 #define LANG_HOOKS_HANDLE_OPTION	lhd_handle_option
@@ -317,6 +321,10 @@  extern void lhd_end_section (void);
   LANG_HOOKS_INIT_OPTIONS_STRUCT, \
   LANG_HOOKS_INIT_OPTIONS, \
   LANG_HOOKS_INITIALIZE_DIAGNOSTICS, \
+  LANG_HOOKS_PREPROCESS_MAIN_FILE, \
+  LANG_HOOKS_PREPROCESS_OPTIONS, \
+  LANG_HOOKS_PREPROCESS_UNDEF, \
+  LANG_HOOKS_PREPROCESS_TOKEN, \
   LANG_HOOKS_REGISTER_DUMPS, \
   LANG_HOOKS_COMPLAIN_WRONG_LANG_P, \
   LANG_HOOKS_HANDLE_OPTION, \
diff --git i/gcc/langhooks.h w/gcc/langhooks.h
index a35cf21b673..f12589ee29d 100644
--- i/gcc/langhooks.h
+++ w/gcc/langhooks.h
@@ -356,6 +356,24 @@  struct lang_hooks
      global diagnostic context structure.  */
   void (*initialize_diagnostics) (diagnostic_context *);
 
+  /* Beginning the main source file.  */
+  void (*preprocess_main_file) (cpp_reader *, line_maps *,
+				const line_map_ordinary *);
+
+  /* Adjust libcpp options and callbacks.  */
+  void (*preprocess_options) (cpp_reader *);
+
+  /* Undefining a macro.  */
+  void (*preprocess_undef) (cpp_reader *, location_t, cpp_hashnode *);
+
+  /* Observer for preprocessing stream.  */
+  uintptr_t (*preprocess_token) (cpp_reader *, const cpp_token *, uintptr_t);
+  /* Various flags it can return about the token.  */
+  enum PT_flags
+    {
+     PT_begin_pragma = 1 << 0
+    };
+
   /* Register language-specific dumps.  */
   void (*register_dumps) (gcc::dump_manager *);