Skip to content

Commit d2dd802

Browse files
authored
[libc] Make hdrgen emit correct relative paths for llvm-libc-types (#127150)
This makes hdrgen emit `#include "..."` lines using the correct relative path (number of `../` steps, if any) for the containing header, and includes this in the sorted block of `#include` lines also used for the macro headers.
1 parent 1199bbb commit d2dd802

File tree

7 files changed

+77
-16
lines changed

7 files changed

+77
-16
lines changed

libc/utils/hdrgen/header.py

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#
77
# ==-------------------------------------------------------------------------==#
88

9-
from pathlib import PurePath
9+
from pathlib import PurePosixPath
1010

1111

1212
class HeaderFile:
@@ -37,26 +37,33 @@ def add_function(self, function):
3737
def includes(self):
3838
return sorted(
3939
{
40-
PurePath("llvm-libc-macros") / macro.header
40+
PurePosixPath("llvm-libc-macros") / macro.header
4141
for macro in self.macros
4242
if macro.header is not None
4343
}
44+
| {
45+
PurePosixPath("llvm-libc-types") / f"{typ.type_name}.h"
46+
for typ in self.types
47+
}
4448
)
4549

4650
def public_api(self):
47-
header_dir = PurePath(self.name).parent
51+
# Python 3.12 has .relative_to(dir, walk_up=True) for this.
52+
path_prefix = PurePosixPath("../" * (len(PurePosixPath(self.name).parents) - 1))
53+
54+
def relpath(file):
55+
return path_prefix / file
56+
4857
content = [
49-
f'#include "{file.relative_to(header_dir)}"' for file in self.includes()
50-
] + [""]
58+
f"#include {file}"
59+
for file in sorted(f'"{relpath(file)!s}"' for file in self.includes())
60+
]
5161

5262
for macro in self.macros:
5363
# When there is nothing to define, the Macro object converts to str
5464
# as an empty string. Don't emit a blank line for those cases.
5565
if str(macro):
56-
content.append(f"{macro}\n")
57-
58-
for type_ in self.types:
59-
content.append(f"{type_}")
66+
content.extend(["", f"{macro}"])
6067

6168
if self.enumerations:
6269
combined_enum_content = ",\n ".join(
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
//===-- C standard library header subdir/test.h --------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===--------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SUBDIR_TEST_H
10+
#define LLVM_LIBC_SUBDIR_TEST_H
11+
12+
#include "../__llvm-libc-common.h"
13+
14+
#include "../llvm-libc-types/type_a.h"
15+
#include "../llvm-libc-types/type_b.h"
16+
17+
__BEGIN_C_DECLS
18+
19+
type_a func(type_b) __NOEXCEPT;
20+
21+
__END_C_DECLS
22+
23+
#endif // LLVM_LIBC_SUBDIR_TEST_H

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

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,16 +15,15 @@
1515

1616
#include "llvm-libc-macros/test_more-macros.h"
1717
#include "llvm-libc-macros/test_small-macros.h"
18+
#include "llvm-libc-types/type_a.h"
19+
#include "llvm-libc-types/type_b.h"
1820

1921
#define MACRO_A 1
2022

2123
#define MACRO_B 2
2224

2325
#define MACRO_C
2426

25-
#include <llvm-libc-types/type_a.h>
26-
#include <llvm-libc-types/type_b.h>
27-
2827
enum {
2928
enum_a = value_1,
3029
enum_b = value_2,
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//===-- C standard library header subdir/test.h --------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===--------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_LIBC_SUBDIR_TEST_H
10+
#define LLVM_LIBC_SUBDIR_TEST_H
11+
12+
#include "../__llvm-libc-common.h"
13+
14+
%%public_api()
15+
16+
#endif // LLVM_LIBC_SUBDIR_TEST_H
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
header: subdir/test.h
2+
header_template: test.h.def
3+
types:
4+
- type_name: type_a
5+
- type_name: type_b
6+
functions:
7+
- name: func
8+
return_type: type_a
9+
arguments:
10+
- type: type_b
11+
standards:
12+
- stdc

libc/utils/hdrgen/tests/test_integration.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def setUp(self):
1212
self.main_script = self.source_dir.parent / "main.py"
1313
self.maxDiff = 80 * 100
1414

15-
def run_script(self, yaml_file, output_file, entry_points):
15+
def run_script(self, yaml_file, output_file, entry_points=[]):
1616
command = [
1717
"python3",
1818
str(self.main_script),
@@ -52,6 +52,13 @@ def test_generate_header(self):
5252

5353
self.compare_files(output_file, expected_output_file)
5454

55+
def test_generate_subdir_header(self):
56+
yaml_file = self.source_dir / "input" / "subdir" / "test.yaml"
57+
expected_output_file = self.source_dir / "expected_output" / "subdir" / "test.h"
58+
output_file = self.output_dir / "subdir" / "test.h"
59+
self.run_script(yaml_file, output_file)
60+
self.compare_files(output_file, expected_output_file)
61+
5562

5663
def main():
5764
parser = argparse.ArgumentParser(description="TestHeaderGenIntegration arguments")

libc/utils/hdrgen/type.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,3 @@
1010
class Type:
1111
def __init__(self, type_name):
1212
self.type_name = type_name
13-
14-
def __str__(self):
15-
return f"#include <llvm-libc-types/{self.type_name}.h>"

0 commit comments

Comments
 (0)