]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/cp/gen-cxxapi-file.py
Update copyright years.
[thirdparty/gcc.git] / gcc / cp / gen-cxxapi-file.py
CommitLineData
a2e28389
UD
1#!/usr/bin/env python3
2
a945c346 3# Copyright (C) 2022-2024 Free Software Foundation, Inc.
a2e28389
UD
4# This file is part of GCC.
5
6# GCC is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 3, or (at your option)
9# any later version.
10
11# GCC is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15
16# You should have received a copy of the GNU General Public License
17# along with GCC; see the file COPYING3. If not see
18# <http://www.gnu.org/licenses/>.
19
20
21# Generate gcc source files:
22# - the export description of the standard C++ library module
23# - the gperf tables used to hint at actions to fix problems
24# related to missing symbols in the std:: namespace
25
26import csv
27import os
28import time
29
30# The CSV file contains the following columns:
31# column value
32# 1 header file, including angle brackets
33# 2 symbol name without std:: prefix
34# 3 nonzero if to be exported
35# 4 "no" if not to be added to the hint table else the appropriate enum cxx_dialect value
36# 5 optional, a string used after #if in a line inserted first to enable conditional definitions
37
38
39def print_condition(prev, e):
40 if len(e) > 4 and e[4] != '':
41 if not prev or prev != e[4]:
42 if prev:
43 print('#endif')
44 print(f'#if {e[4]}')
45 return e[4]
46 if prev:
47 print('#endif')
48 return None
49
50
51def export(script, content):
52 print("""// This file is auto-generated by {:s}.
53#if __cplusplus <= 202002L
54# if __cplusplus == 202002L
55# ifdef __STRICT_ANSI__
56# error "module `std' is only available before C++23 if using -std=gnu++20"
57# endif
58# else
59# error "module `std' is not available before C++23"
60# endif
61#endif
62
63export module std;
64
65import <bits/stdc++.h>;
66
67// new/delete operators in global namespace from <new>
68export using ::operator new;
69export using ::operator delete;
70export using ::operator new[];
71export using ::operator delete[];""".format(script))
72 header = ''
73 printed_header = False
74 cond = None
75 for e in content:
76 if e[0] != header:
77 header = e[0]
78 printed_header = False
79 if e[2] != 0:
80 if not printed_header:
81 if cond:
82 print('#endif')
83 cond = None
84 print(f'\n// {header}')
85 printed_header = True
86 cond = print_condition(cond, e)
87 print(f'export using std::{e[1]};')
88 if cond:
89 print('#endif')
90
91
92def hints(script, content):
93 print("""%language=C++
94%define class-name std_name_hint_lookup
95%struct-type
96%{{
97/* This file is auto-generated by {:s}. */
98/* Copyright (C) {:s} Free Software Foundation, Inc.
99
100This file is part of GCC.
101
102GCC is free software; you can redistribute it and/or modify it under
103the terms of the GNU General Public License as published by the Free
104Software Foundation; either version 3, or (at your option) any later
105version.
106
107GCC is distributed in the hope that it will be useful, but WITHOUT ANY
108WARRANTY; without even the implied warranty of MERCHANTABILITY or
109FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
110for more details.
111
112You should have received a copy of the GNU General Public License
113along with GCC; see the file COPYING3. If not see
114<http://www.gnu.org/licenses/>. */
115%}}
116struct std_name_hint
117{{
118 /* A name within "std::". */
119 const char *name;
120
121 /* The header name defining it within the C++ Standard Library
122 (with '<' and '>'). */
123 const char* header;
124
125 /* The dialect of C++ in which this was added. */
126 enum cxx_dialect min_dialect;
127}};
128%%
129# The standard-defined types, functions, and options in the std:: namespace
130# as defined in the C++ language specification. The result is used in the
131# get_std_name_hint functions.
132# throws an exception.
133#""".format(script, time.strftime('%Y')))
134 header = ''
135 printed_header = False
136 for e in content:
137 if e[0] != header:
138 header = e[0]
139 printed_header = False
140 if e[3] != 'no':
141 if not printed_header:
142 print(f'# {header}')
143 printed_header = True
144 print(f'{e[1]}, "{e[0]}", {e[3]}')
145
146
147def remove_comment(f):
148 for row in f:
149 row = row.strip()
150 if row[0] != '#':
151 yield row
152
153
154modes = {
155 'export': export,
156 'hints': hints
157}
158
159
160def usage(script):
161 print(f'Usage: {script} [{"|".join(modes.keys())}] CSVFILE')
162 exit(1)
163
164
165def main(argv):
166 if len(argv) < 3:
167 usage(argv[0] if len(argv) > 0 else '???')
168
169 script = argv[0]
170 mode = argv[1]
171 filename = argv[2]
172
173 if mode not in modes:
174 print(f"{script}: unrecognized mode '{mode}'")
175 usage(script)
176
177 try:
178 with open(filename, 'r') as csvfile:
179 modes[mode](os.path.basename(script), sorted(csv.reader(remove_comment(csvfile), delimiter=',')))
180 except FileNotFoundError:
181 print(f"{script}: cannot find CSV file '{filename}'")
182 exit(1)
183 except PermissionError:
184 print(f"{script}: insufficient permission to read CSV file '{filename}'")
185 exit(1)
186
187
188if __name__ == '__main__':
189 import sys
190 main(sys.argv)