[libc-commits] [libc] [libc][hdrgen] Extend guard attribute support for types (PR #189803)
via libc-commits
libc-commits at lists.llvm.org
Tue Mar 31 23:23:55 PDT 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-libc
Author: pixl (un-pixelated)
<details>
<summary>Changes</summary>
Closes #<!-- -->187404
- Add guard field to Type class
- Parse guard from yaml in yaml_to_classes.py
- Emit #ifdef/#endif for guarded types in include_lines()
- Validate that guard macros have macro_header in same yaml file
- Add integration tests for type guarding
---
Full diff: https://github.com/llvm/llvm-project/pull/189803.diff
9 Files Affected:
- (modified) libc/utils/hdrgen/hdrgen/header.py (+34-2)
- (modified) libc/utils/hdrgen/hdrgen/type.py (+3-2)
- (modified) libc/utils/hdrgen/hdrgen/yaml_to_classes.py (+15-1)
- (added) libc/utils/hdrgen/tests/expected_output/type_guarding.h (+22)
- (added) libc/utils/hdrgen/tests/expected_output/type_guarding_mixed.h (+27)
- (added) libc/utils/hdrgen/tests/input/type_guarding.yaml (+15)
- (added) libc/utils/hdrgen/tests/input/type_guarding_invalid_macro.yaml (+17)
- (added) libc/utils/hdrgen/tests/input/type_guarding_mixed.yaml (+19)
- (modified) libc/utils/hdrgen/tests/test_integration.py (+21)
``````````diff
diff --git a/libc/utils/hdrgen/hdrgen/header.py b/libc/utils/hdrgen/hdrgen/header.py
index e2ebbdb6e519a..a5708fd284b0d 100644
--- a/libc/utils/hdrgen/hdrgen/header.py
+++ b/libc/utils/hdrgen/hdrgen/header.py
@@ -10,7 +10,6 @@
from functools import reduce
from pathlib import PurePosixPath
-
STDINT_SIZES = [
"16",
"32",
@@ -175,6 +174,7 @@ def includes(self):
PurePosixPath("llvm-libc-types") / f"{typ.name}.h",
)
for typ in self.all_types()
+ if typ.guard is None
}
| {
PurePosixPath("llvm-libc-macros") / f"{attr.split('(')[0]}.h"
@@ -239,7 +239,7 @@ def relpath(file):
# It's implicitly emitted here when using the default template so
# it can get the right relative path. Custom template files should
# all have it explicitly with their right particular relative path.
- return [
+ content = [
f"#include {file}"
for file in ([f'"{relpath(COMMON_HEADER)!s}"'] if with_common else [])
+ sorted(
@@ -248,6 +248,38 @@ def relpath(file):
)
]
+ # Add guarded types
+ append_blank_line_if_guarded_types_exist = True
+ current_guard = None
+ for typ in sorted(self.types):
+ path = COMPILER_HEADER_TYPES.get(
+ typ.name,
+ PurePosixPath("llvm-libc-types") / f"{typ.name}.h",
+ )
+ if append_blank_line_if_guarded_types_exist and typ.guard is not None:
+ append_blank_line_if_guarded_types_exist = False
+ content.append("")
+ if typ.guard is None:
+ continue
+ if current_guard is None:
+ current_guard = typ.guard
+ content.append(f"#ifdef {current_guard}")
+ content.append(f'#include "{relpath(path)!s}"')
+ elif current_guard == typ.guard:
+ content.append(f'#include "{relpath(path)!s}"')
+ else:
+ content.append(f"#endif // {current_guard}")
+ content.append("")
+ current_guard = typ.guard
+ if current_guard is not None:
+ content.append(f"#ifdef {current_guard}")
+ content.append(f'#include "{relpath(path)!s}"')
+ if current_guard is not None:
+ content.append(f"#endif // {current_guard}")
+ content.append("")
+
+ return content
+
def macro_lines(self):
content = []
for macro in sorted(self.macros):
diff --git a/libc/utils/hdrgen/hdrgen/type.py b/libc/utils/hdrgen/hdrgen/type.py
index 20c1881a9379a..4ea5c31c8f1f3 100644
--- a/libc/utils/hdrgen/hdrgen/type.py
+++ b/libc/utils/hdrgen/hdrgen/type.py
@@ -10,6 +10,7 @@
class Type(Symbol):
- # A type so far carries no specific information beyond its name.
- def __init__(self, name):
+ # A type carries its name and guard.
+ def __init__(self, name, guard=None):
super().__init__(name)
+ self.guard = guard
diff --git a/libc/utils/hdrgen/hdrgen/yaml_to_classes.py b/libc/utils/hdrgen/hdrgen/yaml_to_classes.py
index 85aa3267b5274..d174a1b4c4307 100644
--- a/libc/utils/hdrgen/hdrgen/yaml_to_classes.py
+++ b/libc/utils/hdrgen/hdrgen/yaml_to_classes.py
@@ -52,7 +52,21 @@ def yaml_to_classes(yaml_data, header_class, entry_points=None):
types = yaml_data.get("types", [])
sorted_types = sorted(types, key=lambda x: x["type_name"])
for type_data in sorted_types:
- header.add_type(Type(type_data["type_name"]))
+ type_name = type_data["type_name"]
+ type_guard = type_data.get("guard")
+ # If a type has a guard, the macro it references must exist in
+ # the same yaml file with a macro_header attribute.
+ if type_guard is not None and not any(
+ macro_data["macro_name"] == type_guard
+ and macro_data.get("macro_header") is not None
+ for macro_data in yaml_data.get("macros", [])
+ ):
+ raise ValueError(
+ f"Type '{type_name}' has guard '{type_guard}' but no macro with "
+ f"macro_header '{type_guard}' was found in this file."
+ )
+
+ header.add_type(Type(type_name, type_guard))
for enum_data in yaml_data.get("enums", []):
header.add_enumeration(
diff --git a/libc/utils/hdrgen/tests/expected_output/type_guarding.h b/libc/utils/hdrgen/tests/expected_output/type_guarding.h
new file mode 100644
index 0000000000000..b01dbea891231
--- /dev/null
+++ b/libc/utils/hdrgen/tests/expected_output/type_guarding.h
@@ -0,0 +1,22 @@
+//===-- Standard C header <type_guarding.h> --===//
+//
+// 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
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LLVM_LIBC_TYPE_GUARDING_H
+#define _LLVM_LIBC_TYPE_GUARDING_H
+
+#include "__llvm-libc-common.h"
+#include "llvm-libc-macros/size_t-macro.h"
+#include "llvm-libc-types/myType.h"
+#include <stdint.h>
+
+#ifdef LIBC_TYPES_HAS_SIZE_T
+#include "llvm-libc-types/size_t.h"
+#include "llvm-libc-types/ssize_t.h"
+#endif // LIBC_TYPES_HAS_SIZE_T
+
+#endif // _LLVM_LIBC_TYPE_GUARDING_H
diff --git a/libc/utils/hdrgen/tests/expected_output/type_guarding_mixed.h b/libc/utils/hdrgen/tests/expected_output/type_guarding_mixed.h
new file mode 100644
index 0000000000000..33a6fbd22d8d0
--- /dev/null
+++ b/libc/utils/hdrgen/tests/expected_output/type_guarding_mixed.h
@@ -0,0 +1,27 @@
+//===-- Standard C header <type_guarding_mixed.h> --===//
+//
+// 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
+//
+//===---------------------------------------------------------------------===//
+
+#ifndef _LLVM_LIBC_TYPE_GUARDING_MIXED_H
+#define _LLVM_LIBC_TYPE_GUARDING_MIXED_H
+
+#include "__llvm-libc-common.h"
+#include "llvm-libc-macros/float16-macro.h"
+#include "llvm-libc-macros/size_t-macro.h"
+#include "llvm-libc-types/myType.h"
+#include <stdint.h>
+
+#ifdef LIBC_TYPES_HAS_FLOAT16
+#include "llvm-libc-types/float16.h"
+#endif // LIBC_TYPES_HAS_FLOAT16
+
+#ifdef LIBC_TYPES_HAS_SIZE_T
+#include "llvm-libc-types/size_t.h"
+#include "llvm-libc-types/ssize_t.h"
+#endif // LIBC_TYPES_HAS_SIZE_T
+
+#endif // _LLVM_LIBC_TYPE_GUARDING_MIXED_H
diff --git a/libc/utils/hdrgen/tests/input/type_guarding.yaml b/libc/utils/hdrgen/tests/input/type_guarding.yaml
new file mode 100644
index 0000000000000..79ddfe4bad151
--- /dev/null
+++ b/libc/utils/hdrgen/tests/input/type_guarding.yaml
@@ -0,0 +1,15 @@
+header: type_guarding.h
+standards:
+ - stdc
+
+macros:
+ - macro_name: LIBC_TYPES_HAS_SIZE_T
+ macro_header: size_t-macro.h
+
+types:
+ - type_name: size_t
+ guard: LIBC_TYPES_HAS_SIZE_T
+ - type_name: ssize_t
+ guard: LIBC_TYPES_HAS_SIZE_T
+ - type_name: uint8_t
+ - type_name: myType
diff --git a/libc/utils/hdrgen/tests/input/type_guarding_invalid_macro.yaml b/libc/utils/hdrgen/tests/input/type_guarding_invalid_macro.yaml
new file mode 100644
index 0000000000000..daf43a90b29bf
--- /dev/null
+++ b/libc/utils/hdrgen/tests/input/type_guarding_invalid_macro.yaml
@@ -0,0 +1,17 @@
+header: type_guarding_invalid_macro.h
+standards:
+ - stdc
+
+macros:
+ - macro_name: LIBC_TYPES_HAS_SIZE_T
+ macro_header: size_t-macro.h
+ - macro_name: MY_TYPES_GUARD
+
+types:
+ - type_name: size_t
+ guard: LIBC_TYPES_HAS_SIZE_T
+ - type_name: ssize_t
+ guard: LIBC_TYPES_HAS_SIZE_T
+ - type_name: uint8_t
+ - type_name: myType
+ guard: MY_TYPES_GUARD
diff --git a/libc/utils/hdrgen/tests/input/type_guarding_mixed.yaml b/libc/utils/hdrgen/tests/input/type_guarding_mixed.yaml
new file mode 100644
index 0000000000000..b1e7fb14e5d3b
--- /dev/null
+++ b/libc/utils/hdrgen/tests/input/type_guarding_mixed.yaml
@@ -0,0 +1,19 @@
+header: type_guarding_mixed.h
+standards:
+ - stdc
+
+macros:
+ - macro_name: LIBC_TYPES_HAS_SIZE_T
+ macro_header: size_t-macro.h
+ - macro_name: LIBC_TYPES_HAS_FLOAT16
+ macro_header: float16-macro.h
+
+types:
+ - type_name: size_t
+ guard: LIBC_TYPES_HAS_SIZE_T
+ - type_name: ssize_t
+ guard: LIBC_TYPES_HAS_SIZE_T
+ - type_name: float16
+ guard: LIBC_TYPES_HAS_FLOAT16
+ - type_name: uint8_t
+ - type_name: myType
diff --git a/libc/utils/hdrgen/tests/test_integration.py b/libc/utils/hdrgen/tests/test_integration.py
index 8848afe29d50f..9a87a5831f900 100644
--- a/libc/utils/hdrgen/tests/test_integration.py
+++ b/libc/utils/hdrgen/tests/test_integration.py
@@ -96,6 +96,27 @@ def test_generate_macro_only_header(self):
self.run_script(yaml_file, output_file)
self.compare_files(output_file, expected_output_file)
+ def test_type_guarding(self):
+ yaml_file = self.source_dir / "input/type_guarding.yaml"
+ expected_output_file = self.source_dir / "expected_output/type_guarding.h"
+ output_file = self.output_dir / "type_guarding.h"
+ self.run_script(yaml_file, output_file)
+ self.compare_files(output_file, expected_output_file)
+
+ def test_type_guarding_mixed(self):
+ yaml_file = self.source_dir / "input/type_guarding_mixed.yaml"
+ expected_output_file = self.source_dir / "expected_output/type_guarding_mixed.h"
+ output_file = self.output_dir / "type_guarding_mixed.h"
+ self.run_script(yaml_file, output_file)
+ self.compare_files(output_file, expected_output_file)
+
+ def test_type_guarding_invalid_macro(self):
+ yaml_file = self.source_dir / "input/type_guarding_invalid_macro.yaml"
+ output_file = self.output_dir / "type_guarding_invalid_macro.h"
+ with self.assertRaises(subprocess.CalledProcessError):
+ self.run_script(yaml_file, output_file)
+
+
def main():
parser = argparse.ArgumentParser(description="TestHeaderGenIntegration arguments")
parser.add_argument(
``````````
</details>
https://github.com/llvm/llvm-project/pull/189803
More information about the libc-commits
mailing list