[libcxx-commits] [libcxx] 41161ae - [libc++][modules] Generates std.cppm.in.
Mark de Wever via libcxx-commits
libcxx-commits at lists.llvm.org
Tue Aug 22 11:13:45 PDT 2023
Author: Mark de Wever
Date: 2023-08-22T20:13:39+02:00
New Revision: 41161aeb5460a8fea9f55c185b6cc6a438a491fb
URL: https://github.com/llvm/llvm-project/commit/41161aeb5460a8fea9f55c185b6cc6a438a491fb
DIFF: https://github.com/llvm/llvm-project/commit/41161aeb5460a8fea9f55c185b6cc6a438a491fb.diff
LOG: [libc++][modules] Generates std.cppm.in.
This takes the header restrictions into account instead of manually
duplicating this build information. This is a preparation to properly
support the libc++ disabled parts in the std module.
Reviewed By: #libc, ldionne
Differential Revision: https://reviews.llvm.org/D158192
Added:
libcxx/utils/generate_std_cppm_in.py
Modified:
libcxx/modules/std.cppm.in
libcxx/test/libcxx/module_std.gen.py
libcxx/utils/CMakeLists.txt
libcxx/utils/libcxx/header_information.py
Removed:
################################################################################
diff --git a/libcxx/modules/std.cppm.in b/libcxx/modules/std.cppm.in
index dd611d5dbca386..65cec804ff122a 100644
--- a/libcxx/modules/std.cppm.in
+++ b/libcxx/modules/std.cppm.in
@@ -7,19 +7,25 @@
//
//===----------------------------------------------------------------------===//
+// WARNING, this entire header is generated by
+// utils/generate_std_cppm_in.py
+// DO NOT MODIFY!
+
module;
#include <__config>
-// TODO MODULES This could be generated
-
// The headers of Table 24: C++ library headers [tab:headers.cpp]
// and the headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c]
#include <algorithm>
#include <any>
#include <array>
-#include <atomic>
-#include <barrier>
+#if !defined(_LIBCPP_HAS_NO_ATOMIC_HEADER)
+# include <atomic>
+#endif
+#if !defined(_LIBCPP_HAS_NO_THREADS)
+# include <barrier>
+#endif
#include <bit>
#include <bitset>
#include <cassert>
@@ -31,7 +37,13 @@ module;
#include <chrono>
#include <cinttypes>
#include <climits>
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <clocale>
+#endif
#include <cmath>
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <codecvt>
+#endif
#include <compare>
#include <complex>
#include <concepts>
@@ -47,6 +59,12 @@ module;
#include <cstring>
#include <ctime>
#include <cuchar>
+#if !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
+# include <cwchar>
+#endif
+#if !defined(_LIBCPP_HAS_NO_WIDE_CHARACTERS)
+# include <cwctype>
+#endif
#include <deque>
#include <exception>
#include <execution>
@@ -54,14 +72,36 @@ module;
#include <filesystem>
#include <format>
#include <forward_list>
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <fstream>
+#endif
#include <functional>
-#include <future>
+#if !defined(_LIBCPP_HAS_NO_THREADS)
+# include <future>
+#endif
#include <initializer_list>
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <iomanip>
+#endif
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <ios>
+#endif
#include <iosfwd>
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <iostream>
+#endif
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <istream>
+#endif
#include <iterator>
-#include <latch>
+#if !defined(_LIBCPP_HAS_NO_THREADS)
+# include <latch>
+#endif
#include <limits>
#include <list>
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <locale>
+#endif
#include <map>
#include <mdspan>
#include <memory>
@@ -71,24 +111,47 @@ module;
#include <numbers>
#include <numeric>
#include <optional>
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <ostream>
+#endif
#include <print>
#include <queue>
#include <random>
#include <ranges>
#include <ratio>
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <regex>
+#endif
#include <scoped_allocator>
-#include <semaphore>
+#if !defined(_LIBCPP_HAS_NO_THREADS)
+# include <semaphore>
+#endif
#include <set>
-#include <shared_mutex>
+#if !defined(_LIBCPP_HAS_NO_THREADS)
+# include <shared_mutex>
+#endif
#include <source_location>
#include <span>
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <sstream>
+#endif
#include <stack>
#include <stdexcept>
-#include <stop_token>
+#if !defined(_LIBCPP_HAS_NO_THREADS)
+# include <stop_token>
+#endif
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <streambuf>
+#endif
#include <string>
#include <string_view>
+#if !defined(_LIBCPP_HAS_NO_LOCALIZATION)
+# include <strstream>
+#endif
#include <system_error>
-#include <thread>
+#if !defined(_LIBCPP_HAS_NO_THREADS)
+# include <thread>
+#endif
#include <tuple>
#include <type_traits>
#include <typeindex>
@@ -101,68 +164,36 @@ module;
#include <vector>
#include <version>
-// *** Headers disabled by a feature ***
-
-#ifndef _LIBCPP_HAS_NO_LOCALIZATION
-# include <clocale>
-# include <codecvt>
-# include <fstream>
-# include <iomanip>
-# include <ios>
-# include <iostream>
-# include <istream>
-# include <locale>
-# include <ostream>
-# include <regex>
-# include <sstream>
-# include <streambuf>
-# include <strstream>
-#endif // _LIBCPP_HAS_NO_LOCALIZATION
-#ifndef _LIBCPP_HAS_NO_WIDE_CHARACTERS
-# include <cwchar>
-# include <cwctype>
-#endif // _LIBCPP_HAS_NO_WIDE_CHARACTERS
-
// *** Headers not yet available ***
+#if __has_include(<flat_map>)
+# error "update the header information for <flat_map> in libcxx/utils/generate_std_cppm_in.py"
+#endif // __has_include(<flat_map>)
+#if __has_include(<flat_set>)
+# error "update the header information for <flat_set> in libcxx/utils/generate_std_cppm_in.py"
+#endif // __has_include(<flat_set>)
#if __has_include(<generator>)
-# error "include <generator> unconditionally"
-# include <generator>
+# error "update the header information for <generator> in libcxx/utils/generate_std_cppm_in.py"
#endif // __has_include(<generator>)
#if __has_include(<hazard_pointer>)
-# error "include <hazard_pointer> unconditionally"
-# include <hazard_pointer>
+# error "update the header information for <hazard_pointer> in libcxx/utils/generate_std_cppm_in.py"
#endif // __has_include(<hazard_pointer>)
-#if __has_include(<flat_map>)
-# error "include <flat_map> unconditionally"
-# include <flat_map>
-#endif // __has_include(<flat_map>)
-#if __has_include(<flat_set>)
-# error "include <flat_set> unconditionally"
-# include <flat_set>
-#endif // __has_include(<flat_set>)
#if __has_include(<rcu>)
-# error "include <rcu> unconditionally"
-# include <rcu>
+# error "update the header information for <rcu> in libcxx/utils/generate_std_cppm_in.py"
#endif // __has_include(<rcu>)
#if __has_include(<spanstream>)
-# error "include <spanstream> unconditionally"
-# include <spanstream>
+# error "update the header information for <spanstream> in libcxx/utils/generate_std_cppm_in.py"
#endif // __has_include(<spanstream>)
#if __has_include(<stacktrace>)
-# error "include <stacktrace> unconditionally"
-# include <stacktrace>
+# error "update the header information for <stacktrace> in libcxx/utils/generate_std_cppm_in.py"
#endif // __has_include(<stacktrace>)
#if __has_include(<stdfloat>)
-# error "include <stdfloat> unconditionally"
-# include <stdfloat>
+# error "update the header information for <stdfloat> in libcxx/utils/generate_std_cppm_in.py"
#endif // __has_include(<stdfloat>)
#if __has_include(<syncstream>)
-# error "include <syncstream> unconditionally"
-# include <syncstream>
+# error "update the header information for <syncstream> in libcxx/utils/generate_std_cppm_in.py"
#endif // __has_include(<syncstream>)
#if __has_include(<text_encoding>)
-# error "include <text_encoding> unconditionally"
-# include <text_encoding>
+# error "update the header information for <text_encoding> in libcxx/utils/generate_std_cppm_in.py"
#endif // __has_include(<text_encoding>)
export module std;
diff --git a/libcxx/test/libcxx/module_std.gen.py b/libcxx/test/libcxx/module_std.gen.py
index af9b652911bdcb..6d146252754900 100644
--- a/libcxx/test/libcxx/module_std.gen.py
+++ b/libcxx/test/libcxx/module_std.gen.py
@@ -21,22 +21,12 @@
import sys
sys.path.append(sys.argv[1])
-from libcxx.header_information import toplevel_headers
+from libcxx.header_information import module_headers
BLOCKLIT = (
"" # block Lit from interpreting a RUN/XFAIL/etc inside the generation script
)
-### Remove the headers that have no module associated with them
-
-# Note all C-headers using .h are filtered in the loop.
-
-# These headers are not available in C++23, but in older language Standards.
-toplevel_headers.remove("ccomplex")
-toplevel_headers.remove("ciso646")
-toplevel_headers.remove("cstdbool")
-toplevel_headers.remove("ctgmath")
-
# Ignore several declarations found in the includes.
#
# Part of these items are bugs other are not yet implemented features.
@@ -140,10 +130,7 @@
)
# Validate all module parts.
-for header in toplevel_headers:
- if header.endswith(".h"): # Skip C compatibility headers
- continue
-
+for header in module_headers:
# Generate a module partition for the header module includes. This
# makes it possible to verify that all headers export all their
# named declarations.
diff --git a/libcxx/utils/CMakeLists.txt b/libcxx/utils/CMakeLists.txt
index ce4e289290dce6..7e597f632b6c46 100644
--- a/libcxx/utils/CMakeLists.txt
+++ b/libcxx/utils/CMakeLists.txt
@@ -6,6 +6,10 @@ add_custom_target(libcxx-generate-std-clang-module-header
COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/generate_std_clang_module_header.py"
COMMENT "Generate the <__std_clang_module> header")
+add_custom_target(libcxx-generate-std-cppm-in-file
+ COMMAND "${Python3_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/generate_std_cppm_in.py"
+ COMMENT "Generate the std.cppm.in file")
+
add_custom_target(libcxx-generate-extended-grapheme-cluster-tables
COMMAND
"${Python3_EXECUTABLE}"
@@ -43,6 +47,7 @@ add_custom_target(libcxx-generate-iwyu-mapping
add_custom_target(libcxx-generate-files
DEPENDS libcxx-generate-feature-test-macros
libcxx-generate-std-clang-module-header
+ libcxx-generate-std-cppm-in-file
libcxx-generate-extended-grapheme-cluster-tables
libcxx-generate-extended-grapheme-cluster-tests
libcxx-generate-escaped-output-table
diff --git a/libcxx/utils/generate_std_cppm_in.py b/libcxx/utils/generate_std_cppm_in.py
new file mode 100644
index 00000000000000..522f1dd8161aea
--- /dev/null
+++ b/libcxx/utils/generate_std_cppm_in.py
@@ -0,0 +1,74 @@
+# ===----------------------------------------------------------------------===##
+#
+# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+#
+# ===----------------------------------------------------------------------===##
+
+import operator
+import os.path
+
+from libcxx.header_information import module_headers
+from libcxx.header_information import header_restrictions
+from libcxx.header_information import headers_not_available
+
+
+libcxx_module_directory = os.path.join(
+ os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "modules"
+)
+with open(
+ os.path.join(libcxx_module_directory, "std.cppm.in"), "w"
+) as std_module_cpp_in:
+ std_module_cpp_in.write(
+ """\
+// -*- C++ -*-
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// WARNING, this entire header is generated by
+// utils/generate_std_cppm_in.py
+// DO NOT MODIFY!
+
+module;
+
+#include <__config>
+
+// The headers of Table 24: C++ library headers [tab:headers.cpp]
+// and the headers of Table 25: C++ headers for C library facilities [tab:headers.cpp.c]
+"""
+ )
+ for header in module_headers:
+ if header in header_restrictions:
+ std_module_cpp_in.write(
+ f"""\
+#if {header_restrictions[header]}
+# include <{header}>
+#endif
+"""
+ )
+ else:
+ std_module_cpp_in.write(f"#include <{header}>\n")
+
+ std_module_cpp_in.write("\n// *** Headers not yet available ***\n")
+ for header in sorted(headers_not_available):
+ std_module_cpp_in.write(
+ f"""\
+#if __has_include(<{header}>)
+# error "update the header information for <{header}> in libcxx/utils/generate_std_cppm_in.py"
+#endif // __has_include(<{header}>)
+"""
+ )
+
+ std_module_cpp_in.write(
+ """
+export module std;
+
+ at LIBCXX_MODULE_STD_INCLUDE_SOURCES@
+"""
+ )
diff --git a/libcxx/utils/libcxx/header_information.py b/libcxx/utils/libcxx/header_information.py
index 683fe23638e17c..db6f3246f6ba71 100644
--- a/libcxx/utils/libcxx/header_information.py
+++ b/libcxx/utils/libcxx/header_information.py
@@ -141,6 +141,26 @@
"vector": ["compare", "initializer_list"],
}
+
+# These headers are not yet implemented in libc++
+#
+# These headers are required by the latest (draft) Standard but have not been
+# implemented yet. They are used in the generated module input. The C++23 standard
+# modules will fail to build if a header is added but this list is not updated.
+headers_not_available = [
+ "flat_map",
+ "flat_set",
+ "generator",
+ "hazard_pointer",
+ "rcu",
+ "spanstream",
+ "stacktrace",
+ "stdfloat",
+ "syncstream",
+ "text_encoding",
+]
+
+
def is_header(file):
"""Returns whether the given file is a header (i.e. not a directory or the modulemap file)."""
return (
@@ -159,6 +179,19 @@ def is_header(file):
p.relative_to(include).as_posix() for p in include.glob("[a-z]*") if is_header(p)
)
experimental_headers = sorted(
- p.relative_to(include).as_posix() for p in include.glob("experimental/[a-z]*") if is_header(p)
+ p.relative_to(include).as_posix()
+ for p in include.glob("experimental/[a-z]*")
+ if is_header(p)
)
public_headers = toplevel_headers + experimental_headers
+
+# The headers used in the std and std.compat modules.
+#
+# This is the set of all C++23-and-later headers, excluding C compatibility headers.
+module_headers = [
+ header
+ for header in toplevel_headers
+ if not header.endswith(".h")
+ # These headers have been removed in C++20 so are never part of a module.
+ and not header in ["ccomplex", "ciso646", "cstdbool", "ctgmath"]
+]
More information about the libcxx-commits
mailing list