On Thu, 11 Dec 2025, Jason Merrill wrote:
> On 12/11/25 11:12 PM, Patrick Palka wrote:
> > On Wed, 10 Dec 2025, Jason Merrill wrote:
> >
> > > Actually applying this revised version. Tested x86_64-pc-linux-gnu.
> > >
> > > -- 8< --
> > >
> > > Since the standard library doesn't preclude an #include of a standard
> > > library header from bringing in declarations from other headers, we can
> > > translate an #include of any of the importable headers as an import of
> > > <bits/stdc++.h>.
> > >
> > > To reduce the amount of C++ standard knowledge encoded in libcpp, I extend
> > > the translate_include callback to allow it to suggest an alternate header
> > > to
> > > try translating. It's a bit awkward to bounce back and forth, but this
> > > seems like the right division of responsibilities.
> > >
> > > libcpp/ChangeLog:
> > >
> > > * include/cpplib.h (struct cpp_callbacks): Replace 'path' parameter
> > > with file, angle_brackets, and alternate name.
> > > (cpp_get_name): Declare.
> > > * files.cc (cpp_get_name): New.
> > > (_cpp_stack_include, _cpp_post_stack_file, _cpp_stack_file)
> > > (_cpp_stack_translated_file): Refactor, try alternate file.
> > >
> > > gcc/cp/ChangeLog:
> > >
> > > * module.cc (maybe_translate_include): Suggest <bits/stdc++.h>
> > > as an alternate for importable standard library headers.
> > > (importable_headers, is_importable_header): New.
> > >
> > > gcc/ChangeLog:
> > >
> > > * doc/invoke.texi (C++ Modules): Remove standard library header
> > > units from missing pieces, mention importable header redirection.
> > >
> > > gcc/testsuite/ChangeLog:
> > >
> > > * g++.dg/modules/compile-std1.C: Test <vector> translation.
> > > ---
> > > gcc/doc/invoke.texi | 15 +-
> > > libcpp/include/cpplib.h | 3 +-
> > > gcc/cp/module.cc | 81 ++++++++-
> > > gcc/testsuite/g++.dg/modules/compile-std1.C | 4 +-
> > > libcpp/files.cc | 189 ++++++++++++--------
> > > 5 files changed, 204 insertions(+), 88 deletions(-)
> > >
> > > diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
> > > index 813403a9733..8db0aa0ceb7 100644
> > > --- a/gcc/doc/invoke.texi
> > > +++ b/gcc/doc/invoke.texi
> > > @@ -38780,13 +38780,6 @@ reverse is not implemented---textually redefining
> > > an entity that has
> > > been defined in an imported header-unit. A redefinition error is
> > > emitted.
> > > -@item Standard Library Header Units
> > > -The Standard Library is not provided as importable header units. If
> > > -you want to import such units, you must explicitly build them first.
> > > -If you do not do this with care, you may have multiple declarations,
> > > -which the module machinery must merge---compiler resource usage can be
> > > -affected by how you partition header files into header units.
> > > -
> > > @end table
> > > Modular compilation is @emph{not} enabled with just the
> > > @@ -38849,6 +38842,14 @@ and any standard library #includes in mycode.C
> > > will be skipped,
> > > because the import brought in the whole library. This can be a simple
> > > way to use modules to speed up compilation without any code changes.
> > > +But for the standard library in particular this is unnecessary: if a
> > > +header unit has been built for the libstdc++ @samp{bits/stdc++.h}
> > > +header, the compiler will translate an @samp{#include} of any
> > > +importable standard library header into an import of that header unit,
> > > +speeding up compilation without needing to specify @samp{-include}.
> > > +Note that the @samp{bits/stdc++.h} header unit is also built by the
> > > +@option{--compile-std-module} option.
> > > +
> > > The @option{-fmodule-only} option disables generation of the
> > > associated object file for compiling a module interface. Only the CMI
> > > is generated. This option is implied when using the
> > > diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h
> > > index 16f030c82f3..65e1bc6aae0 100644
> > > --- a/libcpp/include/cpplib.h
> > > +++ b/libcpp/include/cpplib.h
> > > @@ -860,7 +860,8 @@ struct cpp_callbacks
> > > /* Maybe translate a #include into something else. Return a
> > > cpp_buffer containing the translation if translating. */
> > > char *(*translate_include) (cpp_reader *, line_maps *, location_t,
> > > - const char *path);
> > > + _cpp_file *file, bool angle_brackets,
> > > + const char **alternate);
> > > };
> > > #ifdef VMS
> > > diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> > > index 5c70e9bb469..7899fac8a2d 100644
> > > --- a/gcc/cp/module.cc
> > > +++ b/gcc/cp/module.cc
> > > @@ -22541,11 +22541,66 @@ void module_state::set_filename (const
> > > Cody::Packet &packet)
> > > }
> > > }
> > > +/* The list of importable headers from C++ Table 24. */
> > > +
> > > +static const char *
> > > +importable_headers[] =
> > > + {
> > > + "algorithm", "any", "array", "atomic",
> > > + "barrier", "bit", "bitset",
> > > + "charconv", "chrono", "compare", "complex", "concepts",
> > > + "condition_variable", "contracts", "coroutine",
> > > + "debugging", "deque",
> > > + "exception", "execution", "expected",
> > > + "filesystem", "flat_map", "flat_set", "format", "forward_list",
> > > + "fstream", "functional", "future",
> > > + "generator",
> > > + "hazard_pointer", "hive",
> > > + "initializer_list", "inplace_vector", "iomanip", "ios", "iosfwd",
> > > + "iostream", "istream", "iterator",
> > > + "latch", "limits", "linalg", "list", "locale",
> > > + "map", "mdspan", "memory", "memory_resource", "meta", "mutex",
> > > + "new", "numbers", "numeric",
> > > + "optional", "ostream",
> > > + "print",
> > > + "queue",
> > > + "random", "ranges", "ratio", "rcu", "regex",
> > > + "scoped_allocator", "semaphore", "set", "shared_mutex", "simd",
> > > + "source_location", "span", "spanstream", "sstream", "stack",
> > > "stacktrace",
> > > + "stdexcept", "stdfloat", "stop_token", "streambuf", "string",
> > > + "string_view", "syncstream", "system_error",
> > > + "text_encoding", "thread", "tuple", "type_traits", "typeindex",
> > > "typeinfo",
> > > + "unordered_map", "unordered_set",
> > > + "utility",
> > > + "valarray", "variant", "vector", "version"
> > > + };
> >
> > It seems this list doesn't included <cstdint> and the other such C
> > headers, is there a reason we can't translate those to import
> > <bits/stdc++.h> as well?
>
> Well, they aren't specified as importable headers by the standard (table 24),
> but I suppose we could also decide that they are in the implementation-defined
> set of importable headers.
>
> Practically, it seems somewhat surprising to get the whole C++ library when
> #including a C library header.
>
> And including C and C++ headers in various orders is fine because once
> stdc++.h has been imported the include guard macros are defined so #including
> <cxxx> is a noop.
Good point, I was indeed thinking about this in the context of 99000
but I didn't realize that we don't have to worry about 99000 as long as
the user includes an importable header before including <cfoo>, which in
practice should be by far the most common scenario.
>
> The use case that doing that would help wrt 99000 is
>
> import std;
> #include <cstdlib>
>
> at the cost of exposing all the implementation details of the entire library
> that are hidden when just importing std.
>
> It's not clear to me that this is a significant win. Other opinions are
> welcome.
+1
>
> Jason
>
>