https://gcc.gnu.org/g:c877a27f04f648e53c27daa252ca46d47e49b3a1

commit r15-4119-gc877a27f04f648e53c27daa252ca46d47e49b3a1
Author: Jason Merrill <ja...@redhat.com>
Date:   Fri Oct 4 10:33:16 2024 -0400

    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.

Diff:
---
 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(-)

diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index d38c1feb86f7..987b63601520 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 e3f5ca3ec97c..374252bb4f37 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 65b37b4b5544..2dc59ce8a120 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 000000000000..562d4ac0e655
--- /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 000000000000..875f8fa5ddb3
--- /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 000000000000..c6322169a013
--- /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 000000000000..281d5d79f88d
--- /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

Reply via email to