Files
clang-p2996/libc/utils/hdrgen/function.py
Roland McGrath 9f6e72bd0c [libc] Add merge_yaml_files feature to hdrgen (#127269)
This allows a sort of "include" mechanism in the YAML files.  A
file can have a "merge_yaml_files" list of paths (relative to the
containing file's location).  These are YAML files in the same
syntax, except they cannot have their own "header" entry.  Only
the lists (types, enums, macros, functions, objects) can appear.
The main YAML file is then processed just as if each of its lists
were the (sorted) union of each YAML file's corresponding list.

This will enable maintaining a single source of truth for each
function signature and other such details, where it is necessary
to generate the same declaration in more than one header.
2025-02-14 15:34:40 -08:00

85 lines
2.4 KiB
Python

# ====-- Function 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
#
# ==-------------------------------------------------------------------------==#
import re
from functools import total_ordering
from type import Type
# These are the keywords that appear in C type syntax but are not part of the
# include file name. This is all of the modifiers, qualifiers, and base types,
# but not "struct".
KEYWORDS = [
"_Atomic",
"_Complex",
"_Float16",
"_Noreturn",
"__restrict",
"accum",
"char",
"const",
"double",
"float",
"fract",
"int",
"long",
"short",
"signed",
"unsigned",
"void",
"volatile",
]
NONIDENTIFIER = re.compile("[^a-zA-Z0-9_]+")
@total_ordering
class Function:
def __init__(
self, return_type, name, arguments, standards, guard=None, attributes=[]
):
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
]
assert all(self.arguments)
self.standards = standards
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
# Split into words at nonidentifier characters (`*`, `[`, etc.),
# filter out keywords and numbers, and then rejoin with "_".
return "_".join(
word
for word in NONIDENTIFIER.split(type_string)
if word and not word.isdecimal() and word not in KEYWORDS
)
all_types = [self.return_type] + self.arguments
return {
Type(string) for string in filter(None, (collapse(t) for t in all_types))
}
def __str__(self):
attrs_str = "".join(f"{attr} " for attr in self.attributes)
arguments_str = ", ".join(self.arguments) if self.arguments else "void"
return attrs_str + f"{self.return_type} {self.name}({arguments_str})"