Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion libc/include/locale.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
header: locale.h
header_template: locale.h.def
macros:
- macro_name: NULL
- macro_name: "NULL"
macro_header: null-macro.h
types:
- type_name: locale_t
Expand Down
2 changes: 1 addition & 1 deletion libc/include/stdio.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
header: stdio.h
header_template: stdio.h.def
macros:
- macro_name: NULL
- macro_name: "NULL"
macro_header: null-macro.h
- macro_name: stdout
macro_value: stdout
Expand Down
2 changes: 1 addition & 1 deletion libc/include/stdlib.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ standards:
merge_yaml_files:
- stdlib-malloc.yaml
macros:
- macro_name: NULL
- macro_name: "NULL"
macro_header: null-macro.h
types:
- type_name: __atexithandler_t
Expand Down
2 changes: 1 addition & 1 deletion libc/include/string.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ header: string.h
standards:
- stdc
macros:
- macro_name: NULL
- macro_name: "NULL"
macro_header: null-macro.h
types:
- type_name: locale_t
Expand Down
2 changes: 1 addition & 1 deletion libc/include/time.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
header: time.h
header_template: time.h.def
macros:
- macro_name: NULL
- macro_name: "NULL"
macro_header: null-macro.h
types:
- type_name: struct_timeval
Expand Down
8 changes: 4 additions & 4 deletions libc/include/wchar.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
header: wchar.h
header_template: wchar.h.def
macros:
- macro_name: NULL
- macro_name: "NULL"
macro_header: null-macro.h
types:
- type_name: FILE
Expand Down Expand Up @@ -188,8 +188,8 @@ functions:
standards:
- stdc
return_type: wchar_t *
arguments:
- type: wchar_t *__restrict
arguments:
- type: wchar_t *__restrict
- type: const wchar_t *__restrict
- type: size_t
- name: wmemmove
Expand All @@ -212,7 +212,7 @@ functions:
standards:
- stdc
return_type: wchar_t *
arguments:
arguments:
- type: wchar_t *__restrict
- type: const wchar_t *__restrict
- name: wcslcat
Expand Down
16 changes: 3 additions & 13 deletions libc/utils/hdrgen/hdrgen/enumeration.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,14 @@
#
# ==-------------------------------------------------------------------------==#

from functools import total_ordering
from hdrgen.symbol import Symbol


@total_ordering
class Enumeration:
class Enumeration(Symbol):
def __init__(self, name, value):
self.name = name
super().__init__(name)
self.value = value

def __eq__(self, other):
return self.name == other.name

def __lt__(self, other):
return self.name < other.name

def __hash__(self):
return self.name.__hash__()

def __str__(self):
if self.value != None:
return f"{self.name} = {self.value}"
Expand Down
16 changes: 3 additions & 13 deletions libc/utils/hdrgen/hdrgen/function.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# ==-------------------------------------------------------------------------==#

import re
from functools import total_ordering
from hdrgen.symbol import Symbol
from hdrgen.type import Type


Expand Down Expand Up @@ -37,14 +37,13 @@
NONIDENTIFIER = re.compile("[^a-zA-Z0-9_]+")


@total_ordering
class Function:
class Function(Symbol):
def __init__(
self, return_type, name, arguments, standards, guard=None, attributes=[]
):
super().__init__(name)
assert return_type
self.return_type = return_type
self.name = name
self.arguments = [
arg if isinstance(arg, str) else arg["type"] for arg in arguments
]
Expand All @@ -53,15 +52,6 @@ def __init__(
self.guard = guard
self.attributes = attributes or []

def __eq__(self, other):
return self.name == other.name

def __lt__(self, other):
return self.name < other.name

def __hash__(self):
return self.name.__hash__()

def signature_types(self):
def collapse(type_string):
assert type_string
Expand Down
14 changes: 10 additions & 4 deletions libc/utils/hdrgen/hdrgen/header.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,8 @@ def includes(self):
}
| {
COMPILER_HEADER_TYPES.get(
typ.type_name,
PurePosixPath("llvm-libc-types") / f"{typ.type_name}.h",
typ.name,
PurePosixPath("llvm-libc-types") / f"{typ.name}.h",
)
for typ in self.all_types()
}
Expand Down Expand Up @@ -227,7 +227,7 @@ def relpath(file):
)
]

for macro in self.macros:
for macro in sorted(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):
Expand All @@ -242,7 +242,12 @@ def relpath(file):
content.append("\n__BEGIN_C_DECLS\n")

current_guard = None
for function in self.functions:
last_name = None
for function in sorted(self.functions):
# If the last function's name was the same after underscores,
# elide the blank line between the declarations.
if last_name == function.name_without_underscores():
content.pop()
if function.guard == None and current_guard == None:
content.append(str(function) + " __NOEXCEPT;")
content.append("")
Expand All @@ -264,6 +269,7 @@ def relpath(file):
content.append(f"#ifdef {current_guard}")
content.append(str(function) + " __NOEXCEPT;")
content.append("")
last_name = function.name_without_underscores()
if current_guard != None:
content.pop()
content.append(f"#endif // {current_guard}")
Expand Down
16 changes: 3 additions & 13 deletions libc/utils/hdrgen/hdrgen/macro.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,15 @@
#
# ==-------------------------------------------------------------------------==#

from functools import total_ordering
from hdrgen.symbol import Symbol


@total_ordering
class Macro:
class Macro(Symbol):
def __init__(self, name, value=None, header=None):
self.name = name
super().__init__(name)
self.value = value
self.header = header

def __eq__(self, other):
return self.name == other.name

def __lt__(self, other):
return self.name < other.name

def __hash__(self):
return self.name.__hash__()

def __str__(self):
if self.header != None:
return ""
Expand Down
1 change: 1 addition & 0 deletions libc/utils/hdrgen/hdrgen/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@ def merge_from(paths):
return 2
header.merge(merge_from_header)

assert header.name, f"`header: name.h` line is required in {yaml_file}"
return header

if args.json:
Expand Down
16 changes: 3 additions & 13 deletions libc/utils/hdrgen/hdrgen/object.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,13 @@
#
# ==-------------------------------------------------------------------------==#

from functools import total_ordering
from hdrgen.symbol import Symbol


@total_ordering
class Object:
class Object(Symbol):
def __init__(self, name, type):
self.name = name
super().__init__(name)
self.type = type

def __eq__(self, other):
return self.name == other.name

def __lt__(self, other):
return self.name < other.name

def __hash__(self):
return self.name.__hash__()

def __str__(self):
return f"extern {self.type} {self.name};"
41 changes: 41 additions & 0 deletions libc/utils/hdrgen/hdrgen/symbol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# ====-- Symbol class for libc function headers----------------*- 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
#
# ==-------------------------------------------------------------------------==#

from functools import total_ordering


@total_ordering
class Symbol:
"""
Symbol is the common superclass for each kind of entity named by an
identifier. It provides the name field, and defines sort ordering,
hashing, and equality based only on the name. The sorting is pretty
presentation order for identifiers, which is to say it first sorts
lexically but ignores leading underscores and secondarily sorts with the
fewest underscores first.
"""

def __init__(self, name):
assert name
self.name = name

def __eq__(self, other):
return self.name == other.name

def __hash__(self):
return self.name.__hash__()

def name_without_underscores(self):
return self.name.lstrip("_")

def name_sort_key(self):
ident = self.name_without_underscores()
return ident, len(self.name) - len(ident)

def __lt__(self, other):
return self.name_sort_key() < other.name_sort_key()
20 changes: 5 additions & 15 deletions libc/utils/hdrgen/hdrgen/type.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,10 @@
#
# ==-------------------------------------------------------------------------==#

from functools import total_ordering
from hdrgen.symbol import Symbol


@total_ordering
class Type:
def __init__(self, type_name):
assert type_name
self.type_name = type_name

def __eq__(self, other):
return self.type_name == other.type_name

def __lt__(self, other):
return self.type_name < other.type_name

def __hash__(self):
return self.type_name.__hash__()
class Type(Symbol):
# A type so far carries no specific information beyond its name.
def __init__(self, name):
super().__init__(name)
24 changes: 24 additions & 0 deletions libc/utils/hdrgen/tests/expected_output/sorting.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//===-- Standard C header <sorting.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_SORTING_H
#define _LLVM_LIBC_SORTING_H

#include "__llvm-libc-common.h"

__BEGIN_C_DECLS

void func_with_aliases(int) __NOEXCEPT;
void _func_with_aliases(int) __NOEXCEPT;
void __func_with_aliases(int) __NOEXCEPT;

void gunk(const char *) __NOEXCEPT;

__END_C_DECLS

#endif // _LLVM_LIBC_SORTING_H
20 changes: 20 additions & 0 deletions libc/utils/hdrgen/tests/input/sorting.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
header: sorting.h
standards:
- stdc
functions:
- name: gunk
return_type: void
arguments:
- type: const char *
- name: _func_with_aliases
return_type: void
arguments:
- type: int
- name: func_with_aliases
return_type: void
arguments:
- type: int
- name: __func_with_aliases
return_type: void
arguments:
- type: int
7 changes: 7 additions & 0 deletions libc/utils/hdrgen/tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ def test_generate_json(self):

self.compare_files(output_file, expected_output_file)

def test_sorting(self):
yaml_file = self.source_dir / "input" / "sorting.yaml"
expected_output_file = self.source_dir / "expected_output" / "sorting.h"
output_file = self.output_dir / "sorting.h"
self.run_script(yaml_file, output_file)
self.compare_files(output_file, expected_output_file)


def main():
parser = argparse.ArgumentParser(description="TestHeaderGenIntegration arguments")
Expand Down
Loading