Skip to content

Commit f1c957d

Browse files
authored
[libc] newheadergen: script adjusted for cmake (llvm#98825)
- added entrypoints and headerfile parameters depending on target - fixed nits in yaml files causing errors - tested with new cmake config - cmake patch will be seperate
1 parent 5f8c46b commit f1c957d

File tree

8 files changed

+162
-64
lines changed

8 files changed

+162
-64
lines changed

libc/newhdrgen/class_implementation/classes/function.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ def __str__(self):
2626
attributes_str = " ".join(self.attributes)
2727
arguments_str = ", ".join(self.arguments)
2828
if attributes_str == "":
29-
result = f"{self.return_type} {self.name}({arguments_str}) __NOEXCEPT;"
29+
result = f"{self.return_type} {self.name}({arguments_str});"
3030
else:
31-
result = f"{attributes_str} {self.return_type} {self.name}({arguments_str}) __NOEXCEPT;"
31+
result = f"{attributes_str} {self.return_type} {self.name}({arguments_str})"
3232
return result

libc/newhdrgen/gpu_headers.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
#!/usr/bin/env python
2+
#
3+
# ===- GPU HeaderFile Class for --export-decls version --------*- python -*--==#
4+
#
5+
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
6+
# See https://llvm.org/LICENSE.txt for license information.
7+
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
8+
#
9+
# ==-------------------------------------------------------------------------==#
10+
11+
12+
class GpuHeaderFile:
13+
def __init__(self, name):
14+
self.name = name
15+
self.macros = []
16+
self.types = []
17+
self.enumerations = []
18+
self.objects = []
19+
self.functions = []
20+
self.includes = []
21+
22+
def add_macro(self, macro):
23+
self.macros.append(macro)
24+
25+
def add_type(self, type_):
26+
self.types.append(type_)
27+
28+
def add_enumeration(self, enumeration):
29+
self.enumerations.append(enumeration)
30+
31+
def add_object(self, object):
32+
self.objects.append(object)
33+
34+
def add_function(self, function):
35+
self.functions.append(function)
36+
37+
def __str__(self):
38+
content = []
39+
40+
content.append(
41+
f"//===-- C standard declarations for {self.name} ------------------------------===//"
42+
)
43+
content.append("//")
44+
content.append(
45+
"// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions."
46+
)
47+
content.append("// See https://llvm.org/LICENSE.txt for license information.")
48+
content.append("// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception")
49+
content.append("//")
50+
content.append(
51+
"//===----------------------------------------------------------------------===//\n"
52+
)
53+
54+
header_guard = f"__LLVM_LIBC_DECLARATIONS_{self.name.upper()[:-2]}_H"
55+
content.append(f"#ifndef {header_guard}")
56+
content.append(f"#define {header_guard}\n")
57+
58+
content.append("#ifndef __LIBC_ATTRS")
59+
content.append("#define __LIBC_ATTRS")
60+
content.append("#endif\n")
61+
62+
content.append("#ifdef __cplusplus")
63+
content.append('extern "C" {')
64+
content.append("#endif\n")
65+
66+
for function in self.functions:
67+
content.append(f"{function} __LIBC_ATTRS;\n")
68+
69+
for object in self.objects:
70+
content.append(f"{object} __LIBC_ATTRS;\n")
71+
72+
content.append("#ifdef __cplusplus")
73+
content.append("}")
74+
content.append("#endif\n")
75+
76+
content.append(f"#endif")
77+
78+
return "\n".join(content)

libc/newhdrgen/header.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,29 +60,29 @@ def __str__(self):
6060
current_guard = None
6161
for function in self.functions:
6262
if function.guard == None:
63-
content.append(str(function))
63+
content.append(str(function) + "__NOEXCEPT")
6464
content.append("")
6565
else:
6666
if current_guard == None:
6767
current_guard = function.guard
6868
content.append(f"#ifdef {current_guard}")
69-
content.append(str(function))
69+
content.append(str(function) + "__NOEXCEPT")
7070
content.append("")
7171
elif current_guard == function.guard:
72-
content.append(str(function))
72+
content.append(str(function) + "__NOEXCEPT")
7373
content.append("")
7474
else:
7575
content.pop()
7676
content.append(f"#endif // {current_guard}")
7777
content.append("")
7878
current_guard = function.guard
7979
content.append(f"#ifdef {current_guard}")
80-
content.append(str(function))
80+
content.append(str(function) + "__NOEXCEPT")
8181
content.append("")
8282
if current_guard != None:
8383
content.pop()
8484
content.append(f"#endif // {current_guard}")
85-
content.append("")
85+
content.append("")
8686

8787
for object in self.objects:
8888
content.append(str(object))

libc/newhdrgen/yaml/features.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
header: features.h
2+
standards:
3+
- stdc
4+
macros: []
5+
types: []
6+
enums: []
7+
objects: []
8+
functions: []

libc/newhdrgen/yaml/pthread.yaml

Lines changed: 3 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,33 +13,8 @@ types:
1313
- type_name: __pthread_start_t
1414
- type_name: __pthread_once_func_t
1515
- type_name: __atfork_callback_t
16-
enums:
17-
- name: PTHREAD_CREATE_JOINABLE
18-
value: 0x0
19-
- name: PTHREAD_CREATE_DETACHED
20-
value: 0x1
21-
- name: PTHREAD_MUTEX_NORMAL
22-
value: 0x0
23-
- name: PTHREAD_MUTEX_ERRORCHECK
24-
value: 0x1
25-
- name: PTHREAD_MUTEX_RECURSIVE
26-
value: 0x2
27-
- name: PTHREAD_MUTEX_DEFAULT
28-
value: 0x0
29-
- name: PTHREAD_PROCESS_PRIVATE
30-
value: 0x0
31-
- name: PTHREAD_PROCESS_SHARED
32-
value: 0x1
33-
- name: PTHREAD_MUTEX_STALLED
34-
value: 0x0
35-
- name: PTHREAD_MUTEX_ROBUST
36-
value: 0x1
37-
- name: PTHREAD_RWLOCK_PREFER_READER_NP
38-
value: 0
39-
- name: PTHREAD_RWLOCK_PREFER_WRITER_NP
40-
value: 1
41-
- name: PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
42-
value: 2
16+
- type_name: pthread_rwlock_t
17+
enums: []
4318
functions:
4419
- name: pthread_atfork
4520
standards:
@@ -184,7 +159,7 @@ functions:
184159
- name: pthread_exit
185160
standards:
186161
- POSIX
187-
return_type: __Noreturn void
162+
return_type: _Noreturn void
188163
arguments:
189164
- type: void *
190165
- name: pthread_getname_np

libc/newhdrgen/yaml/sys/sys_random.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ types:
44
- type_name: ssize_t
55
- type_name: size_t
66
enums: []
7-
objects:
7+
objects: []
88
functions:
99
- name: getrandom
1010
standards:

libc/newhdrgen/yaml/time.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ functions:
1515
- stdc
1616
return_type: char *
1717
arguments:
18-
- type: struct tm *
18+
- type: const struct tm *
1919
- name: asctime_r
2020
standard:
2121
- stdc

libc/newhdrgen/yaml_to_classes.py

Lines changed: 64 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,11 @@
88
#
99
# ==-------------------------------------------------------------------------==#
1010

11-
1211
import yaml
1312
import argparse
14-
1513
from pathlib import Path
1614
from header import HeaderFile
15+
from gpu_headers import GpuHeaderFile as GpuHeader
1716
from class_implementation.classes.macro import Macro
1817
from class_implementation.classes.type import Type
1918
from class_implementation.classes.function import Function
@@ -22,18 +21,20 @@
2221
from class_implementation.classes.object import Object
2322

2423

25-
def yaml_to_classes(yaml_data):
24+
def yaml_to_classes(yaml_data, header_class, entry_points=None):
2625
"""
2726
Convert YAML data to header classes.
2827
2928
Args:
3029
yaml_data: The YAML data containing header specifications.
30+
header_class: The class to use for creating the header.
31+
entry_points: A list of specific function names to include in the header.
3132
3233
Returns:
3334
HeaderFile: An instance of HeaderFile populated with the data.
3435
"""
3536
header_name = yaml_data.get("header")
36-
header = HeaderFile(header_name)
37+
header = header_class(header_name)
3738

3839
for macro_data in yaml_data.get("macros", []):
3940
header.add_macro(Macro(macro_data["macro_name"], macro_data["macro_value"]))
@@ -49,12 +50,15 @@ def yaml_to_classes(yaml_data):
4950
)
5051

5152
functions = yaml_data.get("functions", [])
53+
if entry_points:
54+
entry_points_set = set(entry_points)
55+
functions = [f for f in functions if f["name"] in entry_points_set]
5256
sorted_functions = sorted(functions, key=lambda x: x["name"])
5357
guards = []
5458
guarded_function_dict = {}
5559
for function_data in sorted_functions:
5660
guard = function_data.get("guard", None)
57-
if guard == None:
61+
if guard is None:
5862
arguments = [arg["type"] for arg in function_data["arguments"]]
5963
attributes = function_data.get("attributes", None)
6064
standards = function_data.get("standards", None)
@@ -105,19 +109,21 @@ def yaml_to_classes(yaml_data):
105109
return header
106110

107111

108-
def load_yaml_file(yaml_file):
112+
def load_yaml_file(yaml_file, header_class, entry_points):
109113
"""
110114
Load YAML file and convert it to header classes.
111115
112116
Args:
113-
yaml_file: The path to the YAML file.
117+
yaml_file: Path to the YAML file.
118+
header_class: The class to use for creating the header (HeaderFile or GpuHeader).
119+
entry_points: A list of specific function names to include in the header.
114120
115121
Returns:
116-
HeaderFile: An instance of HeaderFile populated with the data from the YAML file.
122+
HeaderFile: An instance of HeaderFile populated with the data.
117123
"""
118124
with open(yaml_file, "r") as f:
119125
yaml_data = yaml.safe_load(f)
120-
return yaml_to_classes(yaml_data)
126+
return yaml_to_classes(yaml_data, header_class, entry_points)
121127

122128

123129
def fill_public_api(header_str, h_def_content):
@@ -207,7 +213,14 @@ def increase_indent(self, flow=False, indentless=False):
207213
print(f"Added function {new_function.name} to {yaml_file}")
208214

209215

210-
def main(yaml_file, h_def_file, output_dir, add_function=None):
216+
def main(
217+
yaml_file,
218+
output_dir=None,
219+
h_def_file=None,
220+
add_function=None,
221+
entry_points=None,
222+
export_decls=False,
223+
):
211224
"""
212225
Main function to generate header files from YAML and .h.def templates.
213226
@@ -216,41 +229,50 @@ def main(yaml_file, h_def_file, output_dir, add_function=None):
216229
h_def_file: Path to the .h.def template file.
217230
output_dir: Directory to output the generated header file.
218231
add_function: Details of the function to be added to the YAML file (if any).
232+
entry_points: A list of specific function names to include in the header.
233+
export_decls: Flag to use GpuHeader for exporting declarations.
219234
"""
220-
221235
if add_function:
222236
add_function_to_yaml(yaml_file, add_function)
223237

224-
header = load_yaml_file(yaml_file)
225-
226-
with open(h_def_file, "r") as f:
227-
h_def_content = f.read()
238+
header_class = GpuHeader if export_decls else HeaderFile
239+
header = load_yaml_file(yaml_file, header_class, entry_points)
228240

229241
header_str = str(header)
230-
final_header_content = fill_public_api(header_str, h_def_content)
231242

232-
output_file_name = Path(h_def_file).stem
233-
output_file_path = Path(output_dir) / output_file_name
234-
235-
with open(output_file_path, "w") as f:
236-
f.write(final_header_content)
243+
if output_dir:
244+
output_file_path = Path(output_dir)
245+
if output_file_path.is_dir():
246+
output_file_path /= f"{Path(yaml_file).stem}.h"
247+
else:
248+
output_file_path = Path(f"{Path(yaml_file).stem}.h")
249+
250+
if not export_decls and h_def_file:
251+
with open(h_def_file, "r") as f:
252+
h_def_content = f.read()
253+
final_header_content = fill_public_api(header_str, h_def_content)
254+
with open(output_file_path, "w") as f:
255+
f.write(final_header_content)
256+
else:
257+
with open(output_file_path, "w") as f:
258+
f.write(header_str)
237259

238260
print(f"Generated header file: {output_file_path}")
239261

240262

241263
if __name__ == "__main__":
242-
parser = argparse.ArgumentParser(
243-
description="Generate header files from YAML and .h.def templates"
244-
)
264+
parser = argparse.ArgumentParser(description="Generate header files from YAML")
245265
parser.add_argument(
246266
"yaml_file", help="Path to the YAML file containing header specification"
247267
)
248-
parser.add_argument("h_def_file", help="Path to the .h.def template file")
249268
parser.add_argument(
250269
"--output_dir",
251-
default=".",
252270
help="Directory to output the generated header file",
253271
)
272+
parser.add_argument(
273+
"--h_def_file",
274+
help="Path to the .h.def template file (required if not using --export_decls)",
275+
)
254276
parser.add_argument(
255277
"--add_function",
256278
nargs=6,
@@ -264,6 +286,21 @@ def main(yaml_file, h_def_file, output_dir, add_function=None):
264286
),
265287
help="Add a function to the YAML file",
266288
)
289+
parser.add_argument(
290+
"--e", action="append", help="Entry point to include", dest="entry_points"
291+
)
292+
parser.add_argument(
293+
"--export-decls",
294+
action="store_true",
295+
help="Flag to use GpuHeader for exporting declarations",
296+
)
267297
args = parser.parse_args()
268298

269-
main(args.yaml_file, args.h_def_file, args.output_dir, args.add_function)
299+
main(
300+
args.yaml_file,
301+
args.output_dir,
302+
args.h_def_file,
303+
args.add_function,
304+
args.entry_points,
305+
args.export_decls,
306+
)

0 commit comments

Comments
 (0)