From patchwork Tue Nov 17 14:10:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nathan Sidwell X-Patchwork-Id: 1401575 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=ZevYYUU9; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4Cb7BL6QRvz9sVw for ; Wed, 18 Nov 2020 01:10:17 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 847373851C3D; Tue, 17 Nov 2020 14:10:14 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-qt1-x829.google.com (mail-qt1-x829.google.com [IPv6:2607:f8b0:4864:20::829]) by sourceware.org (Postfix) with ESMTPS id 95C783858026 for ; Tue, 17 Nov 2020 14:10:10 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 95C783858026 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=acm.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=nathanmsidwell@gmail.com Received: by mail-qt1-x829.google.com with SMTP id p12so15610887qtp.7 for ; Tue, 17 Nov 2020 06:10:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:to:from:subject:message-id:date:user-agent:mime-version :content-language; bh=PL0oqGfUSsRK1ebw74BtIJnN14o5IsVeB12Dav+AjjY=; b=ZevYYUU9C13ho61JxZkV0WbttfamY/wkthD7cRsQqJt/vs7lTehcTlmiocFwirb+lO sDU72FgYVRkifpj/A1hHq5MwZLKY2ftyxGlkMbf9KSO9VV+BAKW5tARp/cmqJzEO/89K 2qD6AEXkdvORciUsbtCo5dqoFxVmV+cD2qt7N3DbwS3v4v+FHSejTzfDWu5vbLJtl8Wg BXKS8OJx1jlij4Lkpd+M+yggtKQg7W29SYYP9nOyMKz2bUb0sLcydQxEkTHjovuizmTt D1ThI8SC2sw9PAI/G6VkufDZraAdvLjwdcwAjtYd7Go+jmkRuNtWhYnynosoI8u+zV9E HVrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:to:from:subject:message-id:date :user-agent:mime-version:content-language; bh=PL0oqGfUSsRK1ebw74BtIJnN14o5IsVeB12Dav+AjjY=; b=SKcjv7JuMC5dhbYXl8hvrDCOtQaCyu3ZG2Q/vCsjteXBmDgUwvyUh9QdfmDslE+U6x JZPRMAvDbfkTJPNzFwcyJr9NrJgDJ1jK6prwYA46lkjfAcapYiN9dAszVUQ8T36C/3Se F9flX0rBOfGeuHRnY6lZWND5jgdXRtteH2ky29TYGOzdloToilf4/uluQr0iq8yOfIQB vmOEODkbe4gUtU+YE9n7NQxh+QmrZ5bl4ESm8tqkjs8nDcIA1Oiidb0Hxy2SAQx2mOCA 0xWNddAWc4YvK9BtiCLjdccs/kpswxHWh+bLMZMvGdfOxFyDmMTeyKH3AG5GXJOfuneK srXg== X-Gm-Message-State: AOAM533uaX59ItsMeYuE+XbJj+4s6z2mpoaqRIwPujQ9Ca4d1vXvjrL7 hkApcvBIyiFHtaNWtZ4Jfkg= X-Google-Smtp-Source: ABdhPJx7wGKeIvrQ3PkMTPQxkD/fHlzNfrQTGyZC73dFLHOj6W0IiW8qopr5jmaMNhKvR8Xc+YZnsg== X-Received: by 2002:a05:622a:103:: with SMTP id u3mr5820243qtw.129.1605622209657; Tue, 17 Nov 2020 06:10:09 -0800 (PST) Received: from ?IPv6:2620:10d:c0a8:1102:81bf:d41:8bba:9858? ([2620:10d:c091:480::1:113e]) by smtp.googlemail.com with ESMTPSA id k4sm10444655qki.2.2020.11.17.06.10.07 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 17 Nov 2020 06:10:07 -0800 (PST) To: GCC Patches From: Nathan Sidwell Subject: langhooks: preprocessor hooks for c++ modules Message-ID: <14a16659-82f2-39f9-7e8f-fdf29435fb1d@acm.org> Date: Tue, 17 Nov 2020 09:10:06 -0500 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:68.0) Gecko/20100101 Thunderbird/68.5.0 MIME-Version: 1.0 Content-Language: en-US X-Spam-Status: No, score=-11.3 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" 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 --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 (data_); + do_streamer *streamer = reinterpret_cast (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 *);