aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJason Merrill <jason@redhat.com>2024-10-04 10:33:16 -0400
committerJason Merrill <jason@redhat.com>2024-10-07 11:52:41 -0400
commitc877a27f04f648e53c27daa252ca46d47e49b3a1 (patch)
tree3e178d36d781722b0072d5fd7ee29543a5a00660 /gcc
parent5fb1ab539e3315175d2e843f4ce40bde6dd7c520 (diff)
downloadgcc-c877a27f04f648e53c27daa252ca46d47e49b3a1.zip
gcc-c877a27f04f648e53c27daa252ca46d47e49b3a1.tar.gz
gcc-c877a27f04f648e53c27daa252ca46d47e49b3a1.tar.bz2
c++: modules don't require preprocessor output
init_modules has rejected -M -fmodules-ts on the premise that module dependency analysis requires macro expansion, but this is no longer accurate; P1857 prohibited module directives produced by macro expansion. They can still be dependent on #if directives, but those are still handled with -fdirectives-only. What wasn't working was -M or -dM, because cpp_scan_nooutput never called module_token_pre to implement the import. The simplest fix is to use the -fdirectives-only scan when modules are enabled and teach directives_only_cb about flag_no_output. gcc/cp/ChangeLog: * module.cc (init_modules): Don't warn about -M. gcc/c-family/ChangeLog: * c-ppoutput.cc (preprocess_file): For modules, use directives-only scan even with flag_no_output. (directives_only_cb): Respect flag_no_output. gcc/ChangeLog: * doc/invoke.texi (C++ Module Preprocessing): Allow -M, refer to -fdeps. gcc/testsuite/ChangeLog: * g++.dg/modules/macro-8_a.H: New test. * g++.dg/modules/macro-8_b.C: New test. * g++.dg/modules/macro-8_c.C: New test. * g++.dg/modules/macro-8_d.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/c-ppoutput.cc39
-rw-r--r--gcc/cp/module.cc17
-rw-r--r--gcc/doc/invoke.texi13
-rw-r--r--gcc/testsuite/g++.dg/modules/macro-8_a.H4
-rw-r--r--gcc/testsuite/g++.dg/modules/macro-8_b.C13
-rw-r--r--gcc/testsuite/g++.dg/modules/macro-8_c.C13
-rw-r--r--gcc/testsuite/g++.dg/modules/macro-8_d.C13
7 files changed, 73 insertions, 39 deletions
diff --git a/gcc/c-family/c-ppoutput.cc b/gcc/c-family/c-ppoutput.cc
index e3f5ca3..374252b 100644
--- a/gcc/c-family/c-ppoutput.cc
+++ b/gcc/c-family/c-ppoutput.cc
@@ -92,10 +92,16 @@ preprocess_file (cpp_reader *pfile)
cpp_scan_nooutput or cpp_get_token next. */
if (flag_no_output && pfile->buffer)
{
- /* Scan -included buffers, then the main file. */
- while (pfile->buffer->prev)
- cpp_scan_nooutput (pfile);
- cpp_scan_nooutput (pfile);
+ if (flag_modules)
+ /* For macros from imported headers we need directives_only_cb. */
+ scan_translation_unit_directives_only (pfile);
+ else
+ {
+ /* Scan -included buffers, then the main file. */
+ while (pfile->buffer->prev)
+ cpp_scan_nooutput (pfile);
+ cpp_scan_nooutput (pfile);
+ }
}
else if (cpp_get_options (pfile)->traditional)
scan_translation_unit_trad (pfile);
@@ -389,28 +395,31 @@ directives_only_cb (cpp_reader *pfile, CPP_DO_task task, void *data_, ...)
gcc_unreachable ();
case CPP_DO_print:
- {
- print.src_line += va_arg (args, unsigned);
+ if (!flag_no_output)
+ {
+ print.src_line += va_arg (args, unsigned);
- const void *buf = va_arg (args, const void *);
- size_t size = va_arg (args, size_t);
- fwrite (buf, 1, size, print.outf);
- }
+ const void *buf = va_arg (args, const void *);
+ size_t size = va_arg (args, size_t);
+ fwrite (buf, 1, size, print.outf);
+ }
break;
case CPP_DO_location:
- maybe_print_line (va_arg (args, location_t));
+ if (!flag_no_output)
+ maybe_print_line (va_arg (args, location_t));
break;
case CPP_DO_token:
{
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);
+ unsigned flags = 0;
if (streamer->filter)
+ flags = lang_hooks.preprocess_token (pfile, token, streamer->filter);
+ if (!flag_no_output)
{
- unsigned flags = lang_hooks.preprocess_token
- (pfile, token, streamer->filter);
+ location_t spelling_loc = va_arg (args, location_t);
+ streamer->stream (pfile, token, spelling_loc);
if (flags & lang_hooks::PT_begin_pragma)
streamer->begin_pragma ();
}
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 65b37b4..2dc59ce 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -20534,23 +20534,6 @@ init_modules (cpp_reader *reader)
fatal_error (input_location,
"C++ modules are incompatible with traditional preprocessing");
- if (flag_preprocess_only)
- {
- cpp_options *cpp_opts = cpp_get_options (reader);
- if (flag_no_output
- || (cpp_opts->deps.style != DEPS_NONE
- && !cpp_opts->deps.need_preprocessor_output))
- {
- auto_diagnostic_group d;
- warning (0, flag_dump_macros == 'M'
- ? G_("macro debug output may be incomplete with modules")
- : G_("module dependencies require preprocessing"));
- if (cpp_opts->deps.style != DEPS_NONE)
- inform (input_location, "you should use the %<-%s%> option",
- cpp_opts->deps.style == DEPS_SYSTEM ? "MD" : "MMD");
- }
- }
-
/* :: is always exported. */
DECL_MODULE_EXPORT_P (global_namespace) = true;
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d38c1fe..987b636 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -38206,13 +38206,12 @@ Whether a particular directive is translated is controlled by the
module mapper. Header unit names are canonicalized during
preprocessing.
-Dependency information can be emitted for macro import, extending the
-functionality of @option{-MD} and @option{-MMD} options. Detection of
-import declarations also requires phase 4 preprocessing, and thus
-requires full preprocessing (or compilation).
-
-The @option{-M}, @option{-MM} and @option{-E -fdirectives-only} options halt
-preprocessing before phase 4.
+Dependency information can be emitted for module import, extending the
+functionality of the various @option{-M} options. Detection of import
+declarations requires phase 4 handling of preprocessor directives, but
+does not require macro expansion, so it is not necessary to use
+@option{-MD}. See also @option{-fdeps-*} for an alternate format for
+module dependency information.
The @option{-save-temps} option uses @option{-fdirectives-only} for
preprocessing, and preserve the macro definitions in the preprocessed
diff --git a/gcc/testsuite/g++.dg/modules/macro-8_a.H b/gcc/testsuite/g++.dg/modules/macro-8_a.H
new file mode 100644
index 0000000..281d5d7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/macro-8_a.H
@@ -0,0 +1,4 @@
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+#define FOO foo
diff --git a/gcc/testsuite/g++.dg/modules/macro-8_b.C b/gcc/testsuite/g++.dg/modules/macro-8_b.C
new file mode 100644
index 0000000..562d4ac
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/macro-8_b.C
@@ -0,0 +1,13 @@
+// Test that -dM works with a header unit.
+
+// { dg-do preprocess }
+// { dg-additional-options "-dM -fmodules-ts" }
+
+import "macro-8_a.H";
+
+#ifndef FOO
+#error FOOBAR
+#endif
+
+// { dg-final { scan-file macro-8_b.i {#define FOO foo} } }
+// { dg-final { scan-file-not macro-8_b.i {import *"} } }
diff --git a/gcc/testsuite/g++.dg/modules/macro-8_c.C b/gcc/testsuite/g++.dg/modules/macro-8_c.C
new file mode 100644
index 0000000..875f8fa
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/macro-8_c.C
@@ -0,0 +1,13 @@
+// Test that -M works with a header unit.
+
+// { dg-do preprocess }
+// { dg-additional-options "-M -fmodules-ts" }
+
+import "macro-8_a.H";
+
+#ifndef FOO
+#error FOOBAR
+#endif
+
+// { dg-final { scan-file macro-8_c.i {macro-8_a.H.gcm} } }
+// { dg-final { scan-file-not macro-8_c.i {import *"} } }
diff --git a/gcc/testsuite/g++.dg/modules/macro-8_d.C b/gcc/testsuite/g++.dg/modules/macro-8_d.C
new file mode 100644
index 0000000..c632216
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/macro-8_d.C
@@ -0,0 +1,13 @@
+// Test that -MM works with a header unit.
+
+// { dg-do preprocess }
+// { dg-additional-options "-MM -MF macro-8_d.d -fmodules-ts" }
+
+#include "macro-8_a.H"
+
+#ifndef FOO
+#error FOOBAR
+#endif
+
+// { dg-final { scan-file macro-8_d.d {macro-8_a.H.gcm} } }
+// { dg-final { scan-file-not macro-8_d.i {import *"} } }