Tested x86_64-pc-linux-gnu, applying to trunk.
-- 8< --
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.
---
gcc/doc/invoke.texi | 13 ++++----
gcc/c-family/c-ppoutput.cc | 39 +++++++++++++++---------
gcc/cp/module.cc | 17 -----------
gcc/testsuite/g++.dg/modules/macro-8_b.C | 13 ++++++++
gcc/testsuite/g++.dg/modules/macro-8_c.C | 13 ++++++++
gcc/testsuite/g++.dg/modules/macro-8_d.C | 13 ++++++++
gcc/testsuite/g++.dg/modules/macro-8_a.H | 4 +++
7 files changed, 73 insertions(+), 39 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/modules/macro-8_b.C
create mode 100644 gcc/testsuite/g++.dg/modules/macro-8_c.C
create mode 100644 gcc/testsuite/g++.dg/modules/macro-8_d.C
create mode 100644 gcc/testsuite/g++.dg/modules/macro-8_a.H
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d38c1feb86f..987b6360152 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/c-family/c-ppoutput.cc b/gcc/c-family/c-ppoutput.cc
index e3f5ca3ec97..374252bb4f3 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 65b37b4b554..2dc59ce8a12 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/testsuite/g++.dg/modules/macro-8_b.C
b/gcc/testsuite/g++.dg/modules/macro-8_b.C
new file mode 100644
index 00000000000..562d4ac0e65
--- /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 00000000000..875f8fa5ddb
--- /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 00000000000..c6322169a01
--- /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 *"} } }
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 00000000000..281d5d79f88
--- /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
base-commit: 5fb1ab539e3315175d2e843f4ce40bde6dd7c520
--
2.46.2