[libc] Add ability to generate enum types/values to HdrGen.
authorSiva Chandra Reddy <sivachandra@google.com>
Thu, 27 Feb 2020 22:30:24 +0000 (14:30 -0800)
committerSiva Chandra Reddy <sivachandra@google.com>
Sat, 29 Feb 2020 07:27:32 +0000 (23:27 -0800)
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

libc/config/linux/api.td
libc/config/public_api.td
libc/include/CMakeLists.txt
libc/include/threads.h.def [new file with mode: 0644]
libc/spec/linux.td
libc/spec/posix.td
libc/spec/spec.td
libc/spec/stdc.td
libc/utils/HdrGen/PublicAPICommand.cpp

index 3d7faa7..ebb4883 100644 (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",
+  ];
+}
index 3f40921..b608369 100644 (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 = [];
 }
index 1ff9e78..612b531 100644 (file)
@@ -36,6 +36,14 @@ add_gen_header(
 )
 
 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
   PARAMS
diff --git a/libc/include/threads.h.def b/libc/include/threads.h.def
new file mode 100644 (file)
index 0000000..276f78b
--- /dev/null
@@ -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
index 8903fda..29baf8b 100644 (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 = [
index 094eaea..b2ad036 100644 (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",
index 61c1f89..2272ef3 100644 (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> {
index 8278e9d..0eff020 100644 (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,
   ];
 }
index c072838..15263e5 100644 (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())