From 6fa2c2bb30b257d2b6fbda0b495c2a7cb300b6b8 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 16 Jan 2025 17:28:32 -0800 Subject: [PATCH 1/4] [libc] Make hdrgen support macro_header YAML field. A macro can specify macro_header instead of macro_value to indicate that an llvm-libc-macros/ header file is supposed to define this macro. This is used for dlfcn.h, which previously bogusly redefined the RTLD_* macros to empty. --- libc/include/dlfcn.yaml | 8 +++---- libc/utils/hdrgen/gpu_headers.py | 1 + libc/utils/hdrgen/header.py | 24 ++++++++++++++----- libc/utils/hdrgen/macro.py | 10 +++++--- .../tests/expected_output/test_header.h | 14 ++++++++++- .../utils/hdrgen/tests/input/test_small.h.def | 1 - libc/utils/hdrgen/tests/input/test_small.yaml | 5 ++++ libc/utils/hdrgen/tests/test_integration.py | 1 + libc/utils/hdrgen/yaml_to_classes.py | 8 ++++++- 9 files changed, 56 insertions(+), 16 deletions(-) diff --git a/libc/include/dlfcn.yaml b/libc/include/dlfcn.yaml index 9e8803cb5fa78..78bbeff4e60d9 100644 --- a/libc/include/dlfcn.yaml +++ b/libc/include/dlfcn.yaml @@ -2,13 +2,13 @@ header: dlfcn.h header_template: dlfcn.h.def macros: - macro_name: RTLD_LAZY - macro_value: null + macro_header: dlfcn-macros.h - macro_name: RTLD_NOW - macro_value: null + macro_header: dlfcn-macros.h - macro_name: RTLD_GLOBAL - macro_value: null + macro_header: dlfcn-macros.h - macro_name: RTLD_LOCAL - macro_value: null + macro_header: dlfcn-macros.h types: [] enums: [] objects: [] diff --git a/libc/utils/hdrgen/gpu_headers.py b/libc/utils/hdrgen/gpu_headers.py index 8c4ff6e08b112..505adfa8fee8a 100644 --- a/libc/utils/hdrgen/gpu_headers.py +++ b/libc/utils/hdrgen/gpu_headers.py @@ -8,6 +8,7 @@ from header import HeaderFile + class GpuHeaderFile(HeaderFile): def __str__(self): content = [] diff --git a/libc/utils/hdrgen/header.py b/libc/utils/hdrgen/header.py index 9339acceaf7a9..7e14e768de2bb 100644 --- a/libc/utils/hdrgen/header.py +++ b/libc/utils/hdrgen/header.py @@ -6,6 +6,8 @@ # # ==-------------------------------------------------------------------------==# +from pathlib import PurePath + class HeaderFile: def __init__(self, name): @@ -32,8 +34,20 @@ def add_object(self, object): def add_function(self, function): self.functions.append(function) + def includes(self): + return sorted( + { + PurePath("llvm-libc-macros") / macro.header + for macro in self.macros + if macro.header is not None + } + ) + def public_api(self): - content = [""] + header_dir = PurePath(self.name).parent + content = [ + f'#include "{file.relative_to(header_dir)}"' for file in self.includes() + ] + [""] for macro in self.macros: content.append(f"{macro}\n") @@ -76,11 +90,9 @@ def public_api(self): content.append(f"#endif // {current_guard}") content.append("") - for object in self.objects: - content.append(str(object)) + content.extend(str(object) for object in self.objects) if self.objects: - content.append("\n__END_C_DECLS") - else: - content.append("__END_C_DECLS") + content.append("") + content.append("__END_C_DECLS") return "\n".join(content) diff --git a/libc/utils/hdrgen/macro.py b/libc/utils/hdrgen/macro.py index 9a712f2a1c743..e1eb678f7a832 100644 --- a/libc/utils/hdrgen/macro.py +++ b/libc/utils/hdrgen/macro.py @@ -8,12 +8,16 @@ class Macro: - def __init__(self, name, value=None): + def __init__(self, name, value=None, header=None): self.name = name self.value = value + self.header = header def __str__(self): + if self.header != None: + return f"""#ifndef {self.name} +#error "{self.name} should be defined by llvm-libc-macros/{self.header}" +#endif""" if self.value != None: return f"#define {self.name} {self.value}" - else: - return f"#define {self.name}" + return f"#define {self.name}" diff --git a/libc/utils/hdrgen/tests/expected_output/test_header.h b/libc/utils/hdrgen/tests/expected_output/test_header.h index a777976134b04..97870df58d0e8 100644 --- a/libc/utils/hdrgen/tests/expected_output/test_header.h +++ b/libc/utils/hdrgen/tests/expected_output/test_header.h @@ -11,13 +11,25 @@ #include "__llvm-libc-common.h" #include "llvm-libc-macros/float16-macros.h" -#include "llvm-libc-macros/test_small-macros.h" #include "llvm-libc-types/float128.h" +#include "llvm-libc-macros/test_more-macros.h" +#include "llvm-libc-macros/test_small-macros.h" + #define MACRO_A 1 #define MACRO_B 2 +#define MACRO_C + +#ifndef MACRO_D +#error "MACRO_D should be defined by llvm-libc-macros/test_small-macros.h" +#endif + +#ifndef MACRO_E +#error "MACRO_E should be defined by llvm-libc-macros/test_more-macros.h" +#endif + #include #include diff --git a/libc/utils/hdrgen/tests/input/test_small.h.def b/libc/utils/hdrgen/tests/input/test_small.h.def index 075be957b8136..587b163b68d96 100644 --- a/libc/utils/hdrgen/tests/input/test_small.h.def +++ b/libc/utils/hdrgen/tests/input/test_small.h.def @@ -11,7 +11,6 @@ #include "__llvm-libc-common.h" #include "llvm-libc-macros/float16-macros.h" -#include "llvm-libc-macros/test_small-macros.h" #include "llvm-libc-types/float128.h" %%public_api() diff --git a/libc/utils/hdrgen/tests/input/test_small.yaml b/libc/utils/hdrgen/tests/input/test_small.yaml index 1d4b2990a3002..d5bb2bbfe4468 100644 --- a/libc/utils/hdrgen/tests/input/test_small.yaml +++ b/libc/utils/hdrgen/tests/input/test_small.yaml @@ -5,6 +5,11 @@ macros: macro_value: 1 - macro_name: MACRO_B macro_value: 2 + - macro_name: MACRO_C + - macro_name: MACRO_D + macro_header: test_small-macros.h + - macro_name: MACRO_E + macro_header: test_more-macros.h types: - type_name: type_a - type_name: type_b diff --git a/libc/utils/hdrgen/tests/test_integration.py b/libc/utils/hdrgen/tests/test_integration.py index 49cb08cd1b339..110a218fbde8f 100644 --- a/libc/utils/hdrgen/tests/test_integration.py +++ b/libc/utils/hdrgen/tests/test_integration.py @@ -10,6 +10,7 @@ def setUp(self): self.output_dir = TestHeaderGenIntegration.output_dir self.source_dir = Path(__file__).parent self.main_script = self.source_dir.parent / "main.py" + self.maxDiff = 80*100 def run_script(self, yaml_file, output_file, entry_points): command = [ diff --git a/libc/utils/hdrgen/yaml_to_classes.py b/libc/utils/hdrgen/yaml_to_classes.py index d64feafc260b7..4a3f48633dc1d 100644 --- a/libc/utils/hdrgen/yaml_to_classes.py +++ b/libc/utils/hdrgen/yaml_to_classes.py @@ -38,7 +38,13 @@ def yaml_to_classes(yaml_data, header_class, entry_points=None): header.template_file = yaml_data.get("header_template") for macro_data in yaml_data.get("macros", []): - header.add_macro(Macro(macro_data["macro_name"], macro_data["macro_value"])) + header.add_macro( + Macro( + macro_data["macro_name"], + macro_data.get("macro_value"), + macro_data.get("macro_header"), + ) + ) types = yaml_data.get("types", []) sorted_types = sorted(types, key=lambda x: x["type_name"]) From 60a72b4864eab74656ad2d32513b1945bec3094b Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 16 Jan 2025 17:40:34 -0800 Subject: [PATCH 2/4] reformat python --- libc/utils/hdrgen/tests/test_integration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libc/utils/hdrgen/tests/test_integration.py b/libc/utils/hdrgen/tests/test_integration.py index 110a218fbde8f..7789c9c0a1316 100644 --- a/libc/utils/hdrgen/tests/test_integration.py +++ b/libc/utils/hdrgen/tests/test_integration.py @@ -10,7 +10,7 @@ def setUp(self): self.output_dir = TestHeaderGenIntegration.output_dir self.source_dir = Path(__file__).parent self.main_script = self.source_dir.parent / "main.py" - self.maxDiff = 80*100 + self.maxDiff = 80 * 100 def run_script(self, yaml_file, output_file, entry_points): command = [ From 03f18c87c147a0cb18ec21224c5dc3e09329c263 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 13 Feb 2025 12:08:30 -0800 Subject: [PATCH 3/4] Remove #ifndef self-test from generated headers --- libc/utils/hdrgen/header.py | 3 ++- libc/utils/hdrgen/macro.py | 4 +--- libc/utils/hdrgen/tests/expected_output/test_header.h | 8 -------- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/libc/utils/hdrgen/header.py b/libc/utils/hdrgen/header.py index 7e14e768de2bb..35ec8a7d81476 100644 --- a/libc/utils/hdrgen/header.py +++ b/libc/utils/hdrgen/header.py @@ -50,7 +50,8 @@ def public_api(self): ] + [""] for macro in self.macros: - content.append(f"{macro}\n") + if str(macro): + content.append(f"{macro}\n") for type_ in self.types: content.append(f"{type_}") diff --git a/libc/utils/hdrgen/macro.py b/libc/utils/hdrgen/macro.py index e1eb678f7a832..19c2b318b8f77 100644 --- a/libc/utils/hdrgen/macro.py +++ b/libc/utils/hdrgen/macro.py @@ -15,9 +15,7 @@ def __init__(self, name, value=None, header=None): def __str__(self): if self.header != None: - return f"""#ifndef {self.name} -#error "{self.name} should be defined by llvm-libc-macros/{self.header}" -#endif""" + return "" if self.value != None: return f"#define {self.name} {self.value}" return f"#define {self.name}" diff --git a/libc/utils/hdrgen/tests/expected_output/test_header.h b/libc/utils/hdrgen/tests/expected_output/test_header.h index 01a6af512da99..ca9439982d66b 100644 --- a/libc/utils/hdrgen/tests/expected_output/test_header.h +++ b/libc/utils/hdrgen/tests/expected_output/test_header.h @@ -22,14 +22,6 @@ #define MACRO_C -#ifndef MACRO_D -#error "MACRO_D should be defined by llvm-libc-macros/test_small-macros.h" -#endif - -#ifndef MACRO_E -#error "MACRO_E should be defined by llvm-libc-macros/test_more-macros.h" -#endif - #include #include From 39fe98e4d76a518be464d9d6813824d89dafb2c7 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Thu, 13 Feb 2025 13:50:05 -0800 Subject: [PATCH 4/4] Add comment wrt Macro.__str__ use --- libc/utils/hdrgen/header.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libc/utils/hdrgen/header.py b/libc/utils/hdrgen/header.py index 35ec8a7d81476..85d3c54892f89 100644 --- a/libc/utils/hdrgen/header.py +++ b/libc/utils/hdrgen/header.py @@ -50,6 +50,8 @@ def public_api(self): ] + [""] for macro in self.macros: + # When there is nothing to define, the Macro object converts to str + # as an empty string. Don't emit a blank line for those cases. if str(macro): content.append(f"{macro}\n")