Skip to content

Commit

Permalink
[libc] newheadergen: script adjusted for cmake (llvm#98825)
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
aaryanshukla authored and RoseZhang03 committed Jul 16, 2024
1 parent ce5d7e7 commit 37c21f1
Show file tree
Hide file tree
Showing 8 changed files with 162 additions and 64 deletions.
4 changes: 2 additions & 2 deletions libc/newhdrgen/class_implementation/classes/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def __str__(self):
attributes_str = " ".join(self.attributes)
arguments_str = ", ".join(self.arguments)
if attributes_str == "":
result = f"{self.return_type} {self.name}({arguments_str}) __NOEXCEPT;"
result = f"{self.return_type} {self.name}({arguments_str});"
else:
result = f"{attributes_str} {self.return_type} {self.name}({arguments_str}) __NOEXCEPT;"
result = f"{attributes_str} {self.return_type} {self.name}({arguments_str})"
return result
78 changes: 78 additions & 0 deletions libc/newhdrgen/gpu_headers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#!/usr/bin/env python
#
# ===- GPU HeaderFile Class for --export-decls version --------*- python -*--==#
#
# 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
#
# ==-------------------------------------------------------------------------==#


class GpuHeaderFile:
def __init__(self, name):
self.name = name
self.macros = []
self.types = []
self.enumerations = []
self.objects = []
self.functions = []
self.includes = []

def add_macro(self, macro):
self.macros.append(macro)

def add_type(self, type_):
self.types.append(type_)

def add_enumeration(self, enumeration):
self.enumerations.append(enumeration)

def add_object(self, object):
self.objects.append(object)

def add_function(self, function):
self.functions.append(function)

def __str__(self):
content = []

content.append(
f"//===-- C standard declarations for {self.name} ------------------------------===//"
)
content.append("//")
content.append(
"// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions."
)
content.append("// See https://llvm.org/LICENSE.txt for license information.")
content.append("// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception")
content.append("//")
content.append(
"//===----------------------------------------------------------------------===//\n"
)

header_guard = f"__LLVM_LIBC_DECLARATIONS_{self.name.upper()[:-2]}_H"
content.append(f"#ifndef {header_guard}")
content.append(f"#define {header_guard}\n")

content.append("#ifndef __LIBC_ATTRS")
content.append("#define __LIBC_ATTRS")
content.append("#endif\n")

content.append("#ifdef __cplusplus")
content.append('extern "C" {')
content.append("#endif\n")

for function in self.functions:
content.append(f"{function} __LIBC_ATTRS;\n")

for object in self.objects:
content.append(f"{object} __LIBC_ATTRS;\n")

content.append("#ifdef __cplusplus")
content.append("}")
content.append("#endif\n")

content.append(f"#endif")

return "\n".join(content)
10 changes: 5 additions & 5 deletions libc/newhdrgen/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,29 +60,29 @@ def __str__(self):
current_guard = None
for function in self.functions:
if function.guard == None:
content.append(str(function))
content.append(str(function) + "__NOEXCEPT")
content.append("")
else:
if current_guard == None:
current_guard = function.guard
content.append(f"#ifdef {current_guard}")
content.append(str(function))
content.append(str(function) + "__NOEXCEPT")
content.append("")
elif current_guard == function.guard:
content.append(str(function))
content.append(str(function) + "__NOEXCEPT")
content.append("")
else:
content.pop()
content.append(f"#endif // {current_guard}")
content.append("")
current_guard = function.guard
content.append(f"#ifdef {current_guard}")
content.append(str(function))
content.append(str(function) + "__NOEXCEPT")
content.append("")
if current_guard != None:
content.pop()
content.append(f"#endif // {current_guard}")
content.append("")
content.append("")

for object in self.objects:
content.append(str(object))
Expand Down
8 changes: 8 additions & 0 deletions libc/newhdrgen/yaml/features.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
header: features.h
standards:
- stdc
macros: []
types: []
enums: []
objects: []
functions: []
31 changes: 3 additions & 28 deletions libc/newhdrgen/yaml/pthread.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,33 +13,8 @@ types:
- type_name: __pthread_start_t
- type_name: __pthread_once_func_t
- type_name: __atfork_callback_t
enums:
- name: PTHREAD_CREATE_JOINABLE
value: 0x0
- name: PTHREAD_CREATE_DETACHED
value: 0x1
- name: PTHREAD_MUTEX_NORMAL
value: 0x0
- name: PTHREAD_MUTEX_ERRORCHECK
value: 0x1
- name: PTHREAD_MUTEX_RECURSIVE
value: 0x2
- name: PTHREAD_MUTEX_DEFAULT
value: 0x0
- name: PTHREAD_PROCESS_PRIVATE
value: 0x0
- name: PTHREAD_PROCESS_SHARED
value: 0x1
- name: PTHREAD_MUTEX_STALLED
value: 0x0
- name: PTHREAD_MUTEX_ROBUST
value: 0x1
- name: PTHREAD_RWLOCK_PREFER_READER_NP
value: 0
- name: PTHREAD_RWLOCK_PREFER_WRITER_NP
value: 1
- name: PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
value: 2
- type_name: pthread_rwlock_t
enums: []
functions:
- name: pthread_atfork
standards:
Expand Down Expand Up @@ -184,7 +159,7 @@ functions:
- name: pthread_exit
standards:
- POSIX
return_type: __Noreturn void
return_type: _Noreturn void
arguments:
- type: void *
- name: pthread_getname_np
Expand Down
2 changes: 1 addition & 1 deletion libc/newhdrgen/yaml/sys/sys_random.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ types:
- type_name: ssize_t
- type_name: size_t
enums: []
objects:
objects: []
functions:
- name: getrandom
standards:
Expand Down
2 changes: 1 addition & 1 deletion libc/newhdrgen/yaml/time.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ functions:
- stdc
return_type: char *
arguments:
- type: struct tm *
- type: const struct tm *
- name: asctime_r
standard:
- stdc
Expand Down
91 changes: 64 additions & 27 deletions libc/newhdrgen/yaml_to_classes.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,11 @@
#
# ==-------------------------------------------------------------------------==#


import yaml
import argparse

from pathlib import Path
from header import HeaderFile
from gpu_headers import GpuHeaderFile as GpuHeader
from class_implementation.classes.macro import Macro
from class_implementation.classes.type import Type
from class_implementation.classes.function import Function
Expand All @@ -22,18 +21,20 @@
from class_implementation.classes.object import Object


def yaml_to_classes(yaml_data):
def yaml_to_classes(yaml_data, header_class, entry_points=None):
"""
Convert YAML data to header classes.
Args:
yaml_data: The YAML data containing header specifications.
header_class: The class to use for creating the header.
entry_points: A list of specific function names to include in the header.
Returns:
HeaderFile: An instance of HeaderFile populated with the data.
"""
header_name = yaml_data.get("header")
header = HeaderFile(header_name)
header = header_class(header_name)

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

functions = yaml_data.get("functions", [])
if entry_points:
entry_points_set = set(entry_points)
functions = [f for f in functions if f["name"] in entry_points_set]
sorted_functions = sorted(functions, key=lambda x: x["name"])
guards = []
guarded_function_dict = {}
for function_data in sorted_functions:
guard = function_data.get("guard", None)
if guard == None:
if guard is None:
arguments = [arg["type"] for arg in function_data["arguments"]]
attributes = function_data.get("attributes", None)
standards = function_data.get("standards", None)
Expand Down Expand Up @@ -105,19 +109,21 @@ def yaml_to_classes(yaml_data):
return header


def load_yaml_file(yaml_file):
def load_yaml_file(yaml_file, header_class, entry_points):
"""
Load YAML file and convert it to header classes.
Args:
yaml_file: The path to the YAML file.
yaml_file: Path to the YAML file.
header_class: The class to use for creating the header (HeaderFile or GpuHeader).
entry_points: A list of specific function names to include in the header.
Returns:
HeaderFile: An instance of HeaderFile populated with the data from the YAML file.
HeaderFile: An instance of HeaderFile populated with the data.
"""
with open(yaml_file, "r") as f:
yaml_data = yaml.safe_load(f)
return yaml_to_classes(yaml_data)
return yaml_to_classes(yaml_data, header_class, entry_points)


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


def main(yaml_file, h_def_file, output_dir, add_function=None):
def main(
yaml_file,
output_dir=None,
h_def_file=None,
add_function=None,
entry_points=None,
export_decls=False,
):
"""
Main function to generate header files from YAML and .h.def templates.
Expand All @@ -216,41 +229,50 @@ def main(yaml_file, h_def_file, output_dir, add_function=None):
h_def_file: Path to the .h.def template file.
output_dir: Directory to output the generated header file.
add_function: Details of the function to be added to the YAML file (if any).
entry_points: A list of specific function names to include in the header.
export_decls: Flag to use GpuHeader for exporting declarations.
"""

if add_function:
add_function_to_yaml(yaml_file, add_function)

header = load_yaml_file(yaml_file)

with open(h_def_file, "r") as f:
h_def_content = f.read()
header_class = GpuHeader if export_decls else HeaderFile
header = load_yaml_file(yaml_file, header_class, entry_points)

header_str = str(header)
final_header_content = fill_public_api(header_str, h_def_content)

output_file_name = Path(h_def_file).stem
output_file_path = Path(output_dir) / output_file_name

with open(output_file_path, "w") as f:
f.write(final_header_content)
if output_dir:
output_file_path = Path(output_dir)
if output_file_path.is_dir():
output_file_path /= f"{Path(yaml_file).stem}.h"
else:
output_file_path = Path(f"{Path(yaml_file).stem}.h")

if not export_decls and h_def_file:
with open(h_def_file, "r") as f:
h_def_content = f.read()
final_header_content = fill_public_api(header_str, h_def_content)
with open(output_file_path, "w") as f:
f.write(final_header_content)
else:
with open(output_file_path, "w") as f:
f.write(header_str)

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


if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="Generate header files from YAML and .h.def templates"
)
parser = argparse.ArgumentParser(description="Generate header files from YAML")
parser.add_argument(
"yaml_file", help="Path to the YAML file containing header specification"
)
parser.add_argument("h_def_file", help="Path to the .h.def template file")
parser.add_argument(
"--output_dir",
default=".",
help="Directory to output the generated header file",
)
parser.add_argument(
"--h_def_file",
help="Path to the .h.def template file (required if not using --export_decls)",
)
parser.add_argument(
"--add_function",
nargs=6,
Expand All @@ -264,6 +286,21 @@ def main(yaml_file, h_def_file, output_dir, add_function=None):
),
help="Add a function to the YAML file",
)
parser.add_argument(
"--e", action="append", help="Entry point to include", dest="entry_points"
)
parser.add_argument(
"--export-decls",
action="store_true",
help="Flag to use GpuHeader for exporting declarations",
)
args = parser.parse_args()

main(args.yaml_file, args.h_def_file, args.output_dir, args.add_function)
main(
args.yaml_file,
args.output_dir,
args.h_def_file,
args.add_function,
args.entry_points,
args.export_decls,
)

0 comments on commit 37c21f1

Please sign in to comment.