================
@@ -68,23 +69,156 @@ enum ID {
   FirstTSBuiltin
 };
 
+// The info used to represent each builtin.
 struct Info {
-  llvm::StringLiteral Name;
-  const char *Type, *Attributes;
-  const char *Features;
+  // Rather than store pointers to the string literals describing these four
+  // aspects of builtins, we store offsets into a common string table.
+  struct StrOffsets {
+    int Name;
+    int Type;
+    int Attributes;
+    int Features;
+  } Offsets;
+
   HeaderDesc Header;
   LanguageID Langs;
 };
 
+// The storage for `N` builtins. This contains a single pointer to the string
+// table used for these builtins and an array of metadata for each builtin.
+template <size_t N> struct Storage {
+  const char *StringTable;
+
+  std::array<Info, N> Infos;
+
+  // A constexpr function to construct the storage for a a given string table 
in
+  // the first argument and an array in the second argument. This is *only*
+  // expected to be used at compile time, we should mark it `consteval` when
+  // available.
+  //
+  // The `Infos` array is particularly special. This function expects an array
+  // of `Info` structs, where the string offsets of each entry refer to the
+  // *sizes* of those strings rather than their offsets, and for the target
+  // string to be in the provided string table at an offset the sum of all
+  // previous string sizes. This function walks the `Infos` array computing the
+  // running sum and replacing the sizes with the actual offsets in the string
+  // table that should be used. This arrangement is designed to make it easy to
+  // expand `.def` and `.inc` files with X-macros to construct both the string
+  // table and the `Info` structs in the arguments to this function.
+  static constexpr Storage<N> Make(const char *Strings,
+                                   std::array<Info, N> Infos) {
+    // Translate lengths to offsets.
+    int Offset = 0;
+    for (auto &I : Infos) {
+      Info::StrOffsets NewOffsets = {};
+      NewOffsets.Name = Offset;
+      Offset += I.Offsets.Name;
+      NewOffsets.Type = Offset;
+      Offset += I.Offsets.Type;
+      NewOffsets.Attributes = Offset;
+      Offset += I.Offsets.Attributes;
+      NewOffsets.Features = Offset;
+      Offset += I.Offsets.Features;
+      I.Offsets = NewOffsets;
+    }
+    return {Strings, Infos};
+  }
+};
+
+// A detail macro used below to emit a string literal that, after string 
literal
+// concatenation, ends up triggering the `-Woverlength-strings` warning. While
+// the warning is useful in general to catch accidentally excessive strings,
+// here we are creating them intentionally.
+//
+// This relies on a subtle aspect of `_Pragma`: that the *diagnostic* ones 
don't
+// turn into actual tokens that would disrupt string literal concatenation.
+#ifdef __clang__
+#define CLANG_BUILTIN_DETAIL_STR_TABLE(S)                                      
\
+  _Pragma("clang diagnostic push")                                             
\
+      _Pragma("clang diagnostic ignored \"-Woverlength-strings\"")             
\
+          S _Pragma("clang diagnostic pop")
+#else
+#define CLANG_BUILTIN_DETAIL_STR_TABLE(S) S
+#endif
+
+// A macro that can be used with `Builtins.def` and similar files as an X-macro
+// to add the string arguments to a builtin string table. This is typically the
+// target for the `BUILTIN`, `LANGBUILTIN`, or `LIBBUILTIN` macros in those
+// files.
+#define CLANG_BUILTIN_STR_TABLE(ID, TYPE, ATTRS)                               
\
+  CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" /*FEATURE*/ 
"\0")
+
+// A macro that can be used with target builtin `.def` and `.inc` files as an
+// X-macro to add the string arguments to a builtin string table. this is
+// typically the target for the `TARGET_BUILTIN` macro.
+#define CLANG_TARGET_BUILTIN_STR_TABLE(ID, TYPE, ATTRS, FEATURE)               
\
+  CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" FEATURE "\0")
+
+// A macro that can be used with target builtin `.def` and `.inc` files as an
+// X-macro to add the string arguments to a builtin string table. this is
+// typically the target for the `TARGET_HEADER_BUILTIN` macro. We can't 
delegate
+// to `TARGET_BUILTIN` because the `FEATURE` string changes position.
+#define CLANG_TARGET_HEADER_BUILTIN_STR_TABLE(ID, TYPE, ATTRS, HEADER, LANGS,  
\
+                                              FEATURE)                         
\
+  CLANG_BUILTIN_DETAIL_STR_TABLE(#ID "\0" TYPE "\0" ATTRS "\0" FEATURE "\0")
+
+// A detail macro used internally to compute the desired string table
+// `StrOffsets` struct for arguments to `Storage::Make`.
+#define CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS)                      
\
+  Builtin::Info::StrOffsets {                                                  
\
+    llvm::StringLiteral(#ID).size() + 1, llvm::StringLiteral(TYPE).size() + 1, 
\
+        llvm::StringLiteral(ATTRS).size() + 1,                                 
\
+        llvm::StringLiteral("").size() + 1                                     
\
----------------
nikic wrote:

```suggestion
    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("")                       \
```

https://github.com/llvm/llvm-project/pull/118734
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to