]> git.ipfire.org Git - thirdparty/gcc.git/blob - gcc/cp/gen-cxxapi-file.py
Update copyright years.
[thirdparty/gcc.git] / gcc / cp / gen-cxxapi-file.py
1 #!/usr/bin/env python3
2
3 # Copyright (C) 2022-2024 Free Software Foundation, Inc.
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
26 import csv
27 import os
28 import 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
39 def 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
51 def 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
63 export module std;
64
65 import <bits/stdc++.h>;
66
67 // new/delete operators in global namespace from <new>
68 export using ::operator new;
69 export using ::operator delete;
70 export using ::operator new[];
71 export 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
92 def 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
100 This file is part of GCC.
101
102 GCC is free software; you can redistribute it and/or modify it under
103 the terms of the GNU General Public License as published by the Free
104 Software Foundation; either version 3, or (at your option) any later
105 version.
106
107 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
108 WARRANTY; without even the implied warranty of MERCHANTABILITY or
109 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
110 for more details.
111
112 You should have received a copy of the GNU General Public License
113 along with GCC; see the file COPYING3. If not see
114 <http://www.gnu.org/licenses/>. */
115 %}}
116 struct 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
147 def remove_comment(f):
148 for row in f:
149 row = row.strip()
150 if row[0] != '#':
151 yield row
152
153
154 modes = {
155 'export': export,
156 'hints': hints
157 }
158
159
160 def usage(script):
161 print(f'Usage: {script} [{"|".join(modes.keys())}] CSVFILE')
162 exit(1)
163
164
165 def 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
188 if __name__ == '__main__':
189 import sys
190 main(sys.argv)