diff --git a/libc/newhdrgen/class_implementation/classes/function.py b/libc/newhdrgen/class_implementation/classes/function.py index ea5e8223a538ef..ccfd93547c1d8a 100644 --- a/libc/newhdrgen/class_implementation/classes/function.py +++ b/libc/newhdrgen/class_implementation/classes/function.py @@ -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 diff --git a/libc/newhdrgen/gpu_headers.py b/libc/newhdrgen/gpu_headers.py new file mode 100644 index 00000000000000..cc13096cd47c11 --- /dev/null +++ b/libc/newhdrgen/gpu_headers.py @@ -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) diff --git a/libc/newhdrgen/header.py b/libc/newhdrgen/header.py index ac45bae7c933e2..69de81eebb7198 100644 --- a/libc/newhdrgen/header.py +++ b/libc/newhdrgen/header.py @@ -60,16 +60,16 @@ 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() @@ -77,12 +77,12 @@ def __str__(self): 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)) diff --git a/libc/newhdrgen/yaml/features.yaml b/libc/newhdrgen/yaml/features.yaml new file mode 100644 index 00000000000000..86bc0acfe89ed2 --- /dev/null +++ b/libc/newhdrgen/yaml/features.yaml @@ -0,0 +1,8 @@ +header: features.h +standards: + - stdc +macros: [] +types: [] +enums: [] +objects: [] +functions: [] diff --git a/libc/newhdrgen/yaml/pthread.yaml b/libc/newhdrgen/yaml/pthread.yaml index 14a562082d5deb..f22767eb1b752e 100644 --- a/libc/newhdrgen/yaml/pthread.yaml +++ b/libc/newhdrgen/yaml/pthread.yaml @@ -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: @@ -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 diff --git a/libc/newhdrgen/yaml/sys/sys_random.yaml b/libc/newhdrgen/yaml/sys/sys_random.yaml index 233fb2c7988cb9..6d84056d7dd71d 100644 --- a/libc/newhdrgen/yaml/sys/sys_random.yaml +++ b/libc/newhdrgen/yaml/sys/sys_random.yaml @@ -4,7 +4,7 @@ types: - type_name: ssize_t - type_name: size_t enums: [] -objects: +objects: [] functions: - name: getrandom standards: diff --git a/libc/newhdrgen/yaml/time.yaml b/libc/newhdrgen/yaml/time.yaml index e7f8de65eeb754..220d4328dbbdbb 100644 --- a/libc/newhdrgen/yaml/time.yaml +++ b/libc/newhdrgen/yaml/time.yaml @@ -15,7 +15,7 @@ functions: - stdc return_type: char * arguments: - - type: struct tm * + - type: const struct tm * - name: asctime_r standard: - stdc diff --git a/libc/newhdrgen/yaml_to_classes.py b/libc/newhdrgen/yaml_to_classes.py index 6bccda8e036409..205bb35fe691a6 100644 --- a/libc/newhdrgen/yaml_to_classes.py +++ b/libc/newhdrgen/yaml_to_classes.py @@ -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 @@ -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"])) @@ -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) @@ -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): @@ -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. @@ -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, @@ -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, + )