aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/c-family/c-opts.c4
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/cp/module.cc32
-rw-r--r--gcc/doc/cppopts.texi14
-rw-r--r--gcc/testsuite/c-c++-common/cpp/headerguard.c8
-rw-r--r--gcc/testsuite/c-c++-common/cpp/noheaderguard-a.h3
-rw-r--r--gcc/testsuite/c-c++-common/cpp/noheaderguard-b.h4
-rw-r--r--gcc/testsuite/c-c++-common/cpp/noheaderguard.c9
-rw-r--r--gcc/testsuite/g++.dg/modules/noheaderguard-1_a.H5
-rw-r--r--gcc/testsuite/g++.dg/modules/noheaderguard-1_b.C7
-rw-r--r--gcc/testsuite/g++.dg/modules/noheaderguard-1_c.C7
11 files changed, 84 insertions, 13 deletions
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index bd15b9cd902..240d3b8839e 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -477,6 +477,10 @@ c_common_handle_option (size_t scode, const char *arg, HOST_WIDE_INT value,
cpp_opts->extended_identifiers = value;
break;
+ case OPT_fheader_guard_opt:
+ cpp_opts->no_header_guard_opt = !value;
+ break;
+
case OPT_fmax_include_depth_:
cpp_opts->max_include_depth = value;
break;
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index b209d46d32b..7c155b01cc6 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -1660,6 +1660,10 @@ C++ ObjC++ WarnRemoved
fhandle-exceptions
C++ ObjC++ Optimization Alias(fexceptions) Warn({%<-fhandle-exceptions%> has been renamed %<-fexceptions%> (and is now on by default)})
+fheader-guard-opt
+C ObjC C++ ObjC++
+Enable header file include guard optimization.
+
fhonor-std
C++ ObjC++ WarnRemoved
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 41ce2011525..213d9f699b8 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -19144,22 +19144,28 @@ maybe_translate_include (cpp_reader *reader, line_maps *lmaps, location_t loc,
size_t len = strlen (path);
path = canonicalize_header_name (NULL, loc, true, path, len);
- auto packet = mapper->IncludeTranslate (path, Cody::Flags::None, len);
int xlate = false;
- if (packet.GetCode () == Cody::Client::PC_BOOL)
- xlate = -int (packet.GetInteger ());
- else if (packet.GetCode () == Cody::Client::PC_PATHNAME)
- {
- /* Record the CMI name for when we do the import. */
- module_state *import = get_module (build_string (len, path));
- import->set_filename (packet);
- xlate = +1;
- }
+ auto name_str = build_string (len, path);
+ if (get_module_slot (name_str, nullptr, false, false))
+ /* We've already met this header. */
+ xlate = +1;
else
{
- gcc_checking_assert (packet.GetCode () == Cody::Client::PC_ERROR);
- error_at (loc, "cannot determine %<#include%> translation of %s: %s",
- path, packet.GetString ().c_str ());
+ auto packet = mapper->IncludeTranslate (path, Cody::Flags::None, len);
+ if (packet.GetCode () == Cody::Client::PC_BOOL)
+ xlate = -int (packet.GetInteger ());
+ else if (packet.GetCode () == Cody::Client::PC_PATHNAME)
+ {
+ /* Record the CMI name for when we do the import. */
+ get_module (name_str)->set_filename (packet);
+ xlate = +1;
+ }
+ else
+ {
+ gcc_checking_assert (packet.GetCode () == Cody::Client::PC_ERROR);
+ error_at (loc, "cannot determine %<#include%> translation of %s: %s",
+ path, packet.GetString ().c_str ());
+ }
}
bool note = false;
diff --git a/gcc/doc/cppopts.texi b/gcc/doc/cppopts.texi
index b941de6df1b..a3bad58f6ab 100644
--- a/gcc/doc/cppopts.texi
+++ b/gcc/doc/cppopts.texi
@@ -266,6 +266,20 @@ standard versions) and C++.
@opindex fno-canonical-system-headers
When preprocessing, do not shorten system header paths with canonicalization.
+@item -fno-header-guard-opt
+@opindex fno-header-guard-opt
+This disables the preprocessor's optimization of header files that
+have a macro header-guard. Usually such files are do not appear at
+all in the preprocessed output on their second and subsequent
+inclusion. This disables that optimization such that they will appear
+in the @code{#} line directive output, but of course their contents
+will be elided by the controlling @code{#if} directive. This also
+covers C++ 20 include-translated header-unit imports, those will be
+subject to multiple include translations. This option is useful to
+discover the complete #include graph of a translation unit. It does
+not apply to idempotent headerfiles marked with @code{#pragma once},
+nor to headers read with @code{#import}.
+
@item -fmax-include-depth=@var{depth}
@opindex fmax-include-depth
Set the maximum depth of the nested #include. The default is 200.
diff --git a/gcc/testsuite/c-c++-common/cpp/headerguard.c b/gcc/testsuite/c-c++-common/cpp/headerguard.c
new file mode 100644
index 00000000000..be63849d33c
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/headerguard.c
@@ -0,0 +1,8 @@
+/* { dg-do preprocess } */
+/* Check header guards are optimized. */
+
+#include "noheaderguard-b.h"
+#include "noheaderguard-b.h"
+#include "noheaderguard-a.h"
+
+/* { dg-final { scan-file headerguard.i {# [0-9]* "[^\n]*headerguard.c"\n\n*# [0-9]* "[^\n]*headerguard-b.h" 1\n\n*# [0-9]* "[^\n]*headerguard-a.h" 1\n\n*# [0-9]* "[^\n]*headerguard-b.h" 2\n\n*# [0-9]* "[^\n]*headerguard.c" 2\n} } } */
diff --git a/gcc/testsuite/c-c++-common/cpp/noheaderguard-a.h b/gcc/testsuite/c-c++-common/cpp/noheaderguard-a.h
new file mode 100644
index 00000000000..6a6c2b49e8f
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/noheaderguard-a.h
@@ -0,0 +1,3 @@
+#ifndef INNER
+#define INNER
+#endif
diff --git a/gcc/testsuite/c-c++-common/cpp/noheaderguard-b.h b/gcc/testsuite/c-c++-common/cpp/noheaderguard-b.h
new file mode 100644
index 00000000000..8b72a9fbb7a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/noheaderguard-b.h
@@ -0,0 +1,4 @@
+#ifndef OUTER
+#define OUTER
+#include "noheaderguard-a.h"
+#endif
diff --git a/gcc/testsuite/c-c++-common/cpp/noheaderguard.c b/gcc/testsuite/c-c++-common/cpp/noheaderguard.c
new file mode 100644
index 00000000000..3e6fd876f1b
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/cpp/noheaderguard.c
@@ -0,0 +1,9 @@
+/* { dg-do preprocess } */
+/* { dg-additional-options -fno-header-guard-opt } */
+/* Check header guard optimization is disabled. */
+
+#include "noheaderguard-b.h"
+#include "noheaderguard-b.h"
+#include "noheaderguard-a.h"
+
+/* { dg-final { scan-file noheaderguard.i {# [0-9]* "[^\n]*noheaderguard.c"\n\n*# [0-9]* "[^\n]*noheaderguard-b.h" 1\n\n*# [0-9]* "[^\n]*noheaderguard-a.h" 1\n\n*# [0-9]* "[^\n]*noheaderguard-b.h" 2\n\n*# [0-9]* "[^\n]*noheaderguard.c" 2\n\n*# [0-9]* "[^\n]*noheaderguard-b.h" 1\n\n*# [0-9]* "[^\n]*noheaderguard.c" 2\n\n*# [0-9]* "[^\n]*noheaderguard-a.h" 1\n\n*# [0-9]* "[^\n]*noheaderguard.c" 2\n} } } */
diff --git a/gcc/testsuite/g++.dg/modules/noheaderguard-1_a.H b/gcc/testsuite/g++.dg/modules/noheaderguard-1_a.H
new file mode 100644
index 00000000000..6d552bf9cc9
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/noheaderguard-1_a.H
@@ -0,0 +1,5 @@
+// { dg-additional-options -fmodule-header }
+
+#ifndef OUTER
+#define OUTER
+#endif
diff --git a/gcc/testsuite/g++.dg/modules/noheaderguard-1_b.C b/gcc/testsuite/g++.dg/modules/noheaderguard-1_b.C
new file mode 100644
index 00000000000..d5de8b2362f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/noheaderguard-1_b.C
@@ -0,0 +1,7 @@
+// { dg-do preprocess }
+// { dg-additional-options {-fmodules-ts -fno-header-guard-opt} }
+
+#include "noheaderguard-1_a.H"
+#include "noheaderguard-1_a.H"
+
+// { dg-final { scan-file noheaderguard-1_b.i {# [0-9]* "[^\n]*noheaderguard-1_b.C"\n\n*import "[^\n]*noheaderguard-1_a.H" \[\[__translated\]\];\nimport "[^\n]*noheaderguard-1_a.H" \[\[__translated\]\];\n} } }
diff --git a/gcc/testsuite/g++.dg/modules/noheaderguard-1_c.C b/gcc/testsuite/g++.dg/modules/noheaderguard-1_c.C
new file mode 100644
index 00000000000..b4f0442769e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/noheaderguard-1_c.C
@@ -0,0 +1,7 @@
+// { dg-do preprocess }
+// { dg-additional-options {-fmodules-ts -fno-header-guard-opt} }
+
+import "noheaderguard-1_a.H";
+#include "noheaderguard-1_a.H"
+
+// { dg-final { scan-file noheaderguard-1_c.i {# [0-9]* "[^\n]*noheaderguard-1_c.C"\n\n*import "[^\n]*noheaderguard-1_a.H";\nimport "[^\n]*noheaderguard-1_a.H" \[\[__translated\]\];\n} } }