langhooks: preprocessor hooks for c++ modules
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.
This commit is contained in:
parent
e3b55ce50e
commit
8a97aed0d2
|
@ -28,7 +28,7 @@ along with GCC; see the file COPYING3. If not see
|
||||||
#include "c-pragma.h"
|
#include "c-pragma.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "file-prefix-map.h" /* remap_macro_filename() */
|
#include "file-prefix-map.h" /* remap_macro_filename() */
|
||||||
|
#include "langhooks.h"
|
||||||
#include "attribs.h"
|
#include "attribs.h"
|
||||||
|
|
||||||
/* We may keep statistics about how long which files took to compile. */
|
/* 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. */
|
/* #undef callback for DWARF and DWARF2 debug info. */
|
||||||
static void
|
static void
|
||||||
cb_undef (cpp_reader * ARG_UNUSED (pfile), location_t loc,
|
cb_undef (cpp_reader *pfile, location_t loc, cpp_hashnode *node)
|
||||||
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);
|
const struct line_map *map = linemap_lookup (line_table, loc);
|
||||||
(*debug_hooks->undef) (SOURCE_LINE (linemap_check_ordinary (map), loc),
|
(*debug_hooks->undef) (SOURCE_LINE (linemap_check_ordinary (map), loc),
|
||||||
(const char *) NODE_NAME (node));
|
(const char *) NODE_NAME (node));
|
||||||
|
|
|
@ -1106,6 +1106,8 @@ c_common_post_options (const char **pfilename)
|
||||||
struct cpp_callbacks *cb = cpp_get_callbacks (parse_in);
|
struct cpp_callbacks *cb = cpp_get_callbacks (parse_in);
|
||||||
cb->file_change = cb_file_change;
|
cb->file_change = cb_file_change;
|
||||||
cb->dir_change = cb_dir_change;
|
cb->dir_change = cb_dir_change;
|
||||||
|
if (lang_hooks.preprocess_options)
|
||||||
|
lang_hooks.preprocess_options (parse_in);
|
||||||
cpp_post_options (parse_in);
|
cpp_post_options (parse_in);
|
||||||
init_global_opts_from_cpp (&global_options, cpp_get_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;
|
cpp_opts->warn_unused_macros = cpp_warn_unused_macros;
|
||||||
/* Restore the line map back to the main file. */
|
/* Restore the line map back to the main file. */
|
||||||
if (!cpp_opts->preprocessed)
|
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,
|
/* 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. */
|
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. */
|
/* File change callback. Has to handle -include files. */
|
||||||
static void
|
static void
|
||||||
cb_file_change (cpp_reader * ARG_UNUSED (pfile),
|
cb_file_change (cpp_reader *reader, const line_map_ordinary *new_map)
|
||||||
const line_map_ordinary *new_map)
|
|
||||||
{
|
{
|
||||||
if (flag_preprocess_only)
|
if (flag_preprocess_only)
|
||||||
pp_file_change (new_map);
|
pp_file_change (new_map);
|
||||||
else
|
else
|
||||||
fe_file_change (new_map);
|
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
|
if (new_map
|
||||||
&& (new_map->reason == LC_ENTER || new_map->reason == LC_RENAME))
|
&& (new_map->reason == LC_ENTER || new_map->reason == LC_RENAME))
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "coretypes.h"
|
#include "coretypes.h"
|
||||||
#include "c-common.h" /* For flags. */
|
#include "c-common.h" /* For flags. */
|
||||||
#include "../libcpp/internal.h"
|
#include "../libcpp/internal.h"
|
||||||
|
#include "langhooks.h"
|
||||||
#include "c-pragma.h" /* For parse_in. */
|
#include "c-pragma.h" /* For parse_in. */
|
||||||
#include "file-prefix-map.h" /* remap_macro_filename() */
|
#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
|
/* Writes out the preprocessed file, handling spacing and paste
|
||||||
avoidance issues. */
|
avoidance issues. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
scan_translation_unit (cpp_reader *pfile)
|
scan_translation_unit (cpp_reader *pfile)
|
||||||
{
|
{
|
||||||
token_streamer streamer (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;
|
print.source = NULL;
|
||||||
for (;;)
|
for (;;)
|
||||||
|
@ -314,18 +320,38 @@ scan_translation_unit (cpp_reader *pfile)
|
||||||
= cpp_get_token_with_location (pfile, &spelling_loc);
|
= cpp_get_token_with_location (pfile, &spelling_loc);
|
||||||
|
|
||||||
streamer.stream (pfile, token, 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)
|
if (token->type == CPP_EOF)
|
||||||
break;
|
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
|
static void
|
||||||
directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
|
directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
|
||||||
{
|
{
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start (args, data_);
|
va_start (args, data_);
|
||||||
|
|
||||||
token_streamer *streamer = reinterpret_cast <token_streamer *> (data_);
|
do_streamer *streamer = reinterpret_cast <do_streamer *> (data_);
|
||||||
switch (task)
|
switch (task)
|
||||||
{
|
{
|
||||||
default:
|
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 *);
|
const cpp_token *token = va_arg (args, const cpp_token *);
|
||||||
location_t spelling_loc = va_arg (args, location_t);
|
location_t spelling_loc = va_arg (args, location_t);
|
||||||
streamer->stream (pfile, token, spelling_loc);
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -362,8 +395,13 @@ directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
|
||||||
static void
|
static void
|
||||||
scan_translation_unit_directives_only (cpp_reader *pfile)
|
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);
|
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. */
|
/* 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 *to_file_quoted =
|
||||||
(unsigned char *) alloca (to_file_len * 4 + 1);
|
(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
|
/* cpp_quote_string does not nul-terminate, so we have to do it
|
||||||
ourselves. */
|
ourselves. */
|
||||||
unsigned char *p = cpp_quote_string (to_file_quoted,
|
unsigned char *p = cpp_quote_string (to_file_quoted,
|
||||||
(const unsigned char *) file_path,
|
(const unsigned char *) file_path,
|
||||||
to_file_len);
|
to_file_len);
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
|
|
||||||
|
print.src_line = LOCATION_LINE (src_loc);
|
||||||
|
print.src_file = file_path;
|
||||||
|
|
||||||
fprintf (stream, "# %u \"%s\"%s",
|
fprintf (stream, "# %u \"%s\"%s",
|
||||||
print.src_line, to_file_quoted, special_flags);
|
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
|
static void
|
||||||
cb_undef (cpp_reader *pfile ATTRIBUTE_UNUSED, location_t line,
|
cb_undef (cpp_reader *pfile, location_t line, cpp_hashnode *node)
|
||||||
cpp_hashnode *node)
|
|
||||||
{
|
{
|
||||||
|
if (lang_hooks.preprocess_undef)
|
||||||
|
lang_hooks.preprocess_undef (pfile, line, node);
|
||||||
maybe_print_line (line);
|
maybe_print_line (line);
|
||||||
fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
|
fprintf (print.outf, "#undef %s\n", NODE_NAME (node));
|
||||||
print.src_line++;
|
print.src_line++;
|
||||||
|
|
|
@ -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_STRUCT hook_void_gcc_optionsp
|
||||||
#define LANG_HOOKS_INIT_OPTIONS lhd_init_options
|
#define LANG_HOOKS_INIT_OPTIONS lhd_init_options
|
||||||
#define LANG_HOOKS_INITIALIZE_DIAGNOSTICS lhd_initialize_diagnostics
|
#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_REGISTER_DUMPS lhd_register_dumps
|
||||||
#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lhd_complain_wrong_lang_p
|
#define LANG_HOOKS_COMPLAIN_WRONG_LANG_P lhd_complain_wrong_lang_p
|
||||||
#define LANG_HOOKS_HANDLE_OPTION lhd_handle_option
|
#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_STRUCT, \
|
||||||
LANG_HOOKS_INIT_OPTIONS, \
|
LANG_HOOKS_INIT_OPTIONS, \
|
||||||
LANG_HOOKS_INITIALIZE_DIAGNOSTICS, \
|
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_REGISTER_DUMPS, \
|
||||||
LANG_HOOKS_COMPLAIN_WRONG_LANG_P, \
|
LANG_HOOKS_COMPLAIN_WRONG_LANG_P, \
|
||||||
LANG_HOOKS_HANDLE_OPTION, \
|
LANG_HOOKS_HANDLE_OPTION, \
|
||||||
|
|
|
@ -356,6 +356,24 @@ struct lang_hooks
|
||||||
global diagnostic context structure. */
|
global diagnostic context structure. */
|
||||||
void (*initialize_diagnostics) (diagnostic_context *);
|
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. */
|
/* Register language-specific dumps. */
|
||||||
void (*register_dumps) (gcc::dump_manager *);
|
void (*register_dumps) (gcc::dump_manager *);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue