Skip to content

Commit efa5592

Browse files
author
git apple-llvm automerger
committed
Merge commit '22079e3f3698' from llvm.org/main into next
2 parents f65613e + 22079e3 commit efa5592

File tree

8 files changed

+106
-16
lines changed

8 files changed

+106
-16
lines changed

libc/utils/hdrgen/hdrgen/header.py

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,13 @@
3535

3636
COMMON_HEADER = PurePosixPath("__llvm-libc-common.h")
3737

38+
# These "attributes" are known macros defined in COMMON_HEADER.
39+
# Others are found in "llvm-libc-macros/{name}.h".
40+
COMMON_ATTRIBUTES = {
41+
"_Noreturn",
42+
"_Returns_twice",
43+
}
44+
3845
# All the canonical identifiers are in lowercase for easy maintenance.
3946
# This maps them to the pretty descriptions to generate in header comments.
4047
LIBRARY_DESCRIPTIONS = {
@@ -50,9 +57,7 @@
5057
HEADER_TEMPLATE = """\
5158
//===-- {library} header <{header}> --===//
5259
//
53-
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
54-
// See https://llvm.org/LICENSE.txt for license information.
55-
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60+
{license_lines}
5661
//
5762
//===---------------------------------------------------------------------===//
5863
@@ -64,6 +69,12 @@
6469
#endif // {guard}
6570
"""
6671

72+
LLVM_LICENSE_TEXT = [
73+
"Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.",
74+
"See https://llvm.org/LICENSE.txt for license information.",
75+
"SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception",
76+
]
77+
6778

6879
class HeaderFile:
6980
def __init__(self, name):
@@ -74,8 +85,10 @@ def __init__(self, name):
7485
self.enumerations = []
7586
self.objects = []
7687
self.functions = []
88+
self.extra_standards = {}
7789
self.standards = []
7890
self.merge_yaml_files = []
91+
self.license_text = []
7992

8093
def add_macro(self, macro):
8194
self.macros.append(macro)
@@ -98,6 +111,11 @@ def merge(self, other):
98111
self.enumerations = sorted(set(self.enumerations) | set(other.enumerations))
99112
self.objects = sorted(set(self.objects) | set(other.objects))
100113
self.functions = sorted(set(self.functions) | set(other.functions))
114+
self.extra_standards |= other.extra_standards
115+
if self.license_text:
116+
assert not other.license_text, "only one `license_text` allowed"
117+
else:
118+
self.license_text = other.license_text
101119

102120
def all_types(self):
103121
return reduce(
@@ -106,6 +124,13 @@ def all_types(self):
106124
set(self.types),
107125
)
108126

127+
def all_attributes(self):
128+
return reduce(
129+
lambda a, b: a | b,
130+
[set(f.attributes) for f in self.functions],
131+
set(),
132+
)
133+
109134
def all_standards(self):
110135
# FIXME: Only functions have the "standard" field, but all the entity
111136
# types should have one too.
@@ -114,41 +139,54 @@ def all_standards(self):
114139
)
115140

116141
def includes(self):
117-
return {
118-
PurePosixPath("llvm-libc-macros") / macro.header
119-
for macro in self.macros
120-
if macro.header is not None
121-
} | {
122-
COMPILER_HEADER_TYPES.get(
123-
typ.type_name, PurePosixPath("llvm-libc-types") / f"{typ.type_name}.h"
124-
)
125-
for typ in self.all_types()
126-
}
142+
return (
143+
{
144+
PurePosixPath("llvm-libc-macros") / macro.header
145+
for macro in self.macros
146+
if macro.header is not None
147+
}
148+
| {
149+
COMPILER_HEADER_TYPES.get(
150+
typ.type_name,
151+
PurePosixPath("llvm-libc-types") / f"{typ.type_name}.h",
152+
)
153+
for typ in self.all_types()
154+
}
155+
| {
156+
PurePosixPath("llvm-libc-macros") / f"{attr}.h"
157+
for attr in self.all_attributes() - COMMON_ATTRIBUTES
158+
}
159+
)
127160

128161
def header_guard(self):
129162
return "_LLVM_LIBC_" + "_".join(
130163
word.upper() for word in NONIDENTIFIER.split(self.name) if word
131164
)
132165

133166
def library_description(self):
167+
descriptions = LIBRARY_DESCRIPTIONS | self.extra_standards
134168
# If the header itself is in standard C, just call it that.
135169
if "stdc" in self.standards:
136-
return LIBRARY_DESCRIPTIONS["stdc"]
170+
return descriptions["stdc"]
137171
# If the header itself is in POSIX, just call it that.
138172
if "posix" in self.standards:
139-
return LIBRARY_DESCRIPTIONS["posix"]
173+
return descriptions["posix"]
140174
# Otherwise, consider the standards for each symbol as well.
141175
standards = self.all_standards()
142176
# Otherwise, it's described by all those that apply, but ignoring
143177
# "stdc" and "posix" since this is not a "stdc" or "posix" header.
144178
return " / ".join(
145179
sorted(
146-
LIBRARY_DESCRIPTIONS[standard]
180+
descriptions[standard]
147181
for standard in standards
148182
if standard not in {"stdc", "posix"}
149183
)
150184
)
151185

186+
def license_lines(self):
187+
lines = self.license_text or LLVM_LICENSE_TEXT
188+
return "\n".join([f"// {line}" for line in lines])
189+
152190
def template(self, dir, files_read):
153191
if self.template_file is not None:
154192
# There's a custom template file, so just read it in and record
@@ -162,6 +200,7 @@ def template(self, dir, files_read):
162200
library=self.library_description(),
163201
header=self.name,
164202
guard=self.header_guard(),
203+
license_lines=self.license_lines(),
165204
)
166205

167206
def public_api(self):

libc/utils/hdrgen/hdrgen/yaml_to_classes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ def yaml_to_classes(yaml_data, header_class, entry_points=None):
3737
header = header_class(header_name)
3838
header.template_file = yaml_data.get("header_template")
3939
header.standards = yaml_data.get("standards", [])
40+
header.extra_standards = yaml_data.get("extra_standards", {})
41+
header.license_text = yaml_data.get("license_text", [])
4042
header.merge_yaml_files = yaml_data.get("merge_yaml_files", [])
4143

4244
for macro_data in yaml_data.get("macros", []):
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
//===-- Wile E. Coyote header <custom.h> --===//
2+
//
3+
// Caveat emptor.
4+
// I never studied law.
5+
//
6+
//===---------------------------------------------------------------------===//
7+
8+
#ifndef _LLVM_LIBC_CUSTOM_H
9+
#define _LLVM_LIBC_CUSTOM_H
10+
11+
#include "__llvm-libc-common.h"
12+
#include "llvm-libc-types/meep.h"
13+
#include "llvm-libc-types/road.h"
14+
15+
__BEGIN_C_DECLS
16+
17+
road runner(meep, meep) __NOEXCEPT;
18+
19+
__END_C_DECLS
20+
21+
#endif // _LLVM_LIBC_CUSTOM_H

libc/utils/hdrgen/tests/expected_output/test_header.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include "__llvm-libc-common.h"
1313
#include "llvm-libc-macros/float16-macros.h"
1414

15+
#include "llvm-libc-macros/CONST_FUNC_A.h"
1516
#include "llvm-libc-macros/test_more-macros.h"
1617
#include "llvm-libc-macros/test_small-macros.h"
1718
#include "llvm-libc-types/float128.h"

libc/utils/hdrgen/tests/expected_output/test_small.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
"standards": [],
55
"includes": [
66
"__llvm-libc-common.h",
7+
"llvm-libc-macros/CONST_FUNC_A.h",
78
"llvm-libc-macros/test_more-macros.h",
89
"llvm-libc-macros/test_small-macros.h",
910
"llvm-libc-types/float128.h",
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
license_text:
2+
- Caveat emptor.
3+
- I never studied law.
4+
5+
extra_standards:
6+
acme: Wile E. Coyote
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
merge_yaml_files:
2+
- custom-common.yaml
3+
4+
header: custom.h
5+
standards:
6+
- acme
7+
8+
functions:
9+
- name: runner
10+
return_type: road
11+
arguments:
12+
- type: meep
13+
- type: meep

libc/utils/hdrgen/tests/test_integration.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,13 @@ def test_generate_subdir_header(self):
5959
self.run_script(yaml_file, output_file)
6060
self.compare_files(output_file, expected_output_file)
6161

62+
def test_custom_license_and_standards(self):
63+
yaml_file = self.source_dir / "input" / "custom.yaml"
64+
expected_output_file = self.source_dir / "expected_output" / "custom.h"
65+
output_file = self.output_dir / "custom.h"
66+
self.run_script(yaml_file, output_file)
67+
self.compare_files(output_file, expected_output_file)
68+
6269
def test_generate_json(self):
6370
yaml_file = self.source_dir / "input/test_small.yaml"
6471
expected_output_file = self.source_dir / "expected_output/test_small.json"

0 commit comments

Comments
 (0)