Skip to content

Revert "Switch builtin strings to use string tables" #119638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Dec 14, 2024

Conversation

chandlerc
Copy link
Member

@chandlerc chandlerc commented Dec 12, 2024

Reverts #118734

There are currently some specific versions of MSVC that are miscompiling this code (we think). We don't know why as all the other build bots and at least some folks' local Windows builds work fine.

This is a candidate revert to help the relevant folks catch their builders up and have time to debug the issue. However, the expectation is to roll forward at some point with a workaround if at all possible.

@llvmbot
Copy link
Member

llvmbot commented Dec 12, 2024

@llvm/pr-subscribers-backend-powerpc
@llvm/pr-subscribers-backend-systemz

@llvm/pr-subscribers-backend-msp430

Author: Chandler Carruth (chandlerc)

Changes

Reverts llvm/llvm-project#118734

There is currently a specific (unreleased?) version of MSVC and builder that are crashing / failing on this code. We don't know why as all the other build bots and at least some folks' local Windows builds work fine.

This is a candidate revert to help the relevant folks catch their builders up and have time to debug the issue. However, it should only be submitted if we have a fairly concrete ETA on figuring out what is going wrong and suggesting some path forward given that no one else has thus far reproduced the issue.


Patch is 77.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119638.diff

48 Files Affected:

  • (modified) clang/include/clang/Basic/Builtins.h (+36-169)
  • (modified) clang/include/clang/Basic/BuiltinsPPC.def (-1)
  • (modified) clang/include/clang/Basic/TargetInfo.h (+5-6)
  • (modified) clang/lib/Basic/Builtins.cpp (+39-81)
  • (modified) clang/lib/Basic/Targets/AArch64.cpp (+28-32)
  • (modified) clang/lib/Basic/Targets/AArch64.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AMDGPU.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/AMDGPU.h (+1-2)
  • (modified) clang/lib/Basic/Targets/ARC.h (+1-4)
  • (modified) clang/lib/Basic/Targets/ARM.cpp (+21-24)
  • (modified) clang/lib/Basic/Targets/ARM.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AVR.h (+1-4)
  • (modified) clang/lib/Basic/Targets/BPF.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/BPF.h (+1-2)
  • (modified) clang/lib/Basic/Targets/CSKY.cpp (+4)
  • (modified) clang/lib/Basic/Targets/CSKY.h (+1-4)
  • (modified) clang/lib/Basic/Targets/DirectX.h (+1-4)
  • (modified) clang/lib/Basic/Targets/Hexagon.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/Hexagon.h (+1-2)
  • (modified) clang/lib/Basic/Targets/Lanai.h (+1-4)
  • (modified) clang/lib/Basic/Targets/LoongArch.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/LoongArch.h (+1-2)
  • (modified) clang/lib/Basic/Targets/M68k.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/M68k.h (+1-2)
  • (modified) clang/lib/Basic/Targets/MSP430.h (+2-3)
  • (modified) clang/lib/Basic/Targets/Mips.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/Mips.h (+1-2)
  • (modified) clang/lib/Basic/Targets/NVPTX.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/NVPTX.h (+1-2)
  • (modified) clang/lib/Basic/Targets/PNaCl.h (+1-4)
  • (modified) clang/lib/Basic/Targets/PPC.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/PPC.h (+1-2)
  • (modified) clang/lib/Basic/Targets/RISCV.cpp (+13-19)
  • (modified) clang/lib/Basic/Targets/RISCV.h (+1-2)
  • (modified) clang/lib/Basic/Targets/SPIR.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/SPIR.h (+2-6)
  • (modified) clang/lib/Basic/Targets/Sparc.h (+2-3)
  • (modified) clang/lib/Basic/Targets/SystemZ.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/SystemZ.h (+1-2)
  • (modified) clang/lib/Basic/Targets/TCE.h (+1-4)
  • (modified) clang/lib/Basic/Targets/VE.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/VE.h (+1-2)
  • (modified) clang/lib/Basic/Targets/WebAssembly.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/WebAssembly.h (+1-2)
  • (modified) clang/lib/Basic/Targets/X86.cpp (+26-42)
  • (modified) clang/lib/Basic/Targets/X86.h (+2-4)
  • (modified) clang/lib/Basic/Targets/XCore.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/XCore.h (+1-2)
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index a9bb6efe850cc6..89f65682ae5b41 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -55,7 +55,6 @@ struct HeaderDesc {
 #undef HEADER
   } ID;
 
-  constexpr HeaderDesc() : ID() {}
   constexpr HeaderDesc(HeaderID ID) : ID(ID) {}
 
   const char *getName() const;
@@ -69,140 +68,14 @@ enum ID {
   FirstTSBuiltin
 };
 
-// The info used to represent each builtin.
 struct Info {
-  // 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;
-
+  llvm::StringLiteral Name;
+  const char *Type, *Attributes;
+  const char *Features;
   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 {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("")                       \
-  }
-
-// A detail macro used internally to compute the desired string table
-// `StrOffsets` struct for arguments to `Storage::Make`.
-#define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE)      \
-  Builtin::Info::StrOffsets {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof(FEATURE)                  \
-  }
-
-// A set of macros that can be used with builtin `.def' files as an X-macro to
-// create an `Info` struct for a particular builtin. It both computes the
-// `StrOffsets` value for the string table (the lengths here, translated to
-// offsets by the Storage::Make function), and the other metadata for each
-// builtin.
-//
-// There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`,
-// `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`.
-#define CLANG_BUILTIN_ENTRY(ID, TYPE, ATTRS)                                   \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_LANGBUILTIN_ENTRY(ID, TYPE, ATTRS, LANG)                         \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, LANG},
-#define CLANG_LIBBUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG)                  \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::HEADER, LANG},
-#define CLANG_TARGET_BUILTIN_ENTRY(ID, TYPE, ATTRS, FEATURE)                   \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_TARGET_HEADER_BUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG,       \
-                                          FEATURE)                             \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::HEADER, LANG},
-
 /// Holds information about both target-independent and
 /// target-specific builtins, allowing easy queries by clients.
 ///
@@ -210,11 +83,8 @@ template <size_t N> struct Storage {
 /// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
 /// be translated back with getAuxBuiltinID() before use.
 class Context {
-  const char *TSStrTable = nullptr;
-  const char *AuxTSStrTable = nullptr;
-
-  llvm::ArrayRef<Info> TSInfos;
-  llvm::ArrayRef<Info> AuxTSInfos;
+  llvm::ArrayRef<Info> TSRecords;
+  llvm::ArrayRef<Info> AuxTSRecords;
 
 public:
   Context() = default;
@@ -230,13 +100,12 @@ class Context {
 
   /// Return the identifier name for the specified builtin,
   /// e.g. "__builtin_abs".
-  llvm::StringRef getName(unsigned ID) const;
+  llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
 
   /// Get the type descriptor string for the specified builtin.
-  const char *getTypeString(unsigned ID) const;
-
-  /// Get the attributes descriptor string for the specified builtin.
-  const char *getAttributesString(unsigned ID) const;
+  const char *getTypeString(unsigned ID) const {
+    return getRecord(ID).Type;
+  }
 
   /// Return true if this function is a target-specific builtin.
   bool isTSBuiltin(unsigned ID) const {
@@ -245,40 +114,40 @@ class Context {
 
   /// Return true if this function has no side effects.
   bool isPure(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'U') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'U') != nullptr;
   }
 
   /// Return true if this function has no side effects and doesn't
   /// read memory.
   bool isConst(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'c') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'c') != nullptr;
   }
 
   /// Return true if we know this builtin never throws an exception.
   bool isNoThrow(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'n') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'n') != nullptr;
   }
 
   /// Return true if we know this builtin never returns.
   bool isNoReturn(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'r') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'r') != nullptr;
   }
 
   /// Return true if we know this builtin can return twice.
   bool isReturnsTwice(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'j') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'j') != nullptr;
   }
 
   /// Returns true if this builtin does not perform the side-effects
   /// of its arguments.
   bool isUnevaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'u') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'u') != nullptr;
   }
 
   /// Return true if this is a builtin for a libc/libm function,
   /// with a "__builtin_" prefix (e.g. __builtin_abs).
   bool isLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'F') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'F') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined libc/libm
@@ -289,21 +158,21 @@ class Context {
   /// they do not, but they are recognized as builtins once we see
   /// a declaration.
   bool isPredefinedLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'f') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'f') != nullptr;
   }
 
   /// Returns true if this builtin requires appropriate header in other
   /// compilers. In Clang it will work even without including it, but we can emit
   /// a warning about missing header.
   bool isHeaderDependentFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'h') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'h') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined compiler-rt/libgcc
   /// function, such as "__clear_cache", where we know the signature a
   /// priori.
   bool isPredefinedRuntimeFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'i') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'i') != nullptr;
   }
 
   /// Determines whether this builtin is a C++ standard library function
@@ -311,7 +180,7 @@ class Context {
   /// specialization, where the signature is determined by the standard library
   /// declaration.
   bool isInStdNamespace(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'z') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'z') != nullptr;
   }
 
   /// Determines whether this builtin can have its address taken with no
@@ -325,33 +194,33 @@ class Context {
 
   /// Determines whether this builtin has custom typechecking.
   bool hasCustomTypechecking(unsigned ID) const {
-    return strchr(getAttributesString(ID), 't') != nullptr;
+    return strchr(getRecord(ID).Attributes, 't') != nullptr;
   }
 
   /// Determines whether a declaration of this builtin should be recognized
   /// even if the type doesn't match the specified signature.
   bool allowTypeMismatch(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'T') != nullptr ||
+    return strchr(getRecord(ID).Attributes, 'T') != nullptr ||
            hasCustomTypechecking(ID);
   }
 
   /// Determines whether this builtin has a result or any arguments which
   /// are pointer types.
   bool hasPtrArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '*') != nullptr;
+    return strchr(getRecord(ID).Type, '*') != nullptr;
   }
 
   /// Return true if this builtin has a result or any arguments which are
   /// reference types.
   bool hasReferenceArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '&') != nullptr ||
-           strchr(getTypeString(ID), 'A') != nullptr;
+    return strchr(getRecord(ID).Type, '&') != nullptr ||
+           strchr(getRecord(ID).Type, 'A') != nullptr;
   }
 
   /// If this is a library function that comes from a specific
   /// header, retrieve that header name.
   const char *getHeaderName(unsigned ID) const {
-    return getInfo(ID).Header.getName();
+    return getRecord(ID).Header.getName();
   }
 
   /// Determine whether this builtin is like printf in its
@@ -376,25 +245,27 @@ class Context {
   /// Such functions can be const when the MathErrno lang option and FP
   /// exceptions are disabled.
   bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'e') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'e') != nullptr;
   }
 
   bool isConstWithoutExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'g') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'g') != nullptr;
   }
 
-  const char *getRequiredFeatures(unsigned ID) const;
+  const char *getRequiredFeatures(unsigned ID) const {
+    return getRecord(ID).Features;
+  }
 
   unsigned getRequiredVectorWidth(unsigned ID) const;
 
   /// Return true if builtin ID belongs to AuxTarget.
   bool isAuxBuiltinID(unsigned ID) const {
-    return ID >= (Builtin::FirstTSBuiltin + TSInfos.size());
+    return ID >= (Builtin::FirstTSBuiltin + TSRecords.size());
   }
 
   /// Return real builtin ID (i.e. ID it would have during compilation
   /// for AuxTarget).
-  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSInfos.size(); }
+  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
 
   /// Returns true if this is a libc/libm function without the '__builtin_'
   /// prefix.
@@ -406,20 +277,16 @@ class Context {
 
   /// Return true if this function can be constant evaluated by Clang frontend.
   bool isConstantEvaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'E') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'E') != nullptr;
   }
 
   /// Returns true if this is an immediate (consteval) function
   bool isImmediate(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'G') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'G') != nullptr;
   }
 
 private:
-  std::pair<const char *, const Info &> getStrTableAndInfo(unsigned ID) const;
-
-  const Info &getInfo(unsigned ID) const {
-    return getStrTableAndInfo(ID).second;
-  }
+  const Info &getRecord(unsigned ID) const;
 
   /// Helper function for isPrintfLike and isScanfLike.
   bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index bb7d54bbb793eb..161df386f00f03 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1138,6 +1138,5 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true,
 // FIXME: Obviously incomplete.
 
 #undef BUILTIN
-#undef TARGET_BUILTIN
 #undef CUSTOM_BUILTIN
 #undef UNALIASED_CUSTOM_BUILTIN
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 52a1ac9781395c..4420228793e95f 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -16,7 +16,6 @@
 
 #include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/BitmaskEnum.h"
-#include "clang/Basic/Builtins.h"
 #include "clang/Basic/CFProtectionOptions.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/LLVM.h"
@@ -1010,11 +1009,11 @@ class TargetInfo : public TransferrableTargetInfo,
   virtual void getTargetDefines(const LangOptions &Opts,
                                 MacroBuilder &Builder) const = 0;
 
-  /// Return information about target-specific builtins for the current primary
-  /// target, and info about which builtins are non-portable across the current
-  /// set of primary and secondary targets.
-  virtual std::pair<const char *, ArrayRef<Builtin::Info>>
-  getTargetBuiltinStorage() const = 0;
+
+  /// Return information about target-specific builtins for
+  /// the current primary target, and info about which builtins are non-portable
+  /// across the current set of primary and secondary targets.
+  virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
 
   /// Returns target-specific min and max values VScale_Range.
   virtual std::optional<std::pair<unsigned, unsigned>>
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index c991139b8d5ad7..25a601573698e7 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -29,93 +29,54 @@ const char *HeaderDesc::getName() const {
   llvm_unreachable("Unknown HeaderDesc::HeaderID enum");
 }
 
-static constexpr auto BuiltinStorage =
-    Builtin::Storage<Builtin::FirstTSBuiltin>::Make(
-        CLANG_BUILTIN_STR_TABLE("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_STR_TABLE
+static constexpr Builtin::Info BuiltinInfo[] = {
+    {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER,
+     ALL_LANGUAGES},
+#define BUILTIN(ID, TYPE, ATTRS)                                               \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS)                                    \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS},
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS)                             \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS},
 #include "clang/Basic/Builtins.inc"
-            ,
-        {CLANG_BUILTIN_ENTRY("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_ENTRY
-#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
-#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
-#include "clang/Basic/Builtins.inc"
-        });
+};
 
-std::pair<const char *, const Builtin::Info &>
-Builtin::Context::getStrTableAndInfo(unsigned ID) const {
+const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
   if (ID < Builtin::FirstTSBuiltin)
-    return {BuiltinStorage.StringTable, BuiltinStorage.Infos[ID]};
-  assert(
-      ((ID - Builtin::FirstTSBuiltin) < (TSInfos.size() + AuxTSInfos.size())) &&
-      "Invalid builtin ID!");
+    return BuiltinInfo[ID];
+  assert(((ID - Builtin::FirstTSBuiltin) <
+          (TSRecords.size() + AuxTSRecords.size())) &&
+         "Invalid builtin ID!");
   if (isAuxBuiltinID(ID))
-    return {AuxTSStrTable,
-            AuxTSInfos[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin]};
-  return {TSStrTable, TSInfos[ID - Builtin::FirstTSBuiltin]};
-}
-
-static llvm::StringRef getStrFromTable(const char *StrTable, int Offset) {
-  return &StrTable[Offset];
-}
-
-/// Return the identifier name for the specified builtin,
-/// e.g. "__builtin_abs".
-llvm::StringRef Builtin::Context::getName(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Name);
-}
-
-const char *Builtin::Context::getTypeString(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Type).data();
-}
-
-const char *Builtin::Context::getAt...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Dec 12, 2024

@llvm/pr-subscribers-backend-aarch64

Author: Chandler Carruth (chandlerc)

Changes

Reverts llvm/llvm-project#118734

There is currently a specific (unreleased?) version of MSVC and builder that are crashing / failing on this code. We don't know why as all the other build bots and at least some folks' local Windows builds work fine.

This is a candidate revert to help the relevant folks catch their builders up and have time to debug the issue. However, it should only be submitted if we have a fairly concrete ETA on figuring out what is going wrong and suggesting some path forward given that no one else has thus far reproduced the issue.


Patch is 77.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119638.diff

48 Files Affected:

  • (modified) clang/include/clang/Basic/Builtins.h (+36-169)
  • (modified) clang/include/clang/Basic/BuiltinsPPC.def (-1)
  • (modified) clang/include/clang/Basic/TargetInfo.h (+5-6)
  • (modified) clang/lib/Basic/Builtins.cpp (+39-81)
  • (modified) clang/lib/Basic/Targets/AArch64.cpp (+28-32)
  • (modified) clang/lib/Basic/Targets/AArch64.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AMDGPU.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/AMDGPU.h (+1-2)
  • (modified) clang/lib/Basic/Targets/ARC.h (+1-4)
  • (modified) clang/lib/Basic/Targets/ARM.cpp (+21-24)
  • (modified) clang/lib/Basic/Targets/ARM.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AVR.h (+1-4)
  • (modified) clang/lib/Basic/Targets/BPF.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/BPF.h (+1-2)
  • (modified) clang/lib/Basic/Targets/CSKY.cpp (+4)
  • (modified) clang/lib/Basic/Targets/CSKY.h (+1-4)
  • (modified) clang/lib/Basic/Targets/DirectX.h (+1-4)
  • (modified) clang/lib/Basic/Targets/Hexagon.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/Hexagon.h (+1-2)
  • (modified) clang/lib/Basic/Targets/Lanai.h (+1-4)
  • (modified) clang/lib/Basic/Targets/LoongArch.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/LoongArch.h (+1-2)
  • (modified) clang/lib/Basic/Targets/M68k.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/M68k.h (+1-2)
  • (modified) clang/lib/Basic/Targets/MSP430.h (+2-3)
  • (modified) clang/lib/Basic/Targets/Mips.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/Mips.h (+1-2)
  • (modified) clang/lib/Basic/Targets/NVPTX.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/NVPTX.h (+1-2)
  • (modified) clang/lib/Basic/Targets/PNaCl.h (+1-4)
  • (modified) clang/lib/Basic/Targets/PPC.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/PPC.h (+1-2)
  • (modified) clang/lib/Basic/Targets/RISCV.cpp (+13-19)
  • (modified) clang/lib/Basic/Targets/RISCV.h (+1-2)
  • (modified) clang/lib/Basic/Targets/SPIR.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/SPIR.h (+2-6)
  • (modified) clang/lib/Basic/Targets/Sparc.h (+2-3)
  • (modified) clang/lib/Basic/Targets/SystemZ.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/SystemZ.h (+1-2)
  • (modified) clang/lib/Basic/Targets/TCE.h (+1-4)
  • (modified) clang/lib/Basic/Targets/VE.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/VE.h (+1-2)
  • (modified) clang/lib/Basic/Targets/WebAssembly.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/WebAssembly.h (+1-2)
  • (modified) clang/lib/Basic/Targets/X86.cpp (+26-42)
  • (modified) clang/lib/Basic/Targets/X86.h (+2-4)
  • (modified) clang/lib/Basic/Targets/XCore.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/XCore.h (+1-2)
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index a9bb6efe850cc6..89f65682ae5b41 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -55,7 +55,6 @@ struct HeaderDesc {
 #undef HEADER
   } ID;
 
-  constexpr HeaderDesc() : ID() {}
   constexpr HeaderDesc(HeaderID ID) : ID(ID) {}
 
   const char *getName() const;
@@ -69,140 +68,14 @@ enum ID {
   FirstTSBuiltin
 };
 
-// The info used to represent each builtin.
 struct Info {
-  // 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;
-
+  llvm::StringLiteral Name;
+  const char *Type, *Attributes;
+  const char *Features;
   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 {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("")                       \
-  }
-
-// A detail macro used internally to compute the desired string table
-// `StrOffsets` struct for arguments to `Storage::Make`.
-#define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE)      \
-  Builtin::Info::StrOffsets {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof(FEATURE)                  \
-  }
-
-// A set of macros that can be used with builtin `.def' files as an X-macro to
-// create an `Info` struct for a particular builtin. It both computes the
-// `StrOffsets` value for the string table (the lengths here, translated to
-// offsets by the Storage::Make function), and the other metadata for each
-// builtin.
-//
-// There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`,
-// `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`.
-#define CLANG_BUILTIN_ENTRY(ID, TYPE, ATTRS)                                   \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_LANGBUILTIN_ENTRY(ID, TYPE, ATTRS, LANG)                         \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, LANG},
-#define CLANG_LIBBUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG)                  \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::HEADER, LANG},
-#define CLANG_TARGET_BUILTIN_ENTRY(ID, TYPE, ATTRS, FEATURE)                   \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_TARGET_HEADER_BUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG,       \
-                                          FEATURE)                             \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::HEADER, LANG},
-
 /// Holds information about both target-independent and
 /// target-specific builtins, allowing easy queries by clients.
 ///
@@ -210,11 +83,8 @@ template <size_t N> struct Storage {
 /// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
 /// be translated back with getAuxBuiltinID() before use.
 class Context {
-  const char *TSStrTable = nullptr;
-  const char *AuxTSStrTable = nullptr;
-
-  llvm::ArrayRef<Info> TSInfos;
-  llvm::ArrayRef<Info> AuxTSInfos;
+  llvm::ArrayRef<Info> TSRecords;
+  llvm::ArrayRef<Info> AuxTSRecords;
 
 public:
   Context() = default;
@@ -230,13 +100,12 @@ class Context {
 
   /// Return the identifier name for the specified builtin,
   /// e.g. "__builtin_abs".
-  llvm::StringRef getName(unsigned ID) const;
+  llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
 
   /// Get the type descriptor string for the specified builtin.
-  const char *getTypeString(unsigned ID) const;
-
-  /// Get the attributes descriptor string for the specified builtin.
-  const char *getAttributesString(unsigned ID) const;
+  const char *getTypeString(unsigned ID) const {
+    return getRecord(ID).Type;
+  }
 
   /// Return true if this function is a target-specific builtin.
   bool isTSBuiltin(unsigned ID) const {
@@ -245,40 +114,40 @@ class Context {
 
   /// Return true if this function has no side effects.
   bool isPure(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'U') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'U') != nullptr;
   }
 
   /// Return true if this function has no side effects and doesn't
   /// read memory.
   bool isConst(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'c') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'c') != nullptr;
   }
 
   /// Return true if we know this builtin never throws an exception.
   bool isNoThrow(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'n') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'n') != nullptr;
   }
 
   /// Return true if we know this builtin never returns.
   bool isNoReturn(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'r') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'r') != nullptr;
   }
 
   /// Return true if we know this builtin can return twice.
   bool isReturnsTwice(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'j') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'j') != nullptr;
   }
 
   /// Returns true if this builtin does not perform the side-effects
   /// of its arguments.
   bool isUnevaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'u') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'u') != nullptr;
   }
 
   /// Return true if this is a builtin for a libc/libm function,
   /// with a "__builtin_" prefix (e.g. __builtin_abs).
   bool isLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'F') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'F') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined libc/libm
@@ -289,21 +158,21 @@ class Context {
   /// they do not, but they are recognized as builtins once we see
   /// a declaration.
   bool isPredefinedLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'f') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'f') != nullptr;
   }
 
   /// Returns true if this builtin requires appropriate header in other
   /// compilers. In Clang it will work even without including it, but we can emit
   /// a warning about missing header.
   bool isHeaderDependentFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'h') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'h') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined compiler-rt/libgcc
   /// function, such as "__clear_cache", where we know the signature a
   /// priori.
   bool isPredefinedRuntimeFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'i') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'i') != nullptr;
   }
 
   /// Determines whether this builtin is a C++ standard library function
@@ -311,7 +180,7 @@ class Context {
   /// specialization, where the signature is determined by the standard library
   /// declaration.
   bool isInStdNamespace(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'z') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'z') != nullptr;
   }
 
   /// Determines whether this builtin can have its address taken with no
@@ -325,33 +194,33 @@ class Context {
 
   /// Determines whether this builtin has custom typechecking.
   bool hasCustomTypechecking(unsigned ID) const {
-    return strchr(getAttributesString(ID), 't') != nullptr;
+    return strchr(getRecord(ID).Attributes, 't') != nullptr;
   }
 
   /// Determines whether a declaration of this builtin should be recognized
   /// even if the type doesn't match the specified signature.
   bool allowTypeMismatch(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'T') != nullptr ||
+    return strchr(getRecord(ID).Attributes, 'T') != nullptr ||
            hasCustomTypechecking(ID);
   }
 
   /// Determines whether this builtin has a result or any arguments which
   /// are pointer types.
   bool hasPtrArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '*') != nullptr;
+    return strchr(getRecord(ID).Type, '*') != nullptr;
   }
 
   /// Return true if this builtin has a result or any arguments which are
   /// reference types.
   bool hasReferenceArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '&') != nullptr ||
-           strchr(getTypeString(ID), 'A') != nullptr;
+    return strchr(getRecord(ID).Type, '&') != nullptr ||
+           strchr(getRecord(ID).Type, 'A') != nullptr;
   }
 
   /// If this is a library function that comes from a specific
   /// header, retrieve that header name.
   const char *getHeaderName(unsigned ID) const {
-    return getInfo(ID).Header.getName();
+    return getRecord(ID).Header.getName();
   }
 
   /// Determine whether this builtin is like printf in its
@@ -376,25 +245,27 @@ class Context {
   /// Such functions can be const when the MathErrno lang option and FP
   /// exceptions are disabled.
   bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'e') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'e') != nullptr;
   }
 
   bool isConstWithoutExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'g') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'g') != nullptr;
   }
 
-  const char *getRequiredFeatures(unsigned ID) const;
+  const char *getRequiredFeatures(unsigned ID) const {
+    return getRecord(ID).Features;
+  }
 
   unsigned getRequiredVectorWidth(unsigned ID) const;
 
   /// Return true if builtin ID belongs to AuxTarget.
   bool isAuxBuiltinID(unsigned ID) const {
-    return ID >= (Builtin::FirstTSBuiltin + TSInfos.size());
+    return ID >= (Builtin::FirstTSBuiltin + TSRecords.size());
   }
 
   /// Return real builtin ID (i.e. ID it would have during compilation
   /// for AuxTarget).
-  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSInfos.size(); }
+  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
 
   /// Returns true if this is a libc/libm function without the '__builtin_'
   /// prefix.
@@ -406,20 +277,16 @@ class Context {
 
   /// Return true if this function can be constant evaluated by Clang frontend.
   bool isConstantEvaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'E') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'E') != nullptr;
   }
 
   /// Returns true if this is an immediate (consteval) function
   bool isImmediate(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'G') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'G') != nullptr;
   }
 
 private:
-  std::pair<const char *, const Info &> getStrTableAndInfo(unsigned ID) const;
-
-  const Info &getInfo(unsigned ID) const {
-    return getStrTableAndInfo(ID).second;
-  }
+  const Info &getRecord(unsigned ID) const;
 
   /// Helper function for isPrintfLike and isScanfLike.
   bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index bb7d54bbb793eb..161df386f00f03 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1138,6 +1138,5 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true,
 // FIXME: Obviously incomplete.
 
 #undef BUILTIN
-#undef TARGET_BUILTIN
 #undef CUSTOM_BUILTIN
 #undef UNALIASED_CUSTOM_BUILTIN
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 52a1ac9781395c..4420228793e95f 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -16,7 +16,6 @@
 
 #include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/BitmaskEnum.h"
-#include "clang/Basic/Builtins.h"
 #include "clang/Basic/CFProtectionOptions.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/LLVM.h"
@@ -1010,11 +1009,11 @@ class TargetInfo : public TransferrableTargetInfo,
   virtual void getTargetDefines(const LangOptions &Opts,
                                 MacroBuilder &Builder) const = 0;
 
-  /// Return information about target-specific builtins for the current primary
-  /// target, and info about which builtins are non-portable across the current
-  /// set of primary and secondary targets.
-  virtual std::pair<const char *, ArrayRef<Builtin::Info>>
-  getTargetBuiltinStorage() const = 0;
+
+  /// Return information about target-specific builtins for
+  /// the current primary target, and info about which builtins are non-portable
+  /// across the current set of primary and secondary targets.
+  virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
 
   /// Returns target-specific min and max values VScale_Range.
   virtual std::optional<std::pair<unsigned, unsigned>>
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index c991139b8d5ad7..25a601573698e7 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -29,93 +29,54 @@ const char *HeaderDesc::getName() const {
   llvm_unreachable("Unknown HeaderDesc::HeaderID enum");
 }
 
-static constexpr auto BuiltinStorage =
-    Builtin::Storage<Builtin::FirstTSBuiltin>::Make(
-        CLANG_BUILTIN_STR_TABLE("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_STR_TABLE
+static constexpr Builtin::Info BuiltinInfo[] = {
+    {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER,
+     ALL_LANGUAGES},
+#define BUILTIN(ID, TYPE, ATTRS)                                               \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS)                                    \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS},
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS)                             \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS},
 #include "clang/Basic/Builtins.inc"
-            ,
-        {CLANG_BUILTIN_ENTRY("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_ENTRY
-#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
-#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
-#include "clang/Basic/Builtins.inc"
-        });
+};
 
-std::pair<const char *, const Builtin::Info &>
-Builtin::Context::getStrTableAndInfo(unsigned ID) const {
+const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
   if (ID < Builtin::FirstTSBuiltin)
-    return {BuiltinStorage.StringTable, BuiltinStorage.Infos[ID]};
-  assert(
-      ((ID - Builtin::FirstTSBuiltin) < (TSInfos.size() + AuxTSInfos.size())) &&
-      "Invalid builtin ID!");
+    return BuiltinInfo[ID];
+  assert(((ID - Builtin::FirstTSBuiltin) <
+          (TSRecords.size() + AuxTSRecords.size())) &&
+         "Invalid builtin ID!");
   if (isAuxBuiltinID(ID))
-    return {AuxTSStrTable,
-            AuxTSInfos[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin]};
-  return {TSStrTable, TSInfos[ID - Builtin::FirstTSBuiltin]};
-}
-
-static llvm::StringRef getStrFromTable(const char *StrTable, int Offset) {
-  return &StrTable[Offset];
-}
-
-/// Return the identifier name for the specified builtin,
-/// e.g. "__builtin_abs".
-llvm::StringRef Builtin::Context::getName(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Name);
-}
-
-const char *Builtin::Context::getTypeString(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Type).data();
-}
-
-const char *Builtin::Context::getAt...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Dec 12, 2024

@llvm/pr-subscribers-clang

Author: Chandler Carruth (chandlerc)

Changes

Reverts llvm/llvm-project#118734

There is currently a specific (unreleased?) version of MSVC and builder that are crashing / failing on this code. We don't know why as all the other build bots and at least some folks' local Windows builds work fine.

This is a candidate revert to help the relevant folks catch their builders up and have time to debug the issue. However, it should only be submitted if we have a fairly concrete ETA on figuring out what is going wrong and suggesting some path forward given that no one else has thus far reproduced the issue.


Patch is 77.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119638.diff

48 Files Affected:

  • (modified) clang/include/clang/Basic/Builtins.h (+36-169)
  • (modified) clang/include/clang/Basic/BuiltinsPPC.def (-1)
  • (modified) clang/include/clang/Basic/TargetInfo.h (+5-6)
  • (modified) clang/lib/Basic/Builtins.cpp (+39-81)
  • (modified) clang/lib/Basic/Targets/AArch64.cpp (+28-32)
  • (modified) clang/lib/Basic/Targets/AArch64.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AMDGPU.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/AMDGPU.h (+1-2)
  • (modified) clang/lib/Basic/Targets/ARC.h (+1-4)
  • (modified) clang/lib/Basic/Targets/ARM.cpp (+21-24)
  • (modified) clang/lib/Basic/Targets/ARM.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AVR.h (+1-4)
  • (modified) clang/lib/Basic/Targets/BPF.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/BPF.h (+1-2)
  • (modified) clang/lib/Basic/Targets/CSKY.cpp (+4)
  • (modified) clang/lib/Basic/Targets/CSKY.h (+1-4)
  • (modified) clang/lib/Basic/Targets/DirectX.h (+1-4)
  • (modified) clang/lib/Basic/Targets/Hexagon.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/Hexagon.h (+1-2)
  • (modified) clang/lib/Basic/Targets/Lanai.h (+1-4)
  • (modified) clang/lib/Basic/Targets/LoongArch.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/LoongArch.h (+1-2)
  • (modified) clang/lib/Basic/Targets/M68k.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/M68k.h (+1-2)
  • (modified) clang/lib/Basic/Targets/MSP430.h (+2-3)
  • (modified) clang/lib/Basic/Targets/Mips.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/Mips.h (+1-2)
  • (modified) clang/lib/Basic/Targets/NVPTX.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/NVPTX.h (+1-2)
  • (modified) clang/lib/Basic/Targets/PNaCl.h (+1-4)
  • (modified) clang/lib/Basic/Targets/PPC.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/PPC.h (+1-2)
  • (modified) clang/lib/Basic/Targets/RISCV.cpp (+13-19)
  • (modified) clang/lib/Basic/Targets/RISCV.h (+1-2)
  • (modified) clang/lib/Basic/Targets/SPIR.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/SPIR.h (+2-6)
  • (modified) clang/lib/Basic/Targets/Sparc.h (+2-3)
  • (modified) clang/lib/Basic/Targets/SystemZ.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/SystemZ.h (+1-2)
  • (modified) clang/lib/Basic/Targets/TCE.h (+1-4)
  • (modified) clang/lib/Basic/Targets/VE.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/VE.h (+1-2)
  • (modified) clang/lib/Basic/Targets/WebAssembly.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/WebAssembly.h (+1-2)
  • (modified) clang/lib/Basic/Targets/X86.cpp (+26-42)
  • (modified) clang/lib/Basic/Targets/X86.h (+2-4)
  • (modified) clang/lib/Basic/Targets/XCore.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/XCore.h (+1-2)
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index a9bb6efe850cc6..89f65682ae5b41 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -55,7 +55,6 @@ struct HeaderDesc {
 #undef HEADER
   } ID;
 
-  constexpr HeaderDesc() : ID() {}
   constexpr HeaderDesc(HeaderID ID) : ID(ID) {}
 
   const char *getName() const;
@@ -69,140 +68,14 @@ enum ID {
   FirstTSBuiltin
 };
 
-// The info used to represent each builtin.
 struct Info {
-  // 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;
-
+  llvm::StringLiteral Name;
+  const char *Type, *Attributes;
+  const char *Features;
   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 {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("")                       \
-  }
-
-// A detail macro used internally to compute the desired string table
-// `StrOffsets` struct for arguments to `Storage::Make`.
-#define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE)      \
-  Builtin::Info::StrOffsets {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof(FEATURE)                  \
-  }
-
-// A set of macros that can be used with builtin `.def' files as an X-macro to
-// create an `Info` struct for a particular builtin. It both computes the
-// `StrOffsets` value for the string table (the lengths here, translated to
-// offsets by the Storage::Make function), and the other metadata for each
-// builtin.
-//
-// There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`,
-// `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`.
-#define CLANG_BUILTIN_ENTRY(ID, TYPE, ATTRS)                                   \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_LANGBUILTIN_ENTRY(ID, TYPE, ATTRS, LANG)                         \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, LANG},
-#define CLANG_LIBBUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG)                  \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::HEADER, LANG},
-#define CLANG_TARGET_BUILTIN_ENTRY(ID, TYPE, ATTRS, FEATURE)                   \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_TARGET_HEADER_BUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG,       \
-                                          FEATURE)                             \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::HEADER, LANG},
-
 /// Holds information about both target-independent and
 /// target-specific builtins, allowing easy queries by clients.
 ///
@@ -210,11 +83,8 @@ template <size_t N> struct Storage {
 /// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
 /// be translated back with getAuxBuiltinID() before use.
 class Context {
-  const char *TSStrTable = nullptr;
-  const char *AuxTSStrTable = nullptr;
-
-  llvm::ArrayRef<Info> TSInfos;
-  llvm::ArrayRef<Info> AuxTSInfos;
+  llvm::ArrayRef<Info> TSRecords;
+  llvm::ArrayRef<Info> AuxTSRecords;
 
 public:
   Context() = default;
@@ -230,13 +100,12 @@ class Context {
 
   /// Return the identifier name for the specified builtin,
   /// e.g. "__builtin_abs".
-  llvm::StringRef getName(unsigned ID) const;
+  llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
 
   /// Get the type descriptor string for the specified builtin.
-  const char *getTypeString(unsigned ID) const;
-
-  /// Get the attributes descriptor string for the specified builtin.
-  const char *getAttributesString(unsigned ID) const;
+  const char *getTypeString(unsigned ID) const {
+    return getRecord(ID).Type;
+  }
 
   /// Return true if this function is a target-specific builtin.
   bool isTSBuiltin(unsigned ID) const {
@@ -245,40 +114,40 @@ class Context {
 
   /// Return true if this function has no side effects.
   bool isPure(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'U') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'U') != nullptr;
   }
 
   /// Return true if this function has no side effects and doesn't
   /// read memory.
   bool isConst(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'c') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'c') != nullptr;
   }
 
   /// Return true if we know this builtin never throws an exception.
   bool isNoThrow(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'n') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'n') != nullptr;
   }
 
   /// Return true if we know this builtin never returns.
   bool isNoReturn(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'r') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'r') != nullptr;
   }
 
   /// Return true if we know this builtin can return twice.
   bool isReturnsTwice(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'j') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'j') != nullptr;
   }
 
   /// Returns true if this builtin does not perform the side-effects
   /// of its arguments.
   bool isUnevaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'u') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'u') != nullptr;
   }
 
   /// Return true if this is a builtin for a libc/libm function,
   /// with a "__builtin_" prefix (e.g. __builtin_abs).
   bool isLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'F') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'F') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined libc/libm
@@ -289,21 +158,21 @@ class Context {
   /// they do not, but they are recognized as builtins once we see
   /// a declaration.
   bool isPredefinedLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'f') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'f') != nullptr;
   }
 
   /// Returns true if this builtin requires appropriate header in other
   /// compilers. In Clang it will work even without including it, but we can emit
   /// a warning about missing header.
   bool isHeaderDependentFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'h') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'h') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined compiler-rt/libgcc
   /// function, such as "__clear_cache", where we know the signature a
   /// priori.
   bool isPredefinedRuntimeFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'i') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'i') != nullptr;
   }
 
   /// Determines whether this builtin is a C++ standard library function
@@ -311,7 +180,7 @@ class Context {
   /// specialization, where the signature is determined by the standard library
   /// declaration.
   bool isInStdNamespace(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'z') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'z') != nullptr;
   }
 
   /// Determines whether this builtin can have its address taken with no
@@ -325,33 +194,33 @@ class Context {
 
   /// Determines whether this builtin has custom typechecking.
   bool hasCustomTypechecking(unsigned ID) const {
-    return strchr(getAttributesString(ID), 't') != nullptr;
+    return strchr(getRecord(ID).Attributes, 't') != nullptr;
   }
 
   /// Determines whether a declaration of this builtin should be recognized
   /// even if the type doesn't match the specified signature.
   bool allowTypeMismatch(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'T') != nullptr ||
+    return strchr(getRecord(ID).Attributes, 'T') != nullptr ||
            hasCustomTypechecking(ID);
   }
 
   /// Determines whether this builtin has a result or any arguments which
   /// are pointer types.
   bool hasPtrArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '*') != nullptr;
+    return strchr(getRecord(ID).Type, '*') != nullptr;
   }
 
   /// Return true if this builtin has a result or any arguments which are
   /// reference types.
   bool hasReferenceArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '&') != nullptr ||
-           strchr(getTypeString(ID), 'A') != nullptr;
+    return strchr(getRecord(ID).Type, '&') != nullptr ||
+           strchr(getRecord(ID).Type, 'A') != nullptr;
   }
 
   /// If this is a library function that comes from a specific
   /// header, retrieve that header name.
   const char *getHeaderName(unsigned ID) const {
-    return getInfo(ID).Header.getName();
+    return getRecord(ID).Header.getName();
   }
 
   /// Determine whether this builtin is like printf in its
@@ -376,25 +245,27 @@ class Context {
   /// Such functions can be const when the MathErrno lang option and FP
   /// exceptions are disabled.
   bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'e') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'e') != nullptr;
   }
 
   bool isConstWithoutExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'g') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'g') != nullptr;
   }
 
-  const char *getRequiredFeatures(unsigned ID) const;
+  const char *getRequiredFeatures(unsigned ID) const {
+    return getRecord(ID).Features;
+  }
 
   unsigned getRequiredVectorWidth(unsigned ID) const;
 
   /// Return true if builtin ID belongs to AuxTarget.
   bool isAuxBuiltinID(unsigned ID) const {
-    return ID >= (Builtin::FirstTSBuiltin + TSInfos.size());
+    return ID >= (Builtin::FirstTSBuiltin + TSRecords.size());
   }
 
   /// Return real builtin ID (i.e. ID it would have during compilation
   /// for AuxTarget).
-  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSInfos.size(); }
+  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
 
   /// Returns true if this is a libc/libm function without the '__builtin_'
   /// prefix.
@@ -406,20 +277,16 @@ class Context {
 
   /// Return true if this function can be constant evaluated by Clang frontend.
   bool isConstantEvaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'E') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'E') != nullptr;
   }
 
   /// Returns true if this is an immediate (consteval) function
   bool isImmediate(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'G') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'G') != nullptr;
   }
 
 private:
-  std::pair<const char *, const Info &> getStrTableAndInfo(unsigned ID) const;
-
-  const Info &getInfo(unsigned ID) const {
-    return getStrTableAndInfo(ID).second;
-  }
+  const Info &getRecord(unsigned ID) const;
 
   /// Helper function for isPrintfLike and isScanfLike.
   bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index bb7d54bbb793eb..161df386f00f03 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1138,6 +1138,5 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true,
 // FIXME: Obviously incomplete.
 
 #undef BUILTIN
-#undef TARGET_BUILTIN
 #undef CUSTOM_BUILTIN
 #undef UNALIASED_CUSTOM_BUILTIN
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 52a1ac9781395c..4420228793e95f 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -16,7 +16,6 @@
 
 #include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/BitmaskEnum.h"
-#include "clang/Basic/Builtins.h"
 #include "clang/Basic/CFProtectionOptions.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/LLVM.h"
@@ -1010,11 +1009,11 @@ class TargetInfo : public TransferrableTargetInfo,
   virtual void getTargetDefines(const LangOptions &Opts,
                                 MacroBuilder &Builder) const = 0;
 
-  /// Return information about target-specific builtins for the current primary
-  /// target, and info about which builtins are non-portable across the current
-  /// set of primary and secondary targets.
-  virtual std::pair<const char *, ArrayRef<Builtin::Info>>
-  getTargetBuiltinStorage() const = 0;
+
+  /// Return information about target-specific builtins for
+  /// the current primary target, and info about which builtins are non-portable
+  /// across the current set of primary and secondary targets.
+  virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
 
   /// Returns target-specific min and max values VScale_Range.
   virtual std::optional<std::pair<unsigned, unsigned>>
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index c991139b8d5ad7..25a601573698e7 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -29,93 +29,54 @@ const char *HeaderDesc::getName() const {
   llvm_unreachable("Unknown HeaderDesc::HeaderID enum");
 }
 
-static constexpr auto BuiltinStorage =
-    Builtin::Storage<Builtin::FirstTSBuiltin>::Make(
-        CLANG_BUILTIN_STR_TABLE("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_STR_TABLE
+static constexpr Builtin::Info BuiltinInfo[] = {
+    {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER,
+     ALL_LANGUAGES},
+#define BUILTIN(ID, TYPE, ATTRS)                                               \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS)                                    \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS},
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS)                             \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS},
 #include "clang/Basic/Builtins.inc"
-            ,
-        {CLANG_BUILTIN_ENTRY("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_ENTRY
-#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
-#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
-#include "clang/Basic/Builtins.inc"
-        });
+};
 
-std::pair<const char *, const Builtin::Info &>
-Builtin::Context::getStrTableAndInfo(unsigned ID) const {
+const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
   if (ID < Builtin::FirstTSBuiltin)
-    return {BuiltinStorage.StringTable, BuiltinStorage.Infos[ID]};
-  assert(
-      ((ID - Builtin::FirstTSBuiltin) < (TSInfos.size() + AuxTSInfos.size())) &&
-      "Invalid builtin ID!");
+    return BuiltinInfo[ID];
+  assert(((ID - Builtin::FirstTSBuiltin) <
+          (TSRecords.size() + AuxTSRecords.size())) &&
+         "Invalid builtin ID!");
   if (isAuxBuiltinID(ID))
-    return {AuxTSStrTable,
-            AuxTSInfos[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin]};
-  return {TSStrTable, TSInfos[ID - Builtin::FirstTSBuiltin]};
-}
-
-static llvm::StringRef getStrFromTable(const char *StrTable, int Offset) {
-  return &StrTable[Offset];
-}
-
-/// Return the identifier name for the specified builtin,
-/// e.g. "__builtin_abs".
-llvm::StringRef Builtin::Context::getName(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Name);
-}
-
-const char *Builtin::Context::getTypeString(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Type).data();
-}
-
-const char *Builtin::Context::getAt...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Dec 12, 2024

@llvm/pr-subscribers-backend-hexagon

Author: Chandler Carruth (chandlerc)

Changes

Reverts llvm/llvm-project#118734

There is currently a specific (unreleased?) version of MSVC and builder that are crashing / failing on this code. We don't know why as all the other build bots and at least some folks' local Windows builds work fine.

This is a candidate revert to help the relevant folks catch their builders up and have time to debug the issue. However, it should only be submitted if we have a fairly concrete ETA on figuring out what is going wrong and suggesting some path forward given that no one else has thus far reproduced the issue.


Patch is 77.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119638.diff

48 Files Affected:

  • (modified) clang/include/clang/Basic/Builtins.h (+36-169)
  • (modified) clang/include/clang/Basic/BuiltinsPPC.def (-1)
  • (modified) clang/include/clang/Basic/TargetInfo.h (+5-6)
  • (modified) clang/lib/Basic/Builtins.cpp (+39-81)
  • (modified) clang/lib/Basic/Targets/AArch64.cpp (+28-32)
  • (modified) clang/lib/Basic/Targets/AArch64.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AMDGPU.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/AMDGPU.h (+1-2)
  • (modified) clang/lib/Basic/Targets/ARC.h (+1-4)
  • (modified) clang/lib/Basic/Targets/ARM.cpp (+21-24)
  • (modified) clang/lib/Basic/Targets/ARM.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AVR.h (+1-4)
  • (modified) clang/lib/Basic/Targets/BPF.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/BPF.h (+1-2)
  • (modified) clang/lib/Basic/Targets/CSKY.cpp (+4)
  • (modified) clang/lib/Basic/Targets/CSKY.h (+1-4)
  • (modified) clang/lib/Basic/Targets/DirectX.h (+1-4)
  • (modified) clang/lib/Basic/Targets/Hexagon.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/Hexagon.h (+1-2)
  • (modified) clang/lib/Basic/Targets/Lanai.h (+1-4)
  • (modified) clang/lib/Basic/Targets/LoongArch.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/LoongArch.h (+1-2)
  • (modified) clang/lib/Basic/Targets/M68k.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/M68k.h (+1-2)
  • (modified) clang/lib/Basic/Targets/MSP430.h (+2-3)
  • (modified) clang/lib/Basic/Targets/Mips.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/Mips.h (+1-2)
  • (modified) clang/lib/Basic/Targets/NVPTX.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/NVPTX.h (+1-2)
  • (modified) clang/lib/Basic/Targets/PNaCl.h (+1-4)
  • (modified) clang/lib/Basic/Targets/PPC.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/PPC.h (+1-2)
  • (modified) clang/lib/Basic/Targets/RISCV.cpp (+13-19)
  • (modified) clang/lib/Basic/Targets/RISCV.h (+1-2)
  • (modified) clang/lib/Basic/Targets/SPIR.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/SPIR.h (+2-6)
  • (modified) clang/lib/Basic/Targets/Sparc.h (+2-3)
  • (modified) clang/lib/Basic/Targets/SystemZ.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/SystemZ.h (+1-2)
  • (modified) clang/lib/Basic/Targets/TCE.h (+1-4)
  • (modified) clang/lib/Basic/Targets/VE.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/VE.h (+1-2)
  • (modified) clang/lib/Basic/Targets/WebAssembly.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/WebAssembly.h (+1-2)
  • (modified) clang/lib/Basic/Targets/X86.cpp (+26-42)
  • (modified) clang/lib/Basic/Targets/X86.h (+2-4)
  • (modified) clang/lib/Basic/Targets/XCore.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/XCore.h (+1-2)
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index a9bb6efe850cc6..89f65682ae5b41 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -55,7 +55,6 @@ struct HeaderDesc {
 #undef HEADER
   } ID;
 
-  constexpr HeaderDesc() : ID() {}
   constexpr HeaderDesc(HeaderID ID) : ID(ID) {}
 
   const char *getName() const;
@@ -69,140 +68,14 @@ enum ID {
   FirstTSBuiltin
 };
 
-// The info used to represent each builtin.
 struct Info {
-  // 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;
-
+  llvm::StringLiteral Name;
+  const char *Type, *Attributes;
+  const char *Features;
   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 {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("")                       \
-  }
-
-// A detail macro used internally to compute the desired string table
-// `StrOffsets` struct for arguments to `Storage::Make`.
-#define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE)      \
-  Builtin::Info::StrOffsets {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof(FEATURE)                  \
-  }
-
-// A set of macros that can be used with builtin `.def' files as an X-macro to
-// create an `Info` struct for a particular builtin. It both computes the
-// `StrOffsets` value for the string table (the lengths here, translated to
-// offsets by the Storage::Make function), and the other metadata for each
-// builtin.
-//
-// There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`,
-// `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`.
-#define CLANG_BUILTIN_ENTRY(ID, TYPE, ATTRS)                                   \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_LANGBUILTIN_ENTRY(ID, TYPE, ATTRS, LANG)                         \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, LANG},
-#define CLANG_LIBBUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG)                  \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::HEADER, LANG},
-#define CLANG_TARGET_BUILTIN_ENTRY(ID, TYPE, ATTRS, FEATURE)                   \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_TARGET_HEADER_BUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG,       \
-                                          FEATURE)                             \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::HEADER, LANG},
-
 /// Holds information about both target-independent and
 /// target-specific builtins, allowing easy queries by clients.
 ///
@@ -210,11 +83,8 @@ template <size_t N> struct Storage {
 /// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
 /// be translated back with getAuxBuiltinID() before use.
 class Context {
-  const char *TSStrTable = nullptr;
-  const char *AuxTSStrTable = nullptr;
-
-  llvm::ArrayRef<Info> TSInfos;
-  llvm::ArrayRef<Info> AuxTSInfos;
+  llvm::ArrayRef<Info> TSRecords;
+  llvm::ArrayRef<Info> AuxTSRecords;
 
 public:
   Context() = default;
@@ -230,13 +100,12 @@ class Context {
 
   /// Return the identifier name for the specified builtin,
   /// e.g. "__builtin_abs".
-  llvm::StringRef getName(unsigned ID) const;
+  llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
 
   /// Get the type descriptor string for the specified builtin.
-  const char *getTypeString(unsigned ID) const;
-
-  /// Get the attributes descriptor string for the specified builtin.
-  const char *getAttributesString(unsigned ID) const;
+  const char *getTypeString(unsigned ID) const {
+    return getRecord(ID).Type;
+  }
 
   /// Return true if this function is a target-specific builtin.
   bool isTSBuiltin(unsigned ID) const {
@@ -245,40 +114,40 @@ class Context {
 
   /// Return true if this function has no side effects.
   bool isPure(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'U') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'U') != nullptr;
   }
 
   /// Return true if this function has no side effects and doesn't
   /// read memory.
   bool isConst(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'c') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'c') != nullptr;
   }
 
   /// Return true if we know this builtin never throws an exception.
   bool isNoThrow(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'n') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'n') != nullptr;
   }
 
   /// Return true if we know this builtin never returns.
   bool isNoReturn(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'r') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'r') != nullptr;
   }
 
   /// Return true if we know this builtin can return twice.
   bool isReturnsTwice(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'j') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'j') != nullptr;
   }
 
   /// Returns true if this builtin does not perform the side-effects
   /// of its arguments.
   bool isUnevaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'u') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'u') != nullptr;
   }
 
   /// Return true if this is a builtin for a libc/libm function,
   /// with a "__builtin_" prefix (e.g. __builtin_abs).
   bool isLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'F') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'F') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined libc/libm
@@ -289,21 +158,21 @@ class Context {
   /// they do not, but they are recognized as builtins once we see
   /// a declaration.
   bool isPredefinedLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'f') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'f') != nullptr;
   }
 
   /// Returns true if this builtin requires appropriate header in other
   /// compilers. In Clang it will work even without including it, but we can emit
   /// a warning about missing header.
   bool isHeaderDependentFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'h') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'h') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined compiler-rt/libgcc
   /// function, such as "__clear_cache", where we know the signature a
   /// priori.
   bool isPredefinedRuntimeFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'i') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'i') != nullptr;
   }
 
   /// Determines whether this builtin is a C++ standard library function
@@ -311,7 +180,7 @@ class Context {
   /// specialization, where the signature is determined by the standard library
   /// declaration.
   bool isInStdNamespace(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'z') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'z') != nullptr;
   }
 
   /// Determines whether this builtin can have its address taken with no
@@ -325,33 +194,33 @@ class Context {
 
   /// Determines whether this builtin has custom typechecking.
   bool hasCustomTypechecking(unsigned ID) const {
-    return strchr(getAttributesString(ID), 't') != nullptr;
+    return strchr(getRecord(ID).Attributes, 't') != nullptr;
   }
 
   /// Determines whether a declaration of this builtin should be recognized
   /// even if the type doesn't match the specified signature.
   bool allowTypeMismatch(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'T') != nullptr ||
+    return strchr(getRecord(ID).Attributes, 'T') != nullptr ||
            hasCustomTypechecking(ID);
   }
 
   /// Determines whether this builtin has a result or any arguments which
   /// are pointer types.
   bool hasPtrArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '*') != nullptr;
+    return strchr(getRecord(ID).Type, '*') != nullptr;
   }
 
   /// Return true if this builtin has a result or any arguments which are
   /// reference types.
   bool hasReferenceArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '&') != nullptr ||
-           strchr(getTypeString(ID), 'A') != nullptr;
+    return strchr(getRecord(ID).Type, '&') != nullptr ||
+           strchr(getRecord(ID).Type, 'A') != nullptr;
   }
 
   /// If this is a library function that comes from a specific
   /// header, retrieve that header name.
   const char *getHeaderName(unsigned ID) const {
-    return getInfo(ID).Header.getName();
+    return getRecord(ID).Header.getName();
   }
 
   /// Determine whether this builtin is like printf in its
@@ -376,25 +245,27 @@ class Context {
   /// Such functions can be const when the MathErrno lang option and FP
   /// exceptions are disabled.
   bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'e') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'e') != nullptr;
   }
 
   bool isConstWithoutExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'g') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'g') != nullptr;
   }
 
-  const char *getRequiredFeatures(unsigned ID) const;
+  const char *getRequiredFeatures(unsigned ID) const {
+    return getRecord(ID).Features;
+  }
 
   unsigned getRequiredVectorWidth(unsigned ID) const;
 
   /// Return true if builtin ID belongs to AuxTarget.
   bool isAuxBuiltinID(unsigned ID) const {
-    return ID >= (Builtin::FirstTSBuiltin + TSInfos.size());
+    return ID >= (Builtin::FirstTSBuiltin + TSRecords.size());
   }
 
   /// Return real builtin ID (i.e. ID it would have during compilation
   /// for AuxTarget).
-  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSInfos.size(); }
+  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
 
   /// Returns true if this is a libc/libm function without the '__builtin_'
   /// prefix.
@@ -406,20 +277,16 @@ class Context {
 
   /// Return true if this function can be constant evaluated by Clang frontend.
   bool isConstantEvaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'E') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'E') != nullptr;
   }
 
   /// Returns true if this is an immediate (consteval) function
   bool isImmediate(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'G') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'G') != nullptr;
   }
 
 private:
-  std::pair<const char *, const Info &> getStrTableAndInfo(unsigned ID) const;
-
-  const Info &getInfo(unsigned ID) const {
-    return getStrTableAndInfo(ID).second;
-  }
+  const Info &getRecord(unsigned ID) const;
 
   /// Helper function for isPrintfLike and isScanfLike.
   bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index bb7d54bbb793eb..161df386f00f03 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1138,6 +1138,5 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true,
 // FIXME: Obviously incomplete.
 
 #undef BUILTIN
-#undef TARGET_BUILTIN
 #undef CUSTOM_BUILTIN
 #undef UNALIASED_CUSTOM_BUILTIN
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 52a1ac9781395c..4420228793e95f 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -16,7 +16,6 @@
 
 #include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/BitmaskEnum.h"
-#include "clang/Basic/Builtins.h"
 #include "clang/Basic/CFProtectionOptions.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/LLVM.h"
@@ -1010,11 +1009,11 @@ class TargetInfo : public TransferrableTargetInfo,
   virtual void getTargetDefines(const LangOptions &Opts,
                                 MacroBuilder &Builder) const = 0;
 
-  /// Return information about target-specific builtins for the current primary
-  /// target, and info about which builtins are non-portable across the current
-  /// set of primary and secondary targets.
-  virtual std::pair<const char *, ArrayRef<Builtin::Info>>
-  getTargetBuiltinStorage() const = 0;
+
+  /// Return information about target-specific builtins for
+  /// the current primary target, and info about which builtins are non-portable
+  /// across the current set of primary and secondary targets.
+  virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
 
   /// Returns target-specific min and max values VScale_Range.
   virtual std::optional<std::pair<unsigned, unsigned>>
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index c991139b8d5ad7..25a601573698e7 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -29,93 +29,54 @@ const char *HeaderDesc::getName() const {
   llvm_unreachable("Unknown HeaderDesc::HeaderID enum");
 }
 
-static constexpr auto BuiltinStorage =
-    Builtin::Storage<Builtin::FirstTSBuiltin>::Make(
-        CLANG_BUILTIN_STR_TABLE("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_STR_TABLE
+static constexpr Builtin::Info BuiltinInfo[] = {
+    {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER,
+     ALL_LANGUAGES},
+#define BUILTIN(ID, TYPE, ATTRS)                                               \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS)                                    \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS},
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS)                             \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS},
 #include "clang/Basic/Builtins.inc"
-            ,
-        {CLANG_BUILTIN_ENTRY("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_ENTRY
-#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
-#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
-#include "clang/Basic/Builtins.inc"
-        });
+};
 
-std::pair<const char *, const Builtin::Info &>
-Builtin::Context::getStrTableAndInfo(unsigned ID) const {
+const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
   if (ID < Builtin::FirstTSBuiltin)
-    return {BuiltinStorage.StringTable, BuiltinStorage.Infos[ID]};
-  assert(
-      ((ID - Builtin::FirstTSBuiltin) < (TSInfos.size() + AuxTSInfos.size())) &&
-      "Invalid builtin ID!");
+    return BuiltinInfo[ID];
+  assert(((ID - Builtin::FirstTSBuiltin) <
+          (TSRecords.size() + AuxTSRecords.size())) &&
+         "Invalid builtin ID!");
   if (isAuxBuiltinID(ID))
-    return {AuxTSStrTable,
-            AuxTSInfos[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin]};
-  return {TSStrTable, TSInfos[ID - Builtin::FirstTSBuiltin]};
-}
-
-static llvm::StringRef getStrFromTable(const char *StrTable, int Offset) {
-  return &StrTable[Offset];
-}
-
-/// Return the identifier name for the specified builtin,
-/// e.g. "__builtin_abs".
-llvm::StringRef Builtin::Context::getName(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Name);
-}
-
-const char *Builtin::Context::getTypeString(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Type).data();
-}
-
-const char *Builtin::Context::getAt...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Dec 12, 2024

@llvm/pr-subscribers-backend-risc-v

Author: Chandler Carruth (chandlerc)

Changes

Reverts llvm/llvm-project#118734

There is currently a specific (unreleased?) version of MSVC and builder that are crashing / failing on this code. We don't know why as all the other build bots and at least some folks' local Windows builds work fine.

This is a candidate revert to help the relevant folks catch their builders up and have time to debug the issue. However, it should only be submitted if we have a fairly concrete ETA on figuring out what is going wrong and suggesting some path forward given that no one else has thus far reproduced the issue.


Patch is 77.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119638.diff

48 Files Affected:

  • (modified) clang/include/clang/Basic/Builtins.h (+36-169)
  • (modified) clang/include/clang/Basic/BuiltinsPPC.def (-1)
  • (modified) clang/include/clang/Basic/TargetInfo.h (+5-6)
  • (modified) clang/lib/Basic/Builtins.cpp (+39-81)
  • (modified) clang/lib/Basic/Targets/AArch64.cpp (+28-32)
  • (modified) clang/lib/Basic/Targets/AArch64.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AMDGPU.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/AMDGPU.h (+1-2)
  • (modified) clang/lib/Basic/Targets/ARC.h (+1-4)
  • (modified) clang/lib/Basic/Targets/ARM.cpp (+21-24)
  • (modified) clang/lib/Basic/Targets/ARM.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AVR.h (+1-4)
  • (modified) clang/lib/Basic/Targets/BPF.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/BPF.h (+1-2)
  • (modified) clang/lib/Basic/Targets/CSKY.cpp (+4)
  • (modified) clang/lib/Basic/Targets/CSKY.h (+1-4)
  • (modified) clang/lib/Basic/Targets/DirectX.h (+1-4)
  • (modified) clang/lib/Basic/Targets/Hexagon.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/Hexagon.h (+1-2)
  • (modified) clang/lib/Basic/Targets/Lanai.h (+1-4)
  • (modified) clang/lib/Basic/Targets/LoongArch.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/LoongArch.h (+1-2)
  • (modified) clang/lib/Basic/Targets/M68k.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/M68k.h (+1-2)
  • (modified) clang/lib/Basic/Targets/MSP430.h (+2-3)
  • (modified) clang/lib/Basic/Targets/Mips.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/Mips.h (+1-2)
  • (modified) clang/lib/Basic/Targets/NVPTX.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/NVPTX.h (+1-2)
  • (modified) clang/lib/Basic/Targets/PNaCl.h (+1-4)
  • (modified) clang/lib/Basic/Targets/PPC.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/PPC.h (+1-2)
  • (modified) clang/lib/Basic/Targets/RISCV.cpp (+13-19)
  • (modified) clang/lib/Basic/Targets/RISCV.h (+1-2)
  • (modified) clang/lib/Basic/Targets/SPIR.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/SPIR.h (+2-6)
  • (modified) clang/lib/Basic/Targets/Sparc.h (+2-3)
  • (modified) clang/lib/Basic/Targets/SystemZ.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/SystemZ.h (+1-2)
  • (modified) clang/lib/Basic/Targets/TCE.h (+1-4)
  • (modified) clang/lib/Basic/Targets/VE.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/VE.h (+1-2)
  • (modified) clang/lib/Basic/Targets/WebAssembly.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/WebAssembly.h (+1-2)
  • (modified) clang/lib/Basic/Targets/X86.cpp (+26-42)
  • (modified) clang/lib/Basic/Targets/X86.h (+2-4)
  • (modified) clang/lib/Basic/Targets/XCore.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/XCore.h (+1-2)
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index a9bb6efe850cc6..89f65682ae5b41 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -55,7 +55,6 @@ struct HeaderDesc {
 #undef HEADER
   } ID;
 
-  constexpr HeaderDesc() : ID() {}
   constexpr HeaderDesc(HeaderID ID) : ID(ID) {}
 
   const char *getName() const;
@@ -69,140 +68,14 @@ enum ID {
   FirstTSBuiltin
 };
 
-// The info used to represent each builtin.
 struct Info {
-  // 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;
-
+  llvm::StringLiteral Name;
+  const char *Type, *Attributes;
+  const char *Features;
   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 {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("")                       \
-  }
-
-// A detail macro used internally to compute the desired string table
-// `StrOffsets` struct for arguments to `Storage::Make`.
-#define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE)      \
-  Builtin::Info::StrOffsets {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof(FEATURE)                  \
-  }
-
-// A set of macros that can be used with builtin `.def' files as an X-macro to
-// create an `Info` struct for a particular builtin. It both computes the
-// `StrOffsets` value for the string table (the lengths here, translated to
-// offsets by the Storage::Make function), and the other metadata for each
-// builtin.
-//
-// There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`,
-// `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`.
-#define CLANG_BUILTIN_ENTRY(ID, TYPE, ATTRS)                                   \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_LANGBUILTIN_ENTRY(ID, TYPE, ATTRS, LANG)                         \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, LANG},
-#define CLANG_LIBBUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG)                  \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::HEADER, LANG},
-#define CLANG_TARGET_BUILTIN_ENTRY(ID, TYPE, ATTRS, FEATURE)                   \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_TARGET_HEADER_BUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG,       \
-                                          FEATURE)                             \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::HEADER, LANG},
-
 /// Holds information about both target-independent and
 /// target-specific builtins, allowing easy queries by clients.
 ///
@@ -210,11 +83,8 @@ template <size_t N> struct Storage {
 /// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
 /// be translated back with getAuxBuiltinID() before use.
 class Context {
-  const char *TSStrTable = nullptr;
-  const char *AuxTSStrTable = nullptr;
-
-  llvm::ArrayRef<Info> TSInfos;
-  llvm::ArrayRef<Info> AuxTSInfos;
+  llvm::ArrayRef<Info> TSRecords;
+  llvm::ArrayRef<Info> AuxTSRecords;
 
 public:
   Context() = default;
@@ -230,13 +100,12 @@ class Context {
 
   /// Return the identifier name for the specified builtin,
   /// e.g. "__builtin_abs".
-  llvm::StringRef getName(unsigned ID) const;
+  llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
 
   /// Get the type descriptor string for the specified builtin.
-  const char *getTypeString(unsigned ID) const;
-
-  /// Get the attributes descriptor string for the specified builtin.
-  const char *getAttributesString(unsigned ID) const;
+  const char *getTypeString(unsigned ID) const {
+    return getRecord(ID).Type;
+  }
 
   /// Return true if this function is a target-specific builtin.
   bool isTSBuiltin(unsigned ID) const {
@@ -245,40 +114,40 @@ class Context {
 
   /// Return true if this function has no side effects.
   bool isPure(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'U') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'U') != nullptr;
   }
 
   /// Return true if this function has no side effects and doesn't
   /// read memory.
   bool isConst(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'c') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'c') != nullptr;
   }
 
   /// Return true if we know this builtin never throws an exception.
   bool isNoThrow(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'n') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'n') != nullptr;
   }
 
   /// Return true if we know this builtin never returns.
   bool isNoReturn(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'r') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'r') != nullptr;
   }
 
   /// Return true if we know this builtin can return twice.
   bool isReturnsTwice(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'j') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'j') != nullptr;
   }
 
   /// Returns true if this builtin does not perform the side-effects
   /// of its arguments.
   bool isUnevaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'u') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'u') != nullptr;
   }
 
   /// Return true if this is a builtin for a libc/libm function,
   /// with a "__builtin_" prefix (e.g. __builtin_abs).
   bool isLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'F') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'F') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined libc/libm
@@ -289,21 +158,21 @@ class Context {
   /// they do not, but they are recognized as builtins once we see
   /// a declaration.
   bool isPredefinedLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'f') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'f') != nullptr;
   }
 
   /// Returns true if this builtin requires appropriate header in other
   /// compilers. In Clang it will work even without including it, but we can emit
   /// a warning about missing header.
   bool isHeaderDependentFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'h') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'h') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined compiler-rt/libgcc
   /// function, such as "__clear_cache", where we know the signature a
   /// priori.
   bool isPredefinedRuntimeFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'i') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'i') != nullptr;
   }
 
   /// Determines whether this builtin is a C++ standard library function
@@ -311,7 +180,7 @@ class Context {
   /// specialization, where the signature is determined by the standard library
   /// declaration.
   bool isInStdNamespace(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'z') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'z') != nullptr;
   }
 
   /// Determines whether this builtin can have its address taken with no
@@ -325,33 +194,33 @@ class Context {
 
   /// Determines whether this builtin has custom typechecking.
   bool hasCustomTypechecking(unsigned ID) const {
-    return strchr(getAttributesString(ID), 't') != nullptr;
+    return strchr(getRecord(ID).Attributes, 't') != nullptr;
   }
 
   /// Determines whether a declaration of this builtin should be recognized
   /// even if the type doesn't match the specified signature.
   bool allowTypeMismatch(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'T') != nullptr ||
+    return strchr(getRecord(ID).Attributes, 'T') != nullptr ||
            hasCustomTypechecking(ID);
   }
 
   /// Determines whether this builtin has a result or any arguments which
   /// are pointer types.
   bool hasPtrArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '*') != nullptr;
+    return strchr(getRecord(ID).Type, '*') != nullptr;
   }
 
   /// Return true if this builtin has a result or any arguments which are
   /// reference types.
   bool hasReferenceArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '&') != nullptr ||
-           strchr(getTypeString(ID), 'A') != nullptr;
+    return strchr(getRecord(ID).Type, '&') != nullptr ||
+           strchr(getRecord(ID).Type, 'A') != nullptr;
   }
 
   /// If this is a library function that comes from a specific
   /// header, retrieve that header name.
   const char *getHeaderName(unsigned ID) const {
-    return getInfo(ID).Header.getName();
+    return getRecord(ID).Header.getName();
   }
 
   /// Determine whether this builtin is like printf in its
@@ -376,25 +245,27 @@ class Context {
   /// Such functions can be const when the MathErrno lang option and FP
   /// exceptions are disabled.
   bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'e') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'e') != nullptr;
   }
 
   bool isConstWithoutExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'g') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'g') != nullptr;
   }
 
-  const char *getRequiredFeatures(unsigned ID) const;
+  const char *getRequiredFeatures(unsigned ID) const {
+    return getRecord(ID).Features;
+  }
 
   unsigned getRequiredVectorWidth(unsigned ID) const;
 
   /// Return true if builtin ID belongs to AuxTarget.
   bool isAuxBuiltinID(unsigned ID) const {
-    return ID >= (Builtin::FirstTSBuiltin + TSInfos.size());
+    return ID >= (Builtin::FirstTSBuiltin + TSRecords.size());
   }
 
   /// Return real builtin ID (i.e. ID it would have during compilation
   /// for AuxTarget).
-  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSInfos.size(); }
+  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
 
   /// Returns true if this is a libc/libm function without the '__builtin_'
   /// prefix.
@@ -406,20 +277,16 @@ class Context {
 
   /// Return true if this function can be constant evaluated by Clang frontend.
   bool isConstantEvaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'E') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'E') != nullptr;
   }
 
   /// Returns true if this is an immediate (consteval) function
   bool isImmediate(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'G') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'G') != nullptr;
   }
 
 private:
-  std::pair<const char *, const Info &> getStrTableAndInfo(unsigned ID) const;
-
-  const Info &getInfo(unsigned ID) const {
-    return getStrTableAndInfo(ID).second;
-  }
+  const Info &getRecord(unsigned ID) const;
 
   /// Helper function for isPrintfLike and isScanfLike.
   bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index bb7d54bbb793eb..161df386f00f03 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1138,6 +1138,5 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true,
 // FIXME: Obviously incomplete.
 
 #undef BUILTIN
-#undef TARGET_BUILTIN
 #undef CUSTOM_BUILTIN
 #undef UNALIASED_CUSTOM_BUILTIN
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 52a1ac9781395c..4420228793e95f 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -16,7 +16,6 @@
 
 #include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/BitmaskEnum.h"
-#include "clang/Basic/Builtins.h"
 #include "clang/Basic/CFProtectionOptions.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/LLVM.h"
@@ -1010,11 +1009,11 @@ class TargetInfo : public TransferrableTargetInfo,
   virtual void getTargetDefines(const LangOptions &Opts,
                                 MacroBuilder &Builder) const = 0;
 
-  /// Return information about target-specific builtins for the current primary
-  /// target, and info about which builtins are non-portable across the current
-  /// set of primary and secondary targets.
-  virtual std::pair<const char *, ArrayRef<Builtin::Info>>
-  getTargetBuiltinStorage() const = 0;
+
+  /// Return information about target-specific builtins for
+  /// the current primary target, and info about which builtins are non-portable
+  /// across the current set of primary and secondary targets.
+  virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
 
   /// Returns target-specific min and max values VScale_Range.
   virtual std::optional<std::pair<unsigned, unsigned>>
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index c991139b8d5ad7..25a601573698e7 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -29,93 +29,54 @@ const char *HeaderDesc::getName() const {
   llvm_unreachable("Unknown HeaderDesc::HeaderID enum");
 }
 
-static constexpr auto BuiltinStorage =
-    Builtin::Storage<Builtin::FirstTSBuiltin>::Make(
-        CLANG_BUILTIN_STR_TABLE("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_STR_TABLE
+static constexpr Builtin::Info BuiltinInfo[] = {
+    {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER,
+     ALL_LANGUAGES},
+#define BUILTIN(ID, TYPE, ATTRS)                                               \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS)                                    \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS},
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS)                             \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS},
 #include "clang/Basic/Builtins.inc"
-            ,
-        {CLANG_BUILTIN_ENTRY("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_ENTRY
-#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
-#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
-#include "clang/Basic/Builtins.inc"
-        });
+};
 
-std::pair<const char *, const Builtin::Info &>
-Builtin::Context::getStrTableAndInfo(unsigned ID) const {
+const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
   if (ID < Builtin::FirstTSBuiltin)
-    return {BuiltinStorage.StringTable, BuiltinStorage.Infos[ID]};
-  assert(
-      ((ID - Builtin::FirstTSBuiltin) < (TSInfos.size() + AuxTSInfos.size())) &&
-      "Invalid builtin ID!");
+    return BuiltinInfo[ID];
+  assert(((ID - Builtin::FirstTSBuiltin) <
+          (TSRecords.size() + AuxTSRecords.size())) &&
+         "Invalid builtin ID!");
   if (isAuxBuiltinID(ID))
-    return {AuxTSStrTable,
-            AuxTSInfos[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin]};
-  return {TSStrTable, TSInfos[ID - Builtin::FirstTSBuiltin]};
-}
-
-static llvm::StringRef getStrFromTable(const char *StrTable, int Offset) {
-  return &StrTable[Offset];
-}
-
-/// Return the identifier name for the specified builtin,
-/// e.g. "__builtin_abs".
-llvm::StringRef Builtin::Context::getName(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Name);
-}
-
-const char *Builtin::Context::getTypeString(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Type).data();
-}
-
-const char *Builtin::Context::getAt...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Dec 12, 2024

@llvm/pr-subscribers-backend-webassembly

Author: Chandler Carruth (chandlerc)

Changes

Reverts llvm/llvm-project#118734

There is currently a specific (unreleased?) version of MSVC and builder that are crashing / failing on this code. We don't know why as all the other build bots and at least some folks' local Windows builds work fine.

This is a candidate revert to help the relevant folks catch their builders up and have time to debug the issue. However, it should only be submitted if we have a fairly concrete ETA on figuring out what is going wrong and suggesting some path forward given that no one else has thus far reproduced the issue.


Patch is 77.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119638.diff

48 Files Affected:

  • (modified) clang/include/clang/Basic/Builtins.h (+36-169)
  • (modified) clang/include/clang/Basic/BuiltinsPPC.def (-1)
  • (modified) clang/include/clang/Basic/TargetInfo.h (+5-6)
  • (modified) clang/lib/Basic/Builtins.cpp (+39-81)
  • (modified) clang/lib/Basic/Targets/AArch64.cpp (+28-32)
  • (modified) clang/lib/Basic/Targets/AArch64.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AMDGPU.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/AMDGPU.h (+1-2)
  • (modified) clang/lib/Basic/Targets/ARC.h (+1-4)
  • (modified) clang/lib/Basic/Targets/ARM.cpp (+21-24)
  • (modified) clang/lib/Basic/Targets/ARM.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AVR.h (+1-4)
  • (modified) clang/lib/Basic/Targets/BPF.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/BPF.h (+1-2)
  • (modified) clang/lib/Basic/Targets/CSKY.cpp (+4)
  • (modified) clang/lib/Basic/Targets/CSKY.h (+1-4)
  • (modified) clang/lib/Basic/Targets/DirectX.h (+1-4)
  • (modified) clang/lib/Basic/Targets/Hexagon.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/Hexagon.h (+1-2)
  • (modified) clang/lib/Basic/Targets/Lanai.h (+1-4)
  • (modified) clang/lib/Basic/Targets/LoongArch.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/LoongArch.h (+1-2)
  • (modified) clang/lib/Basic/Targets/M68k.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/M68k.h (+1-2)
  • (modified) clang/lib/Basic/Targets/MSP430.h (+2-3)
  • (modified) clang/lib/Basic/Targets/Mips.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/Mips.h (+1-2)
  • (modified) clang/lib/Basic/Targets/NVPTX.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/NVPTX.h (+1-2)
  • (modified) clang/lib/Basic/Targets/PNaCl.h (+1-4)
  • (modified) clang/lib/Basic/Targets/PPC.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/PPC.h (+1-2)
  • (modified) clang/lib/Basic/Targets/RISCV.cpp (+13-19)
  • (modified) clang/lib/Basic/Targets/RISCV.h (+1-2)
  • (modified) clang/lib/Basic/Targets/SPIR.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/SPIR.h (+2-6)
  • (modified) clang/lib/Basic/Targets/Sparc.h (+2-3)
  • (modified) clang/lib/Basic/Targets/SystemZ.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/SystemZ.h (+1-2)
  • (modified) clang/lib/Basic/Targets/TCE.h (+1-4)
  • (modified) clang/lib/Basic/Targets/VE.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/VE.h (+1-2)
  • (modified) clang/lib/Basic/Targets/WebAssembly.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/WebAssembly.h (+1-2)
  • (modified) clang/lib/Basic/Targets/X86.cpp (+26-42)
  • (modified) clang/lib/Basic/Targets/X86.h (+2-4)
  • (modified) clang/lib/Basic/Targets/XCore.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/XCore.h (+1-2)
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index a9bb6efe850cc6..89f65682ae5b41 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -55,7 +55,6 @@ struct HeaderDesc {
 #undef HEADER
   } ID;
 
-  constexpr HeaderDesc() : ID() {}
   constexpr HeaderDesc(HeaderID ID) : ID(ID) {}
 
   const char *getName() const;
@@ -69,140 +68,14 @@ enum ID {
   FirstTSBuiltin
 };
 
-// The info used to represent each builtin.
 struct Info {
-  // 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;
-
+  llvm::StringLiteral Name;
+  const char *Type, *Attributes;
+  const char *Features;
   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 {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("")                       \
-  }
-
-// A detail macro used internally to compute the desired string table
-// `StrOffsets` struct for arguments to `Storage::Make`.
-#define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE)      \
-  Builtin::Info::StrOffsets {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof(FEATURE)                  \
-  }
-
-// A set of macros that can be used with builtin `.def' files as an X-macro to
-// create an `Info` struct for a particular builtin. It both computes the
-// `StrOffsets` value for the string table (the lengths here, translated to
-// offsets by the Storage::Make function), and the other metadata for each
-// builtin.
-//
-// There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`,
-// `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`.
-#define CLANG_BUILTIN_ENTRY(ID, TYPE, ATTRS)                                   \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_LANGBUILTIN_ENTRY(ID, TYPE, ATTRS, LANG)                         \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, LANG},
-#define CLANG_LIBBUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG)                  \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::HEADER, LANG},
-#define CLANG_TARGET_BUILTIN_ENTRY(ID, TYPE, ATTRS, FEATURE)                   \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_TARGET_HEADER_BUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG,       \
-                                          FEATURE)                             \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::HEADER, LANG},
-
 /// Holds information about both target-independent and
 /// target-specific builtins, allowing easy queries by clients.
 ///
@@ -210,11 +83,8 @@ template <size_t N> struct Storage {
 /// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
 /// be translated back with getAuxBuiltinID() before use.
 class Context {
-  const char *TSStrTable = nullptr;
-  const char *AuxTSStrTable = nullptr;
-
-  llvm::ArrayRef<Info> TSInfos;
-  llvm::ArrayRef<Info> AuxTSInfos;
+  llvm::ArrayRef<Info> TSRecords;
+  llvm::ArrayRef<Info> AuxTSRecords;
 
 public:
   Context() = default;
@@ -230,13 +100,12 @@ class Context {
 
   /// Return the identifier name for the specified builtin,
   /// e.g. "__builtin_abs".
-  llvm::StringRef getName(unsigned ID) const;
+  llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
 
   /// Get the type descriptor string for the specified builtin.
-  const char *getTypeString(unsigned ID) const;
-
-  /// Get the attributes descriptor string for the specified builtin.
-  const char *getAttributesString(unsigned ID) const;
+  const char *getTypeString(unsigned ID) const {
+    return getRecord(ID).Type;
+  }
 
   /// Return true if this function is a target-specific builtin.
   bool isTSBuiltin(unsigned ID) const {
@@ -245,40 +114,40 @@ class Context {
 
   /// Return true if this function has no side effects.
   bool isPure(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'U') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'U') != nullptr;
   }
 
   /// Return true if this function has no side effects and doesn't
   /// read memory.
   bool isConst(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'c') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'c') != nullptr;
   }
 
   /// Return true if we know this builtin never throws an exception.
   bool isNoThrow(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'n') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'n') != nullptr;
   }
 
   /// Return true if we know this builtin never returns.
   bool isNoReturn(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'r') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'r') != nullptr;
   }
 
   /// Return true if we know this builtin can return twice.
   bool isReturnsTwice(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'j') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'j') != nullptr;
   }
 
   /// Returns true if this builtin does not perform the side-effects
   /// of its arguments.
   bool isUnevaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'u') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'u') != nullptr;
   }
 
   /// Return true if this is a builtin for a libc/libm function,
   /// with a "__builtin_" prefix (e.g. __builtin_abs).
   bool isLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'F') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'F') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined libc/libm
@@ -289,21 +158,21 @@ class Context {
   /// they do not, but they are recognized as builtins once we see
   /// a declaration.
   bool isPredefinedLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'f') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'f') != nullptr;
   }
 
   /// Returns true if this builtin requires appropriate header in other
   /// compilers. In Clang it will work even without including it, but we can emit
   /// a warning about missing header.
   bool isHeaderDependentFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'h') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'h') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined compiler-rt/libgcc
   /// function, such as "__clear_cache", where we know the signature a
   /// priori.
   bool isPredefinedRuntimeFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'i') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'i') != nullptr;
   }
 
   /// Determines whether this builtin is a C++ standard library function
@@ -311,7 +180,7 @@ class Context {
   /// specialization, where the signature is determined by the standard library
   /// declaration.
   bool isInStdNamespace(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'z') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'z') != nullptr;
   }
 
   /// Determines whether this builtin can have its address taken with no
@@ -325,33 +194,33 @@ class Context {
 
   /// Determines whether this builtin has custom typechecking.
   bool hasCustomTypechecking(unsigned ID) const {
-    return strchr(getAttributesString(ID), 't') != nullptr;
+    return strchr(getRecord(ID).Attributes, 't') != nullptr;
   }
 
   /// Determines whether a declaration of this builtin should be recognized
   /// even if the type doesn't match the specified signature.
   bool allowTypeMismatch(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'T') != nullptr ||
+    return strchr(getRecord(ID).Attributes, 'T') != nullptr ||
            hasCustomTypechecking(ID);
   }
 
   /// Determines whether this builtin has a result or any arguments which
   /// are pointer types.
   bool hasPtrArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '*') != nullptr;
+    return strchr(getRecord(ID).Type, '*') != nullptr;
   }
 
   /// Return true if this builtin has a result or any arguments which are
   /// reference types.
   bool hasReferenceArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '&') != nullptr ||
-           strchr(getTypeString(ID), 'A') != nullptr;
+    return strchr(getRecord(ID).Type, '&') != nullptr ||
+           strchr(getRecord(ID).Type, 'A') != nullptr;
   }
 
   /// If this is a library function that comes from a specific
   /// header, retrieve that header name.
   const char *getHeaderName(unsigned ID) const {
-    return getInfo(ID).Header.getName();
+    return getRecord(ID).Header.getName();
   }
 
   /// Determine whether this builtin is like printf in its
@@ -376,25 +245,27 @@ class Context {
   /// Such functions can be const when the MathErrno lang option and FP
   /// exceptions are disabled.
   bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'e') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'e') != nullptr;
   }
 
   bool isConstWithoutExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'g') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'g') != nullptr;
   }
 
-  const char *getRequiredFeatures(unsigned ID) const;
+  const char *getRequiredFeatures(unsigned ID) const {
+    return getRecord(ID).Features;
+  }
 
   unsigned getRequiredVectorWidth(unsigned ID) const;
 
   /// Return true if builtin ID belongs to AuxTarget.
   bool isAuxBuiltinID(unsigned ID) const {
-    return ID >= (Builtin::FirstTSBuiltin + TSInfos.size());
+    return ID >= (Builtin::FirstTSBuiltin + TSRecords.size());
   }
 
   /// Return real builtin ID (i.e. ID it would have during compilation
   /// for AuxTarget).
-  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSInfos.size(); }
+  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
 
   /// Returns true if this is a libc/libm function without the '__builtin_'
   /// prefix.
@@ -406,20 +277,16 @@ class Context {
 
   /// Return true if this function can be constant evaluated by Clang frontend.
   bool isConstantEvaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'E') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'E') != nullptr;
   }
 
   /// Returns true if this is an immediate (consteval) function
   bool isImmediate(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'G') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'G') != nullptr;
   }
 
 private:
-  std::pair<const char *, const Info &> getStrTableAndInfo(unsigned ID) const;
-
-  const Info &getInfo(unsigned ID) const {
-    return getStrTableAndInfo(ID).second;
-  }
+  const Info &getRecord(unsigned ID) const;
 
   /// Helper function for isPrintfLike and isScanfLike.
   bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index bb7d54bbb793eb..161df386f00f03 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1138,6 +1138,5 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true,
 // FIXME: Obviously incomplete.
 
 #undef BUILTIN
-#undef TARGET_BUILTIN
 #undef CUSTOM_BUILTIN
 #undef UNALIASED_CUSTOM_BUILTIN
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 52a1ac9781395c..4420228793e95f 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -16,7 +16,6 @@
 
 #include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/BitmaskEnum.h"
-#include "clang/Basic/Builtins.h"
 #include "clang/Basic/CFProtectionOptions.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/LLVM.h"
@@ -1010,11 +1009,11 @@ class TargetInfo : public TransferrableTargetInfo,
   virtual void getTargetDefines(const LangOptions &Opts,
                                 MacroBuilder &Builder) const = 0;
 
-  /// Return information about target-specific builtins for the current primary
-  /// target, and info about which builtins are non-portable across the current
-  /// set of primary and secondary targets.
-  virtual std::pair<const char *, ArrayRef<Builtin::Info>>
-  getTargetBuiltinStorage() const = 0;
+
+  /// Return information about target-specific builtins for
+  /// the current primary target, and info about which builtins are non-portable
+  /// across the current set of primary and secondary targets.
+  virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
 
   /// Returns target-specific min and max values VScale_Range.
   virtual std::optional<std::pair<unsigned, unsigned>>
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index c991139b8d5ad7..25a601573698e7 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -29,93 +29,54 @@ const char *HeaderDesc::getName() const {
   llvm_unreachable("Unknown HeaderDesc::HeaderID enum");
 }
 
-static constexpr auto BuiltinStorage =
-    Builtin::Storage<Builtin::FirstTSBuiltin>::Make(
-        CLANG_BUILTIN_STR_TABLE("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_STR_TABLE
+static constexpr Builtin::Info BuiltinInfo[] = {
+    {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER,
+     ALL_LANGUAGES},
+#define BUILTIN(ID, TYPE, ATTRS)                                               \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS)                                    \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS},
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS)                             \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS},
 #include "clang/Basic/Builtins.inc"
-            ,
-        {CLANG_BUILTIN_ENTRY("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_ENTRY
-#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
-#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
-#include "clang/Basic/Builtins.inc"
-        });
+};
 
-std::pair<const char *, const Builtin::Info &>
-Builtin::Context::getStrTableAndInfo(unsigned ID) const {
+const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
   if (ID < Builtin::FirstTSBuiltin)
-    return {BuiltinStorage.StringTable, BuiltinStorage.Infos[ID]};
-  assert(
-      ((ID - Builtin::FirstTSBuiltin) < (TSInfos.size() + AuxTSInfos.size())) &&
-      "Invalid builtin ID!");
+    return BuiltinInfo[ID];
+  assert(((ID - Builtin::FirstTSBuiltin) <
+          (TSRecords.size() + AuxTSRecords.size())) &&
+         "Invalid builtin ID!");
   if (isAuxBuiltinID(ID))
-    return {AuxTSStrTable,
-            AuxTSInfos[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin]};
-  return {TSStrTable, TSInfos[ID - Builtin::FirstTSBuiltin]};
-}
-
-static llvm::StringRef getStrFromTable(const char *StrTable, int Offset) {
-  return &StrTable[Offset];
-}
-
-/// Return the identifier name for the specified builtin,
-/// e.g. "__builtin_abs".
-llvm::StringRef Builtin::Context::getName(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Name);
-}
-
-const char *Builtin::Context::getTypeString(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Type).data();
-}
-
-const char *Builtin::Context::getAt...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Dec 12, 2024

@llvm/pr-subscribers-backend-m68k

Author: Chandler Carruth (chandlerc)

Changes

Reverts llvm/llvm-project#118734

There is currently a specific (unreleased?) version of MSVC and builder that are crashing / failing on this code. We don't know why as all the other build bots and at least some folks' local Windows builds work fine.

This is a candidate revert to help the relevant folks catch their builders up and have time to debug the issue. However, it should only be submitted if we have a fairly concrete ETA on figuring out what is going wrong and suggesting some path forward given that no one else has thus far reproduced the issue.


Patch is 77.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119638.diff

48 Files Affected:

  • (modified) clang/include/clang/Basic/Builtins.h (+36-169)
  • (modified) clang/include/clang/Basic/BuiltinsPPC.def (-1)
  • (modified) clang/include/clang/Basic/TargetInfo.h (+5-6)
  • (modified) clang/lib/Basic/Builtins.cpp (+39-81)
  • (modified) clang/lib/Basic/Targets/AArch64.cpp (+28-32)
  • (modified) clang/lib/Basic/Targets/AArch64.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AMDGPU.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/AMDGPU.h (+1-2)
  • (modified) clang/lib/Basic/Targets/ARC.h (+1-4)
  • (modified) clang/lib/Basic/Targets/ARM.cpp (+21-24)
  • (modified) clang/lib/Basic/Targets/ARM.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AVR.h (+1-4)
  • (modified) clang/lib/Basic/Targets/BPF.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/BPF.h (+1-2)
  • (modified) clang/lib/Basic/Targets/CSKY.cpp (+4)
  • (modified) clang/lib/Basic/Targets/CSKY.h (+1-4)
  • (modified) clang/lib/Basic/Targets/DirectX.h (+1-4)
  • (modified) clang/lib/Basic/Targets/Hexagon.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/Hexagon.h (+1-2)
  • (modified) clang/lib/Basic/Targets/Lanai.h (+1-4)
  • (modified) clang/lib/Basic/Targets/LoongArch.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/LoongArch.h (+1-2)
  • (modified) clang/lib/Basic/Targets/M68k.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/M68k.h (+1-2)
  • (modified) clang/lib/Basic/Targets/MSP430.h (+2-3)
  • (modified) clang/lib/Basic/Targets/Mips.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/Mips.h (+1-2)
  • (modified) clang/lib/Basic/Targets/NVPTX.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/NVPTX.h (+1-2)
  • (modified) clang/lib/Basic/Targets/PNaCl.h (+1-4)
  • (modified) clang/lib/Basic/Targets/PPC.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/PPC.h (+1-2)
  • (modified) clang/lib/Basic/Targets/RISCV.cpp (+13-19)
  • (modified) clang/lib/Basic/Targets/RISCV.h (+1-2)
  • (modified) clang/lib/Basic/Targets/SPIR.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/SPIR.h (+2-6)
  • (modified) clang/lib/Basic/Targets/Sparc.h (+2-3)
  • (modified) clang/lib/Basic/Targets/SystemZ.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/SystemZ.h (+1-2)
  • (modified) clang/lib/Basic/Targets/TCE.h (+1-4)
  • (modified) clang/lib/Basic/Targets/VE.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/VE.h (+1-2)
  • (modified) clang/lib/Basic/Targets/WebAssembly.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/WebAssembly.h (+1-2)
  • (modified) clang/lib/Basic/Targets/X86.cpp (+26-42)
  • (modified) clang/lib/Basic/Targets/X86.h (+2-4)
  • (modified) clang/lib/Basic/Targets/XCore.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/XCore.h (+1-2)
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index a9bb6efe850cc6..89f65682ae5b41 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -55,7 +55,6 @@ struct HeaderDesc {
 #undef HEADER
   } ID;
 
-  constexpr HeaderDesc() : ID() {}
   constexpr HeaderDesc(HeaderID ID) : ID(ID) {}
 
   const char *getName() const;
@@ -69,140 +68,14 @@ enum ID {
   FirstTSBuiltin
 };
 
-// The info used to represent each builtin.
 struct Info {
-  // 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;
-
+  llvm::StringLiteral Name;
+  const char *Type, *Attributes;
+  const char *Features;
   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 {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("")                       \
-  }
-
-// A detail macro used internally to compute the desired string table
-// `StrOffsets` struct for arguments to `Storage::Make`.
-#define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE)      \
-  Builtin::Info::StrOffsets {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof(FEATURE)                  \
-  }
-
-// A set of macros that can be used with builtin `.def' files as an X-macro to
-// create an `Info` struct for a particular builtin. It both computes the
-// `StrOffsets` value for the string table (the lengths here, translated to
-// offsets by the Storage::Make function), and the other metadata for each
-// builtin.
-//
-// There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`,
-// `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`.
-#define CLANG_BUILTIN_ENTRY(ID, TYPE, ATTRS)                                   \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_LANGBUILTIN_ENTRY(ID, TYPE, ATTRS, LANG)                         \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, LANG},
-#define CLANG_LIBBUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG)                  \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::HEADER, LANG},
-#define CLANG_TARGET_BUILTIN_ENTRY(ID, TYPE, ATTRS, FEATURE)                   \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_TARGET_HEADER_BUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG,       \
-                                          FEATURE)                             \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::HEADER, LANG},
-
 /// Holds information about both target-independent and
 /// target-specific builtins, allowing easy queries by clients.
 ///
@@ -210,11 +83,8 @@ template <size_t N> struct Storage {
 /// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
 /// be translated back with getAuxBuiltinID() before use.
 class Context {
-  const char *TSStrTable = nullptr;
-  const char *AuxTSStrTable = nullptr;
-
-  llvm::ArrayRef<Info> TSInfos;
-  llvm::ArrayRef<Info> AuxTSInfos;
+  llvm::ArrayRef<Info> TSRecords;
+  llvm::ArrayRef<Info> AuxTSRecords;
 
 public:
   Context() = default;
@@ -230,13 +100,12 @@ class Context {
 
   /// Return the identifier name for the specified builtin,
   /// e.g. "__builtin_abs".
-  llvm::StringRef getName(unsigned ID) const;
+  llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
 
   /// Get the type descriptor string for the specified builtin.
-  const char *getTypeString(unsigned ID) const;
-
-  /// Get the attributes descriptor string for the specified builtin.
-  const char *getAttributesString(unsigned ID) const;
+  const char *getTypeString(unsigned ID) const {
+    return getRecord(ID).Type;
+  }
 
   /// Return true if this function is a target-specific builtin.
   bool isTSBuiltin(unsigned ID) const {
@@ -245,40 +114,40 @@ class Context {
 
   /// Return true if this function has no side effects.
   bool isPure(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'U') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'U') != nullptr;
   }
 
   /// Return true if this function has no side effects and doesn't
   /// read memory.
   bool isConst(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'c') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'c') != nullptr;
   }
 
   /// Return true if we know this builtin never throws an exception.
   bool isNoThrow(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'n') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'n') != nullptr;
   }
 
   /// Return true if we know this builtin never returns.
   bool isNoReturn(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'r') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'r') != nullptr;
   }
 
   /// Return true if we know this builtin can return twice.
   bool isReturnsTwice(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'j') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'j') != nullptr;
   }
 
   /// Returns true if this builtin does not perform the side-effects
   /// of its arguments.
   bool isUnevaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'u') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'u') != nullptr;
   }
 
   /// Return true if this is a builtin for a libc/libm function,
   /// with a "__builtin_" prefix (e.g. __builtin_abs).
   bool isLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'F') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'F') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined libc/libm
@@ -289,21 +158,21 @@ class Context {
   /// they do not, but they are recognized as builtins once we see
   /// a declaration.
   bool isPredefinedLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'f') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'f') != nullptr;
   }
 
   /// Returns true if this builtin requires appropriate header in other
   /// compilers. In Clang it will work even without including it, but we can emit
   /// a warning about missing header.
   bool isHeaderDependentFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'h') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'h') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined compiler-rt/libgcc
   /// function, such as "__clear_cache", where we know the signature a
   /// priori.
   bool isPredefinedRuntimeFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'i') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'i') != nullptr;
   }
 
   /// Determines whether this builtin is a C++ standard library function
@@ -311,7 +180,7 @@ class Context {
   /// specialization, where the signature is determined by the standard library
   /// declaration.
   bool isInStdNamespace(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'z') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'z') != nullptr;
   }
 
   /// Determines whether this builtin can have its address taken with no
@@ -325,33 +194,33 @@ class Context {
 
   /// Determines whether this builtin has custom typechecking.
   bool hasCustomTypechecking(unsigned ID) const {
-    return strchr(getAttributesString(ID), 't') != nullptr;
+    return strchr(getRecord(ID).Attributes, 't') != nullptr;
   }
 
   /// Determines whether a declaration of this builtin should be recognized
   /// even if the type doesn't match the specified signature.
   bool allowTypeMismatch(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'T') != nullptr ||
+    return strchr(getRecord(ID).Attributes, 'T') != nullptr ||
            hasCustomTypechecking(ID);
   }
 
   /// Determines whether this builtin has a result or any arguments which
   /// are pointer types.
   bool hasPtrArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '*') != nullptr;
+    return strchr(getRecord(ID).Type, '*') != nullptr;
   }
 
   /// Return true if this builtin has a result or any arguments which are
   /// reference types.
   bool hasReferenceArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '&') != nullptr ||
-           strchr(getTypeString(ID), 'A') != nullptr;
+    return strchr(getRecord(ID).Type, '&') != nullptr ||
+           strchr(getRecord(ID).Type, 'A') != nullptr;
   }
 
   /// If this is a library function that comes from a specific
   /// header, retrieve that header name.
   const char *getHeaderName(unsigned ID) const {
-    return getInfo(ID).Header.getName();
+    return getRecord(ID).Header.getName();
   }
 
   /// Determine whether this builtin is like printf in its
@@ -376,25 +245,27 @@ class Context {
   /// Such functions can be const when the MathErrno lang option and FP
   /// exceptions are disabled.
   bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'e') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'e') != nullptr;
   }
 
   bool isConstWithoutExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'g') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'g') != nullptr;
   }
 
-  const char *getRequiredFeatures(unsigned ID) const;
+  const char *getRequiredFeatures(unsigned ID) const {
+    return getRecord(ID).Features;
+  }
 
   unsigned getRequiredVectorWidth(unsigned ID) const;
 
   /// Return true if builtin ID belongs to AuxTarget.
   bool isAuxBuiltinID(unsigned ID) const {
-    return ID >= (Builtin::FirstTSBuiltin + TSInfos.size());
+    return ID >= (Builtin::FirstTSBuiltin + TSRecords.size());
   }
 
   /// Return real builtin ID (i.e. ID it would have during compilation
   /// for AuxTarget).
-  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSInfos.size(); }
+  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
 
   /// Returns true if this is a libc/libm function without the '__builtin_'
   /// prefix.
@@ -406,20 +277,16 @@ class Context {
 
   /// Return true if this function can be constant evaluated by Clang frontend.
   bool isConstantEvaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'E') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'E') != nullptr;
   }
 
   /// Returns true if this is an immediate (consteval) function
   bool isImmediate(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'G') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'G') != nullptr;
   }
 
 private:
-  std::pair<const char *, const Info &> getStrTableAndInfo(unsigned ID) const;
-
-  const Info &getInfo(unsigned ID) const {
-    return getStrTableAndInfo(ID).second;
-  }
+  const Info &getRecord(unsigned ID) const;
 
   /// Helper function for isPrintfLike and isScanfLike.
   bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index bb7d54bbb793eb..161df386f00f03 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1138,6 +1138,5 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true,
 // FIXME: Obviously incomplete.
 
 #undef BUILTIN
-#undef TARGET_BUILTIN
 #undef CUSTOM_BUILTIN
 #undef UNALIASED_CUSTOM_BUILTIN
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 52a1ac9781395c..4420228793e95f 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -16,7 +16,6 @@
 
 #include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/BitmaskEnum.h"
-#include "clang/Basic/Builtins.h"
 #include "clang/Basic/CFProtectionOptions.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/LLVM.h"
@@ -1010,11 +1009,11 @@ class TargetInfo : public TransferrableTargetInfo,
   virtual void getTargetDefines(const LangOptions &Opts,
                                 MacroBuilder &Builder) const = 0;
 
-  /// Return information about target-specific builtins for the current primary
-  /// target, and info about which builtins are non-portable across the current
-  /// set of primary and secondary targets.
-  virtual std::pair<const char *, ArrayRef<Builtin::Info>>
-  getTargetBuiltinStorage() const = 0;
+
+  /// Return information about target-specific builtins for
+  /// the current primary target, and info about which builtins are non-portable
+  /// across the current set of primary and secondary targets.
+  virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
 
   /// Returns target-specific min and max values VScale_Range.
   virtual std::optional<std::pair<unsigned, unsigned>>
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index c991139b8d5ad7..25a601573698e7 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -29,93 +29,54 @@ const char *HeaderDesc::getName() const {
   llvm_unreachable("Unknown HeaderDesc::HeaderID enum");
 }
 
-static constexpr auto BuiltinStorage =
-    Builtin::Storage<Builtin::FirstTSBuiltin>::Make(
-        CLANG_BUILTIN_STR_TABLE("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_STR_TABLE
+static constexpr Builtin::Info BuiltinInfo[] = {
+    {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER,
+     ALL_LANGUAGES},
+#define BUILTIN(ID, TYPE, ATTRS)                                               \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS)                                    \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS},
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS)                             \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS},
 #include "clang/Basic/Builtins.inc"
-            ,
-        {CLANG_BUILTIN_ENTRY("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_ENTRY
-#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
-#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
-#include "clang/Basic/Builtins.inc"
-        });
+};
 
-std::pair<const char *, const Builtin::Info &>
-Builtin::Context::getStrTableAndInfo(unsigned ID) const {
+const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
   if (ID < Builtin::FirstTSBuiltin)
-    return {BuiltinStorage.StringTable, BuiltinStorage.Infos[ID]};
-  assert(
-      ((ID - Builtin::FirstTSBuiltin) < (TSInfos.size() + AuxTSInfos.size())) &&
-      "Invalid builtin ID!");
+    return BuiltinInfo[ID];
+  assert(((ID - Builtin::FirstTSBuiltin) <
+          (TSRecords.size() + AuxTSRecords.size())) &&
+         "Invalid builtin ID!");
   if (isAuxBuiltinID(ID))
-    return {AuxTSStrTable,
-            AuxTSInfos[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin]};
-  return {TSStrTable, TSInfos[ID - Builtin::FirstTSBuiltin]};
-}
-
-static llvm::StringRef getStrFromTable(const char *StrTable, int Offset) {
-  return &StrTable[Offset];
-}
-
-/// Return the identifier name for the specified builtin,
-/// e.g. "__builtin_abs".
-llvm::StringRef Builtin::Context::getName(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Name);
-}
-
-const char *Builtin::Context::getTypeString(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Type).data();
-}
-
-const char *Builtin::Context::getAt...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Dec 12, 2024

@llvm/pr-subscribers-backend-sparc

Author: Chandler Carruth (chandlerc)

Changes

Reverts llvm/llvm-project#118734

There is currently a specific (unreleased?) version of MSVC and builder that are crashing / failing on this code. We don't know why as all the other build bots and at least some folks' local Windows builds work fine.

This is a candidate revert to help the relevant folks catch their builders up and have time to debug the issue. However, it should only be submitted if we have a fairly concrete ETA on figuring out what is going wrong and suggesting some path forward given that no one else has thus far reproduced the issue.


Patch is 77.23 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/119638.diff

48 Files Affected:

  • (modified) clang/include/clang/Basic/Builtins.h (+36-169)
  • (modified) clang/include/clang/Basic/BuiltinsPPC.def (-1)
  • (modified) clang/include/clang/Basic/TargetInfo.h (+5-6)
  • (modified) clang/lib/Basic/Builtins.cpp (+39-81)
  • (modified) clang/lib/Basic/Targets/AArch64.cpp (+28-32)
  • (modified) clang/lib/Basic/Targets/AArch64.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AMDGPU.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/AMDGPU.h (+1-2)
  • (modified) clang/lib/Basic/Targets/ARC.h (+1-4)
  • (modified) clang/lib/Basic/Targets/ARM.cpp (+21-24)
  • (modified) clang/lib/Basic/Targets/ARM.h (+1-2)
  • (modified) clang/lib/Basic/Targets/AVR.h (+1-4)
  • (modified) clang/lib/Basic/Targets/BPF.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/BPF.h (+1-2)
  • (modified) clang/lib/Basic/Targets/CSKY.cpp (+4)
  • (modified) clang/lib/Basic/Targets/CSKY.h (+1-4)
  • (modified) clang/lib/Basic/Targets/DirectX.h (+1-4)
  • (modified) clang/lib/Basic/Targets/Hexagon.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/Hexagon.h (+1-2)
  • (modified) clang/lib/Basic/Targets/Lanai.h (+1-4)
  • (modified) clang/lib/Basic/Targets/LoongArch.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/LoongArch.h (+1-2)
  • (modified) clang/lib/Basic/Targets/M68k.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/M68k.h (+1-2)
  • (modified) clang/lib/Basic/Targets/MSP430.h (+2-3)
  • (modified) clang/lib/Basic/Targets/Mips.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/Mips.h (+1-2)
  • (modified) clang/lib/Basic/Targets/NVPTX.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/NVPTX.h (+1-2)
  • (modified) clang/lib/Basic/Targets/PNaCl.h (+1-4)
  • (modified) clang/lib/Basic/Targets/PPC.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/PPC.h (+1-2)
  • (modified) clang/lib/Basic/Targets/RISCV.cpp (+13-19)
  • (modified) clang/lib/Basic/Targets/RISCV.h (+1-2)
  • (modified) clang/lib/Basic/Targets/SPIR.cpp (+2-3)
  • (modified) clang/lib/Basic/Targets/SPIR.h (+2-6)
  • (modified) clang/lib/Basic/Targets/Sparc.h (+2-3)
  • (modified) clang/lib/Basic/Targets/SystemZ.cpp (+9-14)
  • (modified) clang/lib/Basic/Targets/SystemZ.h (+1-2)
  • (modified) clang/lib/Basic/Targets/TCE.h (+1-4)
  • (modified) clang/lib/Basic/Targets/VE.cpp (+7-12)
  • (modified) clang/lib/Basic/Targets/VE.h (+1-2)
  • (modified) clang/lib/Basic/Targets/WebAssembly.cpp (+11-15)
  • (modified) clang/lib/Basic/Targets/WebAssembly.h (+1-2)
  • (modified) clang/lib/Basic/Targets/X86.cpp (+26-42)
  • (modified) clang/lib/Basic/Targets/X86.h (+2-4)
  • (modified) clang/lib/Basic/Targets/XCore.cpp (+9-13)
  • (modified) clang/lib/Basic/Targets/XCore.h (+1-2)
diff --git a/clang/include/clang/Basic/Builtins.h b/clang/include/clang/Basic/Builtins.h
index a9bb6efe850cc6..89f65682ae5b41 100644
--- a/clang/include/clang/Basic/Builtins.h
+++ b/clang/include/clang/Basic/Builtins.h
@@ -55,7 +55,6 @@ struct HeaderDesc {
 #undef HEADER
   } ID;
 
-  constexpr HeaderDesc() : ID() {}
   constexpr HeaderDesc(HeaderID ID) : ID(ID) {}
 
   const char *getName() const;
@@ -69,140 +68,14 @@ enum ID {
   FirstTSBuiltin
 };
 
-// The info used to represent each builtin.
 struct Info {
-  // 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;
-
+  llvm::StringLiteral Name;
+  const char *Type, *Attributes;
+  const char *Features;
   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 {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof("")                       \
-  }
-
-// A detail macro used internally to compute the desired string table
-// `StrOffsets` struct for arguments to `Storage::Make`.
-#define CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE)      \
-  Builtin::Info::StrOffsets {                                                  \
-    sizeof(#ID), sizeof(TYPE), sizeof(ATTRS), sizeof(FEATURE)                  \
-  }
-
-// A set of macros that can be used with builtin `.def' files as an X-macro to
-// create an `Info` struct for a particular builtin. It both computes the
-// `StrOffsets` value for the string table (the lengths here, translated to
-// offsets by the Storage::Make function), and the other metadata for each
-// builtin.
-//
-// There is a corresponding macro for each of `BUILTIN`, `LANGBUILTIN`,
-// `LIBBUILTIN`, `TARGET_BUILTIN`, and `TARGET_HEADER_BUILTIN`.
-#define CLANG_BUILTIN_ENTRY(ID, TYPE, ATTRS)                                   \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_LANGBUILTIN_ENTRY(ID, TYPE, ATTRS, LANG)                         \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::NO_HEADER, LANG},
-#define CLANG_LIBBUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG)                  \
-  Builtin::Info{CLANG_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS),             \
-                HeaderDesc::HEADER, LANG},
-#define CLANG_TARGET_BUILTIN_ENTRY(ID, TYPE, ATTRS, FEATURE)                   \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::NO_HEADER, ALL_LANGUAGES},
-#define CLANG_TARGET_HEADER_BUILTIN_ENTRY(ID, TYPE, ATTRS, HEADER, LANG,       \
-                                          FEATURE)                             \
-  Builtin::Info{                                                               \
-      CLANG_TARGET_BUILTIN_DETAIL_STR_OFFSETS(ID, TYPE, ATTRS, FEATURE),       \
-      HeaderDesc::HEADER, LANG},
-
 /// Holds information about both target-independent and
 /// target-specific builtins, allowing easy queries by clients.
 ///
@@ -210,11 +83,8 @@ template <size_t N> struct Storage {
 /// AuxTSRecords. Their IDs are shifted up by TSRecords.size() and need to
 /// be translated back with getAuxBuiltinID() before use.
 class Context {
-  const char *TSStrTable = nullptr;
-  const char *AuxTSStrTable = nullptr;
-
-  llvm::ArrayRef<Info> TSInfos;
-  llvm::ArrayRef<Info> AuxTSInfos;
+  llvm::ArrayRef<Info> TSRecords;
+  llvm::ArrayRef<Info> AuxTSRecords;
 
 public:
   Context() = default;
@@ -230,13 +100,12 @@ class Context {
 
   /// Return the identifier name for the specified builtin,
   /// e.g. "__builtin_abs".
-  llvm::StringRef getName(unsigned ID) const;
+  llvm::StringRef getName(unsigned ID) const { return getRecord(ID).Name; }
 
   /// Get the type descriptor string for the specified builtin.
-  const char *getTypeString(unsigned ID) const;
-
-  /// Get the attributes descriptor string for the specified builtin.
-  const char *getAttributesString(unsigned ID) const;
+  const char *getTypeString(unsigned ID) const {
+    return getRecord(ID).Type;
+  }
 
   /// Return true if this function is a target-specific builtin.
   bool isTSBuiltin(unsigned ID) const {
@@ -245,40 +114,40 @@ class Context {
 
   /// Return true if this function has no side effects.
   bool isPure(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'U') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'U') != nullptr;
   }
 
   /// Return true if this function has no side effects and doesn't
   /// read memory.
   bool isConst(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'c') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'c') != nullptr;
   }
 
   /// Return true if we know this builtin never throws an exception.
   bool isNoThrow(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'n') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'n') != nullptr;
   }
 
   /// Return true if we know this builtin never returns.
   bool isNoReturn(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'r') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'r') != nullptr;
   }
 
   /// Return true if we know this builtin can return twice.
   bool isReturnsTwice(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'j') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'j') != nullptr;
   }
 
   /// Returns true if this builtin does not perform the side-effects
   /// of its arguments.
   bool isUnevaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'u') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'u') != nullptr;
   }
 
   /// Return true if this is a builtin for a libc/libm function,
   /// with a "__builtin_" prefix (e.g. __builtin_abs).
   bool isLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'F') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'F') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined libc/libm
@@ -289,21 +158,21 @@ class Context {
   /// they do not, but they are recognized as builtins once we see
   /// a declaration.
   bool isPredefinedLibFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'f') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'f') != nullptr;
   }
 
   /// Returns true if this builtin requires appropriate header in other
   /// compilers. In Clang it will work even without including it, but we can emit
   /// a warning about missing header.
   bool isHeaderDependentFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'h') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'h') != nullptr;
   }
 
   /// Determines whether this builtin is a predefined compiler-rt/libgcc
   /// function, such as "__clear_cache", where we know the signature a
   /// priori.
   bool isPredefinedRuntimeFunction(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'i') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'i') != nullptr;
   }
 
   /// Determines whether this builtin is a C++ standard library function
@@ -311,7 +180,7 @@ class Context {
   /// specialization, where the signature is determined by the standard library
   /// declaration.
   bool isInStdNamespace(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'z') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'z') != nullptr;
   }
 
   /// Determines whether this builtin can have its address taken with no
@@ -325,33 +194,33 @@ class Context {
 
   /// Determines whether this builtin has custom typechecking.
   bool hasCustomTypechecking(unsigned ID) const {
-    return strchr(getAttributesString(ID), 't') != nullptr;
+    return strchr(getRecord(ID).Attributes, 't') != nullptr;
   }
 
   /// Determines whether a declaration of this builtin should be recognized
   /// even if the type doesn't match the specified signature.
   bool allowTypeMismatch(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'T') != nullptr ||
+    return strchr(getRecord(ID).Attributes, 'T') != nullptr ||
            hasCustomTypechecking(ID);
   }
 
   /// Determines whether this builtin has a result or any arguments which
   /// are pointer types.
   bool hasPtrArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '*') != nullptr;
+    return strchr(getRecord(ID).Type, '*') != nullptr;
   }
 
   /// Return true if this builtin has a result or any arguments which are
   /// reference types.
   bool hasReferenceArgsOrResult(unsigned ID) const {
-    return strchr(getTypeString(ID), '&') != nullptr ||
-           strchr(getTypeString(ID), 'A') != nullptr;
+    return strchr(getRecord(ID).Type, '&') != nullptr ||
+           strchr(getRecord(ID).Type, 'A') != nullptr;
   }
 
   /// If this is a library function that comes from a specific
   /// header, retrieve that header name.
   const char *getHeaderName(unsigned ID) const {
-    return getInfo(ID).Header.getName();
+    return getRecord(ID).Header.getName();
   }
 
   /// Determine whether this builtin is like printf in its
@@ -376,25 +245,27 @@ class Context {
   /// Such functions can be const when the MathErrno lang option and FP
   /// exceptions are disabled.
   bool isConstWithoutErrnoAndExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'e') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'e') != nullptr;
   }
 
   bool isConstWithoutExceptions(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'g') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'g') != nullptr;
   }
 
-  const char *getRequiredFeatures(unsigned ID) const;
+  const char *getRequiredFeatures(unsigned ID) const {
+    return getRecord(ID).Features;
+  }
 
   unsigned getRequiredVectorWidth(unsigned ID) const;
 
   /// Return true if builtin ID belongs to AuxTarget.
   bool isAuxBuiltinID(unsigned ID) const {
-    return ID >= (Builtin::FirstTSBuiltin + TSInfos.size());
+    return ID >= (Builtin::FirstTSBuiltin + TSRecords.size());
   }
 
   /// Return real builtin ID (i.e. ID it would have during compilation
   /// for AuxTarget).
-  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSInfos.size(); }
+  unsigned getAuxBuiltinID(unsigned ID) const { return ID - TSRecords.size(); }
 
   /// Returns true if this is a libc/libm function without the '__builtin_'
   /// prefix.
@@ -406,20 +277,16 @@ class Context {
 
   /// Return true if this function can be constant evaluated by Clang frontend.
   bool isConstantEvaluated(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'E') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'E') != nullptr;
   }
 
   /// Returns true if this is an immediate (consteval) function
   bool isImmediate(unsigned ID) const {
-    return strchr(getAttributesString(ID), 'G') != nullptr;
+    return strchr(getRecord(ID).Attributes, 'G') != nullptr;
   }
 
 private:
-  std::pair<const char *, const Info &> getStrTableAndInfo(unsigned ID) const;
-
-  const Info &getInfo(unsigned ID) const {
-    return getStrTableAndInfo(ID).second;
-  }
+  const Info &getRecord(unsigned ID) const;
 
   /// Helper function for isPrintfLike and isScanfLike.
   bool isLike(unsigned ID, unsigned &FormatIdx, bool &HasVAListArg,
diff --git a/clang/include/clang/Basic/BuiltinsPPC.def b/clang/include/clang/Basic/BuiltinsPPC.def
index bb7d54bbb793eb..161df386f00f03 100644
--- a/clang/include/clang/Basic/BuiltinsPPC.def
+++ b/clang/include/clang/Basic/BuiltinsPPC.def
@@ -1138,6 +1138,5 @@ UNALIASED_CUSTOM_BUILTIN(mma_pmxvbf16ger2nn, "vW512*VVi15i15i3", true,
 // FIXME: Obviously incomplete.
 
 #undef BUILTIN
-#undef TARGET_BUILTIN
 #undef CUSTOM_BUILTIN
 #undef UNALIASED_CUSTOM_BUILTIN
diff --git a/clang/include/clang/Basic/TargetInfo.h b/clang/include/clang/Basic/TargetInfo.h
index 52a1ac9781395c..4420228793e95f 100644
--- a/clang/include/clang/Basic/TargetInfo.h
+++ b/clang/include/clang/Basic/TargetInfo.h
@@ -16,7 +16,6 @@
 
 #include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/BitmaskEnum.h"
-#include "clang/Basic/Builtins.h"
 #include "clang/Basic/CFProtectionOptions.h"
 #include "clang/Basic/CodeGenOptions.h"
 #include "clang/Basic/LLVM.h"
@@ -1010,11 +1009,11 @@ class TargetInfo : public TransferrableTargetInfo,
   virtual void getTargetDefines(const LangOptions &Opts,
                                 MacroBuilder &Builder) const = 0;
 
-  /// Return information about target-specific builtins for the current primary
-  /// target, and info about which builtins are non-portable across the current
-  /// set of primary and secondary targets.
-  virtual std::pair<const char *, ArrayRef<Builtin::Info>>
-  getTargetBuiltinStorage() const = 0;
+
+  /// Return information about target-specific builtins for
+  /// the current primary target, and info about which builtins are non-portable
+  /// across the current set of primary and secondary targets.
+  virtual ArrayRef<Builtin::Info> getTargetBuiltins() const = 0;
 
   /// Returns target-specific min and max values VScale_Range.
   virtual std::optional<std::pair<unsigned, unsigned>>
diff --git a/clang/lib/Basic/Builtins.cpp b/clang/lib/Basic/Builtins.cpp
index c991139b8d5ad7..25a601573698e7 100644
--- a/clang/lib/Basic/Builtins.cpp
+++ b/clang/lib/Basic/Builtins.cpp
@@ -29,93 +29,54 @@ const char *HeaderDesc::getName() const {
   llvm_unreachable("Unknown HeaderDesc::HeaderID enum");
 }
 
-static constexpr auto BuiltinStorage =
-    Builtin::Storage<Builtin::FirstTSBuiltin>::Make(
-        CLANG_BUILTIN_STR_TABLE("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_STR_TABLE
+static constexpr Builtin::Info BuiltinInfo[] = {
+    {"not a builtin function", nullptr, nullptr, nullptr, HeaderDesc::NO_HEADER,
+     ALL_LANGUAGES},
+#define BUILTIN(ID, TYPE, ATTRS)                                               \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, ALL_LANGUAGES},
+#define LANGBUILTIN(ID, TYPE, ATTRS, LANGS)                                    \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::NO_HEADER, LANGS},
+#define LIBBUILTIN(ID, TYPE, ATTRS, HEADER, LANGS)                             \
+  {#ID, TYPE, ATTRS, nullptr, HeaderDesc::HEADER, LANGS},
 #include "clang/Basic/Builtins.inc"
-            ,
-        {CLANG_BUILTIN_ENTRY("not a builtin function", "", "")
-#define BUILTIN CLANG_BUILTIN_ENTRY
-#define LANGBUILTIN CLANG_LANGBUILTIN_ENTRY
-#define LIBBUILTIN CLANG_LIBBUILTIN_ENTRY
-#include "clang/Basic/Builtins.inc"
-        });
+};
 
-std::pair<const char *, const Builtin::Info &>
-Builtin::Context::getStrTableAndInfo(unsigned ID) const {
+const Builtin::Info &Builtin::Context::getRecord(unsigned ID) const {
   if (ID < Builtin::FirstTSBuiltin)
-    return {BuiltinStorage.StringTable, BuiltinStorage.Infos[ID]};
-  assert(
-      ((ID - Builtin::FirstTSBuiltin) < (TSInfos.size() + AuxTSInfos.size())) &&
-      "Invalid builtin ID!");
+    return BuiltinInfo[ID];
+  assert(((ID - Builtin::FirstTSBuiltin) <
+          (TSRecords.size() + AuxTSRecords.size())) &&
+         "Invalid builtin ID!");
   if (isAuxBuiltinID(ID))
-    return {AuxTSStrTable,
-            AuxTSInfos[getAuxBuiltinID(ID) - Builtin::FirstTSBuiltin]};
-  return {TSStrTable, TSInfos[ID - Builtin::FirstTSBuiltin]};
-}
-
-static llvm::StringRef getStrFromTable(const char *StrTable, int Offset) {
-  return &StrTable[Offset];
-}
-
-/// Return the identifier name for the specified builtin,
-/// e.g. "__builtin_abs".
-llvm::StringRef Builtin::Context::getName(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Name);
-}
-
-const char *Builtin::Context::getTypeString(unsigned ID) const {
-  const auto &[StrTable, I] = getStrTableAndInfo(ID);
-  return getStrFromTable(StrTable, I.Offsets.Type).data();
-}
-
-const char *Builtin::Context::getAt...
[truncated]

Copy link

github-actions bot commented Dec 12, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

Copy link
Collaborator

@dyung dyung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@dyung
Copy link
Collaborator

dyung commented Dec 13, 2024

I'm going to bring out Windows buildbot back online that was failing so that when you do submit the revert, the bot should go back to green. I am looking into this and will get back to you on the original bug when I find something.

@chandlerc
Copy link
Member Author

I'm going to bring out Windows buildbot back online that was failing so that when you do submit the revert, the bot should go back to green. I am looking into this and will get back to you on the original bug when I find something.

So, the builder came back up, and is now passing without this landing...

Here is the first build after it came back up: https://lab.llvm.org/buildbot/#/builders/46/builds/9173

And I went through the output and found a specific test that was failing, and it seems to pass?

PASS: Clang :: AST/builtins-arm-strex-rettype.c (433 of 81898)

So maybe this was a transient issue that has been fixed, or some stale state?

@chandlerc
Copy link
Member Author

Sorry, let's keep discussion on the original PR -- I'll go post there.

@chandlerc
Copy link
Member Author

Build bot with the issue is now online and failing as expected, merging this revert to get in green (we hope).

@chandlerc chandlerc merged commit ca79ff0 into main Dec 14, 2024
8 checks passed
@chandlerc chandlerc deleted the revert-118734-strtable branch December 14, 2024 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

3 participants