[libc-commits] [libc] f1c957d - [libc] newheadergen: script adjusted for cmake (#98825)

via libc-commits libc-commits at lists.llvm.org
Tue Jul 16 12:44:11 PDT 2024


Author: aaryanshukla
Date: 2024-07-16T12:44:08-07:00
New Revision: f1c957d41bbb07c917cd36762bd6434e7d3daf95

URL: https://github.com/llvm/llvm-project/commit/f1c957d41bbb07c917cd36762bd6434e7d3daf95
DIFF: https://github.com/llvm/llvm-project/commit/f1c957d41bbb07c917cd36762bd6434e7d3daf95.diff

LOG: [libc] newheadergen: script adjusted for cmake (#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

Added: 
    libc/newhdrgen/gpu_headers.py
    libc/newhdrgen/yaml/features.yaml

Modified: 
    libc/newhdrgen/class_implementation/classes/function.py
    libc/newhdrgen/header.py
    libc/newhdrgen/yaml/pthread.yaml
    libc/newhdrgen/yaml/sys/sys_random.yaml
    libc/newhdrgen/yaml/time.yaml
    libc/newhdrgen/yaml_to_classes.py

Removed: 
    


################################################################################
diff  --git a/libc/newhdrgen/class_implementation/classes/function.py b/libc/newhdrgen/class_implementation/classes/function.py
index ea5e8223a538e..ccfd93547c1d8 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 0000000000000..cc13096cd47c1
--- /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 ac45bae7c933e..69de81eebb719 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 0000000000000..86bc0acfe89ed
--- /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 14a562082d5de..f22767eb1b752 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 233fb2c7988cb..6d84056d7dd71 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 e7f8de65eeb75..220d4328dbbdb 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 6bccda8e03640..205bb35fe691a 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,
+    )


        


More information about the libc-commits mailing list