diff --git a/libc/cmake/modules/LLVMLibCHeaderRules.cmake b/libc/cmake/modules/LLVMLibCHeaderRules.cmake --- a/libc/cmake/modules/LLVMLibCHeaderRules.cmake +++ b/libc/cmake/modules/LLVMLibCHeaderRules.cmake @@ -88,6 +88,7 @@ OUTPUT ${out_file} COMMAND $ -o ${out_file} --header ${ADD_GEN_HDR_GEN_HDR} --def ${in_file} ${replacement_params} -I ${LIBC_SOURCE_DIR} + --entrypoints ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/${LIBC_TARGET_MACHINE}/entrypoints.txt ${LIBC_SOURCE_DIR}/config/${LIBC_TARGET_OS}/api.td WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} diff --git a/libc/config/linux/api.td b/libc/config/linux/api.td --- a/libc/config/linux/api.td +++ b/libc/config/linux/api.td @@ -87,22 +87,6 @@ } 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 @@ 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 @@ SizeT, FILE, ]; - - let Functions = [ - "fwrite", - ]; } def StdlibAPI : PublicAPI<"stdlib.h"> { - let Functions = [ - "_Exit", - "abort", - ]; } def ErrnoAPI : PublicAPI<"errno.h"> { @@ -320,11 +217,6 @@ SizeT, OffT, ]; - - let Functions = [ - "mmap", - "munmap", - ]; } def StructSigactionDefn : TypeDecl<"struct sigaction"> { @@ -352,17 +244,6 @@ StructSigactionDefn, SighandlerTDefn, ]; - - let Functions = [ - "raise", - "sigaction", - "sigdelset", - "sigprocmask", - "sigemptyset", - "sigaddset", - "sigfillset", - "signal", - ]; } def OnceFlag : TypeDecl<"once_flag"> { @@ -412,15 +293,6 @@ "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 @@ SSizeT, SizeT, ]; - - let Functions = [ - "write", - ]; } diff --git a/libc/spec/llvm_libc_ext.td b/libc/spec/llvm_libc_ext.td --- a/libc/spec/llvm_libc_ext.td +++ b/libc/spec/llvm_libc_ext.td @@ -13,7 +13,6 @@ >, ] >; - let Headers = [ String, ]; diff --git a/libc/spec/stdc.td b/libc/spec/stdc.td --- a/libc/spec/stdc.td +++ b/libc/spec/stdc.td @@ -1,4 +1,5 @@ def StdC : StandardSpec<"stdc"> { + ConstType ConstVoidPtr = ConstType; RestrictedPtrType VoidRestrictedPtr = RestrictedPtrType; ConstType ConstVoidRestrictedPtr = ConstType; diff --git a/libc/utils/HdrGen/CMakeLists.txt b/libc/utils/HdrGen/CMakeLists.txt --- a/libc/utils/HdrGen/CMakeLists.txt +++ b/libc/utils/HdrGen/CMakeLists.txt @@ -10,6 +10,8 @@ Main.cpp PublicAPICommand.cpp PublicAPICommand.h + EntrypointsReader.h + EntrypointsReader.cpp ) target_include_directories(libc-hdrgen PRIVATE ${LIBC_SOURCE_DIR}) diff --git a/libc/utils/HdrGen/Command.h b/libc/utils/HdrGen/Command.h --- a/libc/utils/HdrGen/Command.h +++ b/libc/utils/HdrGen/Command.h @@ -45,7 +45,8 @@ virtual ~Command(); virtual void run(llvm::raw_ostream &OS, const ArgVector &Args, - llvm::StringRef StdHeader, llvm::RecordKeeper &Records, + llvm::StringRef StdHeader, llvm::StringRef EntrypointsFile, + llvm::RecordKeeper &Records, const ErrorReporter &Reporter) const = 0; }; diff --git a/libc/utils/HdrGen/EntrypointsReader.h b/libc/utils/HdrGen/EntrypointsReader.h new file mode 100644 --- /dev/null +++ b/libc/utils/HdrGen/EntrypointsReader.h @@ -0,0 +1,22 @@ +//===-- A class to index functions listed in entrypoints files --*- C++ -*-===// +// +// 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_UTILS_HDRGEN_ENTRYPOINTSLOADER_H +#define LLVM_LIBC_UTILS_HDRGEN_ENTRYPOINTSLOADER_H + +#include "llvm/ADT/StringRef.h" + +#include +#include + +namespace llvm_libc { +using NameSet = std::unordered_set; +NameSet getFunctionsFromEntrypointsFile(std::string FilePath); +} // namespace llvm_libc + +#endif // LLVM_LIBC_UTILS_HDRGEN_ENTRYPOINTSLOADER_H diff --git a/libc/utils/HdrGen/EntrypointsReader.cpp b/libc/utils/HdrGen/EntrypointsReader.cpp new file mode 100644 --- /dev/null +++ b/libc/utils/HdrGen/EntrypointsReader.cpp @@ -0,0 +1,66 @@ +//===-- Implementation of EntrpointsLoader class---------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "EntrypointsReader.h" + +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/Twine.h" +#include "llvm/TableGen/Error.h" + +#include "llvm/Support/MemoryBuffer.h" + +#include +#include + +namespace llvm_libc { + +using NameSet = std::unordered_set; +NameSet getFunctionsFromEntrypointsFile(std::string FilePath) { + llvm::ErrorOr> FileBuf = + llvm::MemoryBuffer::getFile(FilePath); + + if (!FileBuf) + llvm::PrintFatalError("File failed to load" + FilePath + + " in EntrypointsReader\n"); + + NameSet FunctionSet; + + llvm::SmallVector Lines; + FileBuf.get()->getBuffer().split(Lines, "\n"); + + bool InSet = false; + llvm::StringRef CurLine; + llvm::SmallVector LineChunks; + + for (unsigned Count = 0; Count < Lines.size(); Count += 1) { + CurLine = Lines[Count].trim(' ').trim('\t'); + + if (CurLine.contains("#")) { + CurLine = CurLine.split("#").first; + } + + if (CurLine.size() == 0) { + continue; + } + + if (!InSet && CurLine.startswith("set(")) { + InSet = true; + } else { + if (CurLine.contains(")")) { + InSet = false; + continue; + } else if (CurLine.consume_front("libc.src.")) { + std::string FuncName = std::string(CurLine.rsplit(".").second); + FunctionSet.insert(FuncName); + } + } + } + return FunctionSet; +} + +} // namespace llvm_libc diff --git a/libc/utils/HdrGen/Generator.h b/libc/utils/HdrGen/Generator.h --- a/libc/utils/HdrGen/Generator.h +++ b/libc/utils/HdrGen/Generator.h @@ -31,6 +31,7 @@ class Generator { llvm::StringRef HeaderDefFile; + llvm::StringRef EntrypointsFile; llvm::StringRef StdHeader; std::unordered_map &ArgMap; @@ -44,9 +45,11 @@ void printError(llvm::StringRef Msg); public: - Generator(const std::string &DefFile, const std::string &Header, + Generator(const std::string &DefFile, const std::string &Entrypoints, + const std::string &Header, std::unordered_map &Map) - : HeaderDefFile(DefFile), StdHeader(Header), ArgMap(Map) {} + : HeaderDefFile(DefFile), EntrypointsFile(Entrypoints), StdHeader(Header), + ArgMap(Map) {} void generate(llvm::raw_ostream &OS, llvm::RecordKeeper &Records); }; diff --git a/libc/utils/HdrGen/Generator.cpp b/libc/utils/HdrGen/Generator.cpp --- a/libc/utils/HdrGen/Generator.cpp +++ b/libc/utils/HdrGen/Generator.cpp @@ -105,7 +105,7 @@ Command::ErrorReporter Reporter( llvm::SMLoc::getFromPointer(CommandName.data()), SrcMgr); - Cmd->run(OS, Args, StdHeader, Records, Reporter); + Cmd->run(OS, Args, StdHeader, EntrypointsFile, Records, Reporter); } else if (!Line.startswith(CommentPrefix)) { // There is no comment or command on this line so we just write it as is. OS << P.first << "\n"; diff --git a/libc/utils/HdrGen/IncludeFileCommand.h b/libc/utils/HdrGen/IncludeFileCommand.h --- a/libc/utils/HdrGen/IncludeFileCommand.h +++ b/libc/utils/HdrGen/IncludeFileCommand.h @@ -23,7 +23,8 @@ static const char Name[]; void run(llvm::raw_ostream &OS, const ArgVector &Args, - llvm::StringRef StdHeader, llvm::RecordKeeper &Records, + llvm::StringRef StdHeader, llvm::StringRef EntrypointsFile, + llvm::RecordKeeper &Records, const Command::ErrorReporter &Reporter) const override; }; diff --git a/libc/utils/HdrGen/IncludeFileCommand.cpp b/libc/utils/HdrGen/IncludeFileCommand.cpp --- a/libc/utils/HdrGen/IncludeFileCommand.cpp +++ b/libc/utils/HdrGen/IncludeFileCommand.cpp @@ -19,6 +19,7 @@ void IncludeFileCommand::run(llvm::raw_ostream &OS, const ArgVector &Args, llvm::StringRef StdHeader, + llvm::StringRef EntryPointsFile, llvm::RecordKeeper &Records, const Command::ErrorReporter &Reporter) const { if (Args.size() != 1) { diff --git a/libc/utils/HdrGen/Main.cpp b/libc/utils/HdrGen/Main.cpp --- a/libc/utils/HdrGen/Main.cpp +++ b/libc/utils/HdrGen/Main.cpp @@ -20,6 +20,10 @@ llvm::cl::opt HeaderDefFile("def", llvm::cl::desc("Path to the .h.def file."), llvm::cl::value_desc(""), llvm::cl::Required); +llvm::cl::opt EntrypointsFile( + "entrypoints", + llvm::cl::desc("Path to the entrypoints.txt file for your target."), + llvm::cl::value_desc(""), llvm::cl::Required); llvm::cl::opt StandardHeader( "header", llvm::cl::desc("The standard header file which is to be generated."), @@ -42,7 +46,7 @@ bool HeaderGeneratorMain(llvm::raw_ostream &OS, llvm::RecordKeeper &Records) { std::unordered_map ArgMap; ParseArgValuePairs(ArgMap); - Generator G(HeaderDefFile, StandardHeader, ArgMap); + Generator G(HeaderDefFile, EntrypointsFile, StandardHeader, ArgMap); G.generate(OS, Records); return false; diff --git a/libc/utils/HdrGen/PublicAPICommand.h b/libc/utils/HdrGen/PublicAPICommand.h --- a/libc/utils/HdrGen/PublicAPICommand.h +++ b/libc/utils/HdrGen/PublicAPICommand.h @@ -30,7 +30,8 @@ static const char Name[]; void run(llvm::raw_ostream &OS, const ArgVector &Args, - llvm::StringRef StdHeader, llvm::RecordKeeper &Records, + llvm::StringRef StdHeader, llvm::StringRef EntrypointsFile, + llvm::RecordKeeper &Records, const Command::ErrorReporter &Reporter) const override; }; diff --git a/libc/utils/HdrGen/PublicAPICommand.cpp b/libc/utils/HdrGen/PublicAPICommand.cpp --- a/libc/utils/HdrGen/PublicAPICommand.cpp +++ b/libc/utils/HdrGen/PublicAPICommand.cpp @@ -8,6 +8,8 @@ #include "PublicAPICommand.h" +#include "EntrypointsReader.h" + #include "utils/LibcTableGenUtil/APIIndexer.h" #include "llvm/ADT/StringExtras.h" @@ -40,7 +42,8 @@ namespace llvm_libc { -void writeAPIFromIndex(APIIndexer &G, llvm::raw_ostream &OS) { +void writeAPIFromIndex(APIIndexer &G, llvm::StringRef EntrypointsFile, + llvm::raw_ostream &OS) { for (auto &Pair : G.MacroDefsMap) { const std::string &Name = Pair.first; if (G.MacroSpecMap.find(Name) == G.MacroSpecMap.end()) @@ -82,10 +85,15 @@ if (G.Enumerations.size() != 0) OS << "};\n\n"; + auto Functions = + getFunctionsFromEntrypointsFile(std::string(EntrypointsFile)); OS << "__BEGIN_C_DECLS\n\n"; - for (auto &Name : G.Functions) { + for (auto &Name : Functions) { if (G.FunctionSpecMap.find(Name) == G.FunctionSpecMap.end()) - llvm::PrintFatalError(Name + " not found in any standard spec.\n"); + continue; // this used to be an error, but isn't anymore because + // we're getting the full function list from entrypoints.txt + // and then using this as a filter to get only + // the appropriate ones for each header file. llvm::Record *FunctionSpec = G.FunctionSpecMap[Name]; llvm::Record *RetValSpec = FunctionSpec->getValueAsDef("Return"); @@ -112,6 +120,7 @@ void PublicAPICommand::run(llvm::raw_ostream &OS, const ArgVector &Args, llvm::StringRef StdHeader, + llvm::StringRef EntrypointsFile, llvm::RecordKeeper &Records, const Command::ErrorReporter &Reporter) const { if (Args.size() != 0) { @@ -119,7 +128,7 @@ } APIIndexer G(StdHeader, Records); - writeAPIFromIndex(G, OS); + writeAPIFromIndex(G, EntrypointsFile, OS); } } // namespace llvm_libc