[libc] Add ability to generate enum types/values to HdrGen.

A target to generate the std C threads.h file has been added. This
utilizes the new feature added in this change.

Reviewers: phosek

Differential Revision: https://reviews.llvm.org/D75379
This commit is contained in:
Siva Chandra Reddy 2020-02-27 14:30:24 -08:00
parent 95fa5c4f24
commit d1536673c6
9 changed files with 169 additions and 15 deletions

View File

@ -143,3 +143,16 @@ def SignalAPI : PublicAPI<"signal.h"> {
"raise",
];
}
def ThreadsAPI : PublicAPI<"threads.h"> {
let Enumerations = [
"mtx_plain",
"mtx_recursive",
"mtx_timed",
"thrd_timedout",
"thrd_success",
"thrd_busy",
"thrd_error",
"thrd_nomem",
];
}

View File

@ -24,6 +24,7 @@ class PublicAPI<string name> {
string HeaderName = name;
list<MacroDef> Macros = [];
list<TypeDecl> TypeDeclarations = [];
list<string> Enumerations = [];
list<string> Structs = [];
list<string> Functions = [];
}

View File

@ -35,6 +35,14 @@ add_gen_header(
llvm_libc_common_h
)
add_gen_header(
threads_h
DEF_FILE threads.h.def
GEN_HDR threads.h
DEPENDS
llvm_libc_common_h
)
add_gen_header(
errno_h
DEF_FILE errno.h.def

View File

@ -0,0 +1,16 @@
//===---------------- C standard library header threads.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_THREADS_H
#define LLVM_LIBC_THREADS_H
#include <__llvm-libc-common.h>
%%public_api()
#endif // LLVM_LIBC_THREADS_H

View File

@ -55,16 +55,12 @@ def Linux : StandardSpec<"Linux"> {
Macro<"EL2NSYNC">,
Macro<"EADV">,
Macro<"ECOMM">,
],
[], // Types
[] // Functions
]
>;
HeaderSpec SysMMan = HeaderSpec<
"sys/mman.h",
[Macro<"MAP_ANONYMOUS">],
[], // Types
[] // Functions
[Macro<"MAP_ANONYMOUS">]
>;
HeaderSpec Signal = HeaderSpec<
@ -106,9 +102,7 @@ def Linux : StandardSpec<"Linux"> {
Macro<"SIGPWR">,
Macro<"SIGSYS">,
Macro<"SIGUNUSED">,
],
[], // Types
[] // Functions
]
>;
let Headers = [

View File

@ -84,6 +84,7 @@ def POSIX : StandardSpec<"POSIX"> {
Macro<"EXDEV">,
],
[], // Types
[], // Enumerations
[] // Functions
>;
@ -107,6 +108,7 @@ def POSIX : StandardSpec<"POSIX"> {
SizeTType,
OffTType,
],
[], // Enumerations
[
FunctionSpec<
"mmap",

View File

@ -14,6 +14,15 @@ class Struct<string name> : NamedType<name> {
list<Field> Fields;
}
class EnumNameValue<string name, string value = "__default_enum_value__"> {
string Name = name;
string Value = value;
}
class Enum<string name, list<EnumNameValue> enumerations> : NamedType<name> {
list<EnumNameValue> Enumerations = enumerations;
}
class PtrType<Type type> : Type {
Type PointeeType = type;
}
@ -43,6 +52,11 @@ class Macro<string name> {
string Name = name;
}
class EnumeratedNameValue<string name, string value = "__default__"> {
string Name = name;
string Value = value;
}
class Annotation {}
class RetValSpec<Type type, list<Annotation> annotations = []> {
@ -63,13 +77,15 @@ class FunctionSpec<string name, RetValSpec return, list<ArgSpec> args> {
}
class HeaderSpec<string name,
list<Macro> macros,
list<Type> types,
list<FunctionSpec> functions> {
list<Macro> macros = [],
list<Type> types = [],
list<EnumeratedNameValue> enumerations = [],
list<FunctionSpec> functions = []> {
string Name = name;
list<FunctionSpec> Functions = functions;
list<Type> Types = types;
list<Macro> Macros = macros;
list<EnumeratedNameValue> Enumerations = enumerations;
}
class StandardSpec<string name> {

View File

@ -8,6 +8,14 @@ def StdC : StandardSpec<"stdc"> {
RestrictedPtrType CharRestrictedPtr = RestrictedPtrType<CharType>;
ConstType ConstCharRestrictedPtr = ConstType<CharRestrictedPtr>;
NamedType MtxTType = NamedType<"mtx_t">;
PtrType MtxTTypePtr = PtrType<MtxTType>;
NamedType ThrdStartTType = NamedType<"thrd_start_t">;
NamedType ThrdTType = NamedType<"thrd_t">;
PtrType ThrdTTypePtr = PtrType<ThrdTType>;
PtrType IntPtr = PtrType<IntType>;
HeaderSpec String = HeaderSpec<
"string.h",
[
@ -16,6 +24,7 @@ def StdC : StandardSpec<"stdc"> {
[
SizeTType,
],
[], // Enumerations
[
FunctionSpec<
"memcpy",
@ -143,6 +152,7 @@ def StdC : StandardSpec<"stdc"> {
NamedType<"float_t">,
NamedType<"double_t">,
],
[], // Enumerations
[
FunctionSpec<"acos", RetValSpec<DoubleType>, [ArgSpec<DoubleType>]>,
FunctionSpec<"acosl", RetValSpec<LongDoubleType>, [ArgSpec<LongDoubleType>]>,
@ -155,6 +165,7 @@ def StdC : StandardSpec<"stdc"> {
[ // Types
SizeTType,
],
[], // Enumerations
[
FunctionSpec<
"snprintf",
@ -174,9 +185,7 @@ def StdC : StandardSpec<"stdc"> {
Macro<"EDOM">,
Macro<"EILSEQ">,
Macro<"ERANGE">,
],
[], // Types
[] // Functions
]
>;
HeaderSpec Signal = HeaderSpec<
@ -197,16 +206,79 @@ def StdC : StandardSpec<"stdc"> {
NamedType<"sigset_t">,
SizeTType,
],
[], // Enumerations
[
FunctionSpec<"raise", RetValSpec<IntType>, [ArgSpec<IntType>]>,
]
>;
HeaderSpec Threads = HeaderSpec<
"threads.h",
[], // Macros
[
MtxTType,
ThrdStartTType,
ThrdTType,
],
[
EnumeratedNameValue<"mtx_plain">,
EnumeratedNameValue<"mtx_recursive">,
EnumeratedNameValue<"mtx_timed">,
EnumeratedNameValue<"thrd_timedout">,
EnumeratedNameValue<"thrd_success">,
EnumeratedNameValue<"thrd_busy">,
EnumeratedNameValue<"thrd_error">,
EnumeratedNameValue<"thrd_nomem">,
],
[
FunctionSpec<
"mtx_init",
RetValSpec<IntType>,
[
ArgSpec<MtxTTypePtr>,
ArgSpec<IntType>,
]
>,
FunctionSpec<
"mtx_lock",
RetValSpec<IntType>,
[
ArgSpec<MtxTTypePtr>,
]
>,
FunctionSpec<
"mtx_unlock",
RetValSpec<IntType>,
[
ArgSpec<MtxTTypePtr>,
]
>,
FunctionSpec<
"thrd_create",
RetValSpec<IntType>,
[
ArgSpec<ThrdTTypePtr>,
ArgSpec<ThrdStartTType>,
ArgSpec<VoidPtr>,
]
>,
FunctionSpec<
"thrd_join",
RetValSpec<IntType>,
[
ArgSpec<ThrdTTypePtr>,
ArgSpec<IntPtr>,
]
>
]
>;
let Headers = [
Errno,
Math,
String,
StdIO,
Signal,
Threads,
];
}

View File

@ -75,11 +75,13 @@ class APIGenerator {
// Mapping from names to records defining them.
NameToRecordMapping MacroSpecMap;
NameToRecordMapping TypeSpecMap;
NameToRecordMapping EnumerationSpecMap;
NameToRecordMapping FunctionSpecMap;
NameToRecordMapping MacroDefsMap;
NameToRecordMapping TypeDeclsMap;
NameSet Structs;
NameSet Enumerations;
NameSet Functions;
bool isaNamedType(llvm::Record *Def) { return isa(Def, NamedTypeClass); }
@ -136,6 +138,13 @@ class APIGenerator {
FunctionSpecMap[std::string(FunctionSpec->getValueAsString("Name"))] =
FunctionSpec;
}
auto EnumerationSpecList =
HeaderSpec->getValueAsListOfDefs("Enumerations");
for (llvm::Record *EnumerationSpec : EnumerationSpecList) {
EnumerationSpecMap[std::string(
EnumerationSpec->getValueAsString("Name"))] = EnumerationSpec;
}
}
}
}
@ -159,6 +168,10 @@ class APIGenerator {
auto FunctionList = PublicAPI->getValueAsListOfStrings("Functions");
for (llvm::StringRef FunctionName : FunctionList)
Functions.insert(std::string(FunctionName));
auto EnumerationList = PublicAPI->getValueAsListOfStrings("Enumerations");
for (llvm::StringRef EnumerationName : EnumerationList)
Enumerations.insert(std::string(EnumerationName));
}
void index(llvm::RecordKeeper &Records) {
@ -211,6 +224,25 @@ public:
OS << '\n';
}
if (Enumerations.size() != 0)
OS << "enum {" << '\n';
for (const auto &Name : Enumerations) {
if (EnumerationSpecMap.find(Name) == EnumerationSpecMap.end())
llvm::PrintFatalError(
Name + " is not listed as an enumeration in any standard spec.\n");
llvm::Record *EnumerationSpec = EnumerationSpecMap[Name];
OS << " " << EnumerationSpec->getValueAsString("Name");
auto Value = EnumerationSpec->getValueAsString("Value");
if (Value == "__default__") {
OS << ",\n";
} else {
OS << " = " << Value << ",\n";
}
}
if (Enumerations.size() != 0)
OS << "};\n\n";
OS << "__BEGIN_C_DECLS\n\n";
for (auto &Name : Functions) {
if (FunctionSpecMap.find(Name) == FunctionSpecMap.end())