[libc] Use entrypoints.txt as the single source of list of functions for a platform.

The function listings in api.td are removed. The same lists are now deduced using the information
in entrypoints.txt.

Reviewed By: sivachandra

Differential Revision: https://reviews.llvm.org/D89267
This commit is contained in:
Michael Jones 2020-10-12 17:03:19 +00:00
parent 42ed388120
commit f6bf2823c4
8 changed files with 38 additions and 145 deletions

View File

@ -66,9 +66,6 @@ include(CMakeParseArguments)
include(LLVMLibCRules)
include(LLVMLibCCheckCpuFeatures)
add_subdirectory(include)
add_subdirectory(config)
include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_MACHINE}/entrypoints.txt")
include("${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_MACHINE}/headers.txt")
@ -84,6 +81,8 @@ foreach(entrypoint IN LISTS TARGET_LIBC_ENTRYPOINTS TARGET_LIBM_ENTRYPOINTS)
list(APPEND TARGET_ENTRYPOINT_NAME_LIST ${entrypoint_name})
endforeach()
add_subdirectory(include)
add_subdirectory(config)
add_subdirectory(src)
add_subdirectory(utils)

View File

@ -84,11 +84,15 @@ function(add_gen_header target_name)
file(GLOB td_includes ${LIBC_SOURCE_DIR}/spec/*.td)
set(ENTRYPOINT_NAME_LIST_ARG ${TARGET_ENTRYPOINT_NAME_LIST})
list(TRANSFORM ENTRYPOINT_NAME_LIST_ARG PREPEND "--e=")
add_custom_command(
OUTPUT ${out_file}
COMMAND $<TARGET_FILE:libc-hdrgen> -o ${out_file} --header ${ADD_GEN_HDR_GEN_HDR}
--def ${in_file} ${replacement_params} -I ${LIBC_SOURCE_DIR}
${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
${ENTRYPOINT_NAME_LIST_ARG}
${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${in_file} ${fq_data_files} ${td_includes}

View File

@ -87,22 +87,6 @@ def AssertAPI : PublicAPI<"assert.h"> {
}
def CTypeAPI : PublicAPI<"ctype.h"> {
let Functions = [
"isalnum",
"isalpha",
"isblank",
"iscntrl",
"isdigit",
"isgraph",
"islower",
"isprint",
"ispunct",
"isspace",
"isupper",
"isxdigit",
"tolower",
"toupper",
];
}
def MathErrHandlingMacro : MacroDef<"math_errhandling"> {
@ -168,88 +152,9 @@ def MathAPI : PublicAPI<"math.h"> {
DoubleT,
FloatT,
];
let Functions = [
"copysign",
"copysignf",
"copysignl",
"ceil",
"ceilf",
"ceill",
"cosf",
"fabs",
"fabsf",
"fabsl",
"floor",
"floorf",
"floorl",
"fmax",
"fmaxf",
"fmaxl",
"fmin",
"fminf",
"fminl",
"frexp",
"frexpf",
"frexpl",
"hypotf",
"logb",
"logbf",
"logbl",
"modf",
"modff",
"modfl",
"expf",
"exp2f",
"remainderf",
"remainder",
"remainderl",
"remquof",
"remquo",
"remquol",
"round",
"roundf",
"roundl",
"sincosf",
"sinf",
"sqrt",
"sqrtf",
"sqrtl",
"trunc",
"truncf",
"truncl",
];
}
def StringAPI : PublicAPI<"string.h"> {
let Functions = [
"bzero",
"memchr",
"memcmp",
"memcpy",
"memmove",
"memrchr",
"memset",
"strcat",
"strchr",
"strcmp",
"strcoll",
"strcpy",
"strcspn",
"strerror",
"strlen",
"strncat",
"strncmp",
"strncpy",
"strnlen",
"strpbrk",
"strrchr",
"strspn",
"strstr",
"strtok",
"strtok_r",
"strxfrm",
];
let TypeDeclarations = [
SizeT,
];
@ -264,17 +169,9 @@ def StdIOAPI : PublicAPI<"stdio.h"> {
SizeT,
FILE,
];
let Functions = [
"fwrite",
];
}
def StdlibAPI : PublicAPI<"stdlib.h"> {
let Functions = [
"_Exit",
"abort",
];
}
def ErrnoAPI : PublicAPI<"errno.h"> {
@ -320,11 +217,6 @@ def SysMManAPI : PublicAPI<"sys/mman.h"> {
SizeT,
OffT,
];
let Functions = [
"mmap",
"munmap",
];
}
def StructSigactionDefn : TypeDecl<"struct sigaction"> {
@ -352,17 +244,6 @@ def SignalAPI : PublicAPI<"signal.h"> {
StructSigactionDefn,
SighandlerTDefn,
];
let Functions = [
"raise",
"sigaction",
"sigdelset",
"sigprocmask",
"sigemptyset",
"sigaddset",
"sigfillset",
"signal",
];
}
def OnceFlag : TypeDecl<"once_flag"> {
@ -412,15 +293,6 @@ def ThreadsAPI : PublicAPI<"threads.h"> {
"thrd_error",
"thrd_nomem",
];
let Functions = [
"call_once",
"mtx_init",
"mtx_lock",
"mtx_unlock",
"thrd_create",
"thrd_join",
];
}
def UniStdAPI : PublicAPI<"unistd.h"> {
@ -428,8 +300,4 @@ def UniStdAPI : PublicAPI<"unistd.h"> {
SSizeT,
SizeT,
];
let Functions = [
"write",
];
}

View File

@ -40,7 +40,7 @@ Command *Generator::getCommandHandler(llvm::StringRef CommandName) {
return IncludeFileCmd.get();
} else if (CommandName == PublicAPICommand::Name) {
if (!PublicAPICmd)
PublicAPICmd = std::make_unique<PublicAPICommand>();
PublicAPICmd = std::make_unique<PublicAPICommand>(EntrypointNameList);
return PublicAPICmd.get();
} else {
return nullptr;

View File

@ -31,6 +31,7 @@ class Command;
class Generator {
llvm::StringRef HeaderDefFile;
const std::vector<std::string> &EntrypointNameList;
llvm::StringRef StdHeader;
std::unordered_map<std::string, std::string> &ArgMap;
@ -44,9 +45,11 @@ class Generator {
void printError(llvm::StringRef Msg);
public:
Generator(const std::string &DefFile, const std::string &Header,
Generator(const std::string &DefFile, const std::vector<std::string> &EN,
const std::string &Header,
std::unordered_map<std::string, std::string> &Map)
: HeaderDefFile(DefFile), StdHeader(Header), ArgMap(Map) {}
: HeaderDefFile(DefFile), EntrypointNameList(EN), StdHeader(Header),
ArgMap(Map) {}
void generate(llvm::raw_ostream &OS, llvm::RecordKeeper &Records);
};

View File

@ -24,6 +24,11 @@ llvm::cl::opt<std::string> StandardHeader(
"header",
llvm::cl::desc("The standard header file which is to be generated."),
llvm::cl::value_desc("<header file>"));
llvm::cl::list<std::string> EntrypointNamesOption(
"e", llvm::cl::value_desc("<list of entrypoints>"),
llvm::cl::desc(
"Each --e is one entrypoint (generated from entrypoints.txt)"),
llvm::cl::OneOrMore);
llvm::cl::list<std::string> ReplacementValues(
"args", llvm::cl::desc("Command separated <argument name>=<value> pairs."),
llvm::cl::value_desc("<name=value>[,name=value]"));
@ -42,7 +47,7 @@ namespace llvm_libc {
bool HeaderGeneratorMain(llvm::raw_ostream &OS, llvm::RecordKeeper &Records) {
std::unordered_map<std::string, std::string> ArgMap;
ParseArgValuePairs(ArgMap);
Generator G(HeaderDefFile, StandardHeader, ArgMap);
Generator G(HeaderDefFile, EntrypointNamesOption, StandardHeader, ArgMap);
G.generate(OS, Records);
return false;

View File

@ -40,7 +40,9 @@ static void dedentAndWrite(llvm::StringRef Text, llvm::raw_ostream &OS) {
namespace llvm_libc {
void writeAPIFromIndex(APIIndexer &G, llvm::raw_ostream &OS) {
void writeAPIFromIndex(APIIndexer &G,
std::vector<std::string> EntrypointNameList,
llvm::raw_ostream &OS) {
for (auto &Pair : G.MacroDefsMap) {
const std::string &Name = Pair.first;
if (G.MacroSpecMap.find(Name) == G.MacroSpecMap.end())
@ -83,9 +85,15 @@ void writeAPIFromIndex(APIIndexer &G, llvm::raw_ostream &OS) {
OS << "};\n\n";
OS << "__BEGIN_C_DECLS\n\n";
for (auto &Name : G.Functions) {
if (G.FunctionSpecMap.find(Name) == G.FunctionSpecMap.end())
llvm::PrintFatalError(Name + " not found in any standard spec.\n");
for (auto &Name : EntrypointNameList) {
if (G.FunctionSpecMap.find(Name) == G.FunctionSpecMap.end()) {
continue; // Functions that aren't in this header file are skipped as
// opposed to erroring out because the list of functions being
// iterated over is the complete list of functions with
// entrypoints. Thus this is filtering out the functions that
// don't go to this header file, whereas the other, similar
// conditionals above are more of a sanity check.
}
llvm::Record *FunctionSpec = G.FunctionSpecMap[Name];
llvm::Record *RetValSpec = FunctionSpec->getValueAsDef("Return");
@ -119,7 +127,7 @@ void PublicAPICommand::run(llvm::raw_ostream &OS, const ArgVector &Args,
}
APIIndexer G(StdHeader, Records);
writeAPIFromIndex(G, OS);
writeAPIFromIndex(G, EntrypointNameList, OS);
}
} // namespace llvm_libc

View File

@ -26,9 +26,15 @@ class RecordKeeper;
namespace llvm_libc {
class PublicAPICommand : public Command {
private:
const std::vector<std::string> &EntrypointNameList;
public:
static const char Name[];
PublicAPICommand(const std::vector<std::string> &EntrypointNames)
: EntrypointNameList(EntrypointNames) {}
void run(llvm::raw_ostream &OS, const ArgVector &Args,
llvm::StringRef StdHeader, llvm::RecordKeeper &Records,
const Command::ErrorReporter &Reporter) const override;