[libc] Use entrypoints.txt as the single source of list of functions for a platform.
authorMichael Jones <michaelrj@google.com>
Mon, 12 Oct 2020 17:03:19 +0000 (17:03 +0000)
committerMichael Jones <michaelrj@google.com>
Thu, 15 Oct 2020 20:46:13 +0000 (20:46 +0000)
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

libc/CMakeLists.txt
libc/cmake/modules/LLVMLibCHeaderRules.cmake
libc/config/linux/api.td
libc/utils/HdrGen/Generator.cpp
libc/utils/HdrGen/Generator.h
libc/utils/HdrGen/Main.cpp
libc/utils/HdrGen/PublicAPICommand.cpp
libc/utils/HdrGen/PublicAPICommand.h

index 58613fd..a760098 100644 (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)
 
index 072203c..c01cf25 100644 (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}
index 40eec8f..fbeb040 100644 (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",
-  ];
 }
index 07f10da..cbfb2db 100644 (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;
index 53080c0..eef96ad 100644 (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);
 };
index 2dce804..d148747 100644 (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;
index 87b188c..5285b0d 100644 (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
index bfe2e5f..fb0a7a8 100644 (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;