================ @@ -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