Repository: llvm/llvm-project
Pull request #136629: [llvm] annotate interfaces in llvm/ADT for DLL export
Author: login: andrurogerz
Labels: name: llvm:adt
Created: 2025-04-21T22:48:40Z | Merged: 2025-05-19T20:42:43Z

## Purpose

This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the `llvm/ADT` library. These annotations currently have no meaningful impact on the LLVM build; however, they are a prerequisite to support an LLVM Windows DLL (shared library) build.

## Background

This effort is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307), and documentation for `LLVM_ABI` and related annotations is found in the LLVM repo [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst).  

The bulk of these changes were generated automatically using the [Interface Definition Scanner (IDS)](https://github.com/compnerd/ids) tool, followed formatting with `git clang-format`.

The following manual adjustments were also applied after running IDS:

- Add `#include "llvm/Support/Compiler.h"` to files where it was not auto-added by IDS due to no pre-existing block of include statements.
- Add `LLVM_ABI_FRIEND` to a small number of `friend` function declarations
- Add `LLVM_ABI` to a subset of private class methods and fields that require export

## Validation

Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations:

- Windows with MSVC
- Windows with Clang
- Linux with GCC
- Linux with Clang
- Darwin with Clang


Diff:
diff --git a/llvm/include/llvm/ADT/APFixedPoint.h b/llvm/include/llvm/ADT/APFixedPoint.h
index 89d2a93a06a26..0a47cd50516d4 100644
--- a/llvm/include/llvm/ADT/APFixedPoint.h
+++ b/llvm/include/llvm/ADT/APFixedPoint.h
@@ -19,6 +19,7 @@
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace llvm {
@@ -84,11 +85,11 @@ class FixedPointSemantics {
   /// precision semantic that can precisely represent the precision and ranges
   /// of both input values. This does not compute the resulting semantics for a
   /// given binary operation.
-  FixedPointSemantics
+  LLVM_ABI FixedPointSemantics
   getCommonSemantics(const FixedPointSemantics &Other) const;
 
   /// Print semantics for debug purposes
-  void print(llvm::raw_ostream& OS) const;
+  LLVM_ABI void print(llvm::raw_ostream &OS) const;
 
   /// Returns true if this fixed-point semantic with its value bits interpreted
   /// as an integer can fit in the given floating point semantic without
@@ -97,7 +98,7 @@ class FixedPointSemantics {
   /// minimum integer representation of 127 and -128, respectively. If both of
   /// these values can be represented (possibly inexactly) in the floating
   /// point semantic without overflowing, this returns true.
-  bool fitsInFloatSemantics(const fltSemantics &FloatSema) const;
+  LLVM_ABI bool fitsInFloatSemantics(const fltSemantics &FloatSema) const;
 
   /// Return the FixedPointSemantics for an integer type.
   static FixedPointSemantics GetIntegerSemantics(unsigned Width,
@@ -118,10 +119,10 @@ class FixedPointSemantics {
   /// The result is dependent on the host endianness and not stable across LLVM
   /// versions. See getFromOpaqueInt() to convert it back to a
   /// FixedPointSemantics object.
-  uint32_t toOpaqueInt() const;
+  LLVM_ABI uint32_t toOpaqueInt() const;
   /// Create a FixedPointSemantics object from an integer created via
   /// toOpaqueInt().
-  static FixedPointSemantics getFromOpaqueInt(uint32_t);
+  LLVM_ABI static FixedPointSemantics getFromOpaqueInt(uint32_t);
 
 private:
   unsigned Width          : WidthBitWidth;
@@ -190,22 +191,26 @@ class APFixedPoint {
   // Convert this number to match the semantics provided. If the overflow
   // parameter is provided, set this value to true or false to indicate if this
   // operation results in an overflow.
-  APFixedPoint convert(const FixedPointSemantics &DstSema,
-                       bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint convert(const FixedPointSemantics &DstSema,
+                                bool *Overflow = nullptr) const;
 
   // Perform binary operations on a fixed point type. The resulting fixed point
   // value will be in the common, full precision semantics that can represent
   // the precision and ranges of both input values. See convert() for an
   // explanation of the Overflow parameter.
-  APFixedPoint add(const APFixedPoint &Other, bool *Overflow = nullptr) const;
-  APFixedPoint sub(const APFixedPoint &Other, bool *Overflow = nullptr) const;
-  APFixedPoint mul(const APFixedPoint &Other, bool *Overflow = nullptr) const;
-  APFixedPoint div(const APFixedPoint &Other, bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint add(const APFixedPoint &Other,
+                            bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint sub(const APFixedPoint &Other,
+                            bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint mul(const APFixedPoint &Other,
+                            bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint div(const APFixedPoint &Other,
+                            bool *Overflow = nullptr) const;
 
   // Perform shift operations on a fixed point type. Unlike the other binary
   // operations, the resulting fixed point value will be in the original
   // semantic.
-  APFixedPoint shl(unsigned Amt, bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint shl(unsigned Amt, bool *Overflow = nullptr) const;
   APFixedPoint shr(unsigned Amt, bool *Overflow = nullptr) const {
     // Right shift cannot overflow.
     if (Overflow)
@@ -215,7 +220,7 @@ class APFixedPoint {
 
   /// Perform a unary negation (-X) on this fixed point type, taking into
   /// account saturation if applicable.
-  APFixedPoint negate(bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint negate(bool *Overflow = nullptr) const;
 
   /// Return the integral part of this fixed point number, rounded towards
   /// zero. (-2.5k -> -2)
@@ -234,28 +239,28 @@ class APFixedPoint {
   /// If the overflow parameter is provided, and the integral value is not able
   /// to be fully stored in the provided width and sign, the overflow parameter
   /// is set to true.
-  APSInt convertToInt(unsigned DstWidth, bool DstSign,
-                      bool *Overflow = nullptr) const;
+  LLVM_ABI APSInt convertToInt(unsigned DstWidth, bool DstSign,
+                               bool *Overflow = nullptr) const;
 
   /// Convert this fixed point number to a floating point value with the
   /// provided semantics.
-  APFloat convertToFloat(const fltSemantics &FloatSema) const;
+  LLVM_ABI APFloat convertToFloat(const fltSemantics &FloatSema) const;
 
-  void toString(SmallVectorImpl<char> &Str) const;
+  LLVM_ABI void toString(SmallVectorImpl<char> &Str) const;
   std::string toString() const {
     SmallString<40> S;
     toString(S);
     return std::string(S);
   }
 
-  void print(raw_ostream &) const;
+  LLVM_ABI void print(raw_ostream &) const;
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
   LLVM_DUMP_METHOD void dump() const;
 #endif
 
   // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1.
-  int compare(const APFixedPoint &Other) const;
+  LLVM_ABI int compare(const APFixedPoint &Other) const;
   bool operator==(const APFixedPoint &Other) const {
     return compare(Other) == 0;
   }
@@ -271,21 +276,22 @@ class APFixedPoint {
     return compare(Other) <= 0;
   }
 
-  static APFixedPoint getMax(const FixedPointSemantics &Sema);
-  static APFixedPoint getMin(const FixedPointSemantics &Sema);
-  static APFixedPoint getEpsilon(const FixedPointSemantics &Sema);
+  LLVM_ABI static APFixedPoint getMax(const FixedPointSemantics &Sema);
+  LLVM_ABI static APFixedPoint getMin(const FixedPointSemantics &Sema);
+  LLVM_ABI static APFixedPoint getEpsilon(const FixedPointSemantics &Sema);
 
   /// Given a floating point semantic, return the next floating point semantic
   /// with a larger exponent and larger or equal mantissa.
-  static const fltSemantics *promoteFloatSemantics(const fltSemantics *S);
+  LLVM_ABI static const fltSemantics *
+  promoteFloatSemantics(const fltSemantics *S);
 
   /// Create an APFixedPoint with a value equal to that of the provided integer,
   /// and in the same semantics as the provided target semantics. If the value
   /// is not able to fit in the specified fixed point semantics, and the
   /// overflow parameter is provided, it is set to true.
-  static APFixedPoint getFromIntValue(const APSInt &Value,
-                                      const FixedPointSemantics &DstFXSema,
-                                      bool *Overflow = nullptr);
+  LLVM_ABI static APFixedPoint
+  getFromIntValue(const APSInt &Value, const FixedPointSemantics &DstFXSema,
+                  bool *Overflow = nullptr);
 
   /// Create an APFixedPoint with a value equal to that of the provided
   /// floating point value, in the provided target semantics. If the value is
@@ -294,9 +300,9 @@ class APFixedPoint {
   /// For NaN, the Overflow flag is always set. For +inf and -inf, if the
   /// semantic is saturating, the value saturates. Otherwise, the Overflow flag
   /// is set.
-  static APFixedPoint getFromFloatValue(const APFloat &Value,
-                                        const FixedPointSemantics &DstFXSema,
-                                        bool *Overflow = nullptr);
+  LLVM_ABI static APFixedPoint
+  getFromFloatValue(const APFloat &Value, const FixedPointSemantics &DstFXSema,
+                    bool *Overflow = nullptr);
 
 private:
   APSInt Val;
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index b88cbc56c105c..13df838da3dad 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -18,6 +18,7 @@
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/FloatingPointMode.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/float128.h"
 #include <memory>
@@ -253,38 +254,39 @@ struct APFloatBase {
     S_MaxSemantics = S_x87DoubleExtended,
   };
 
-  static const llvm::fltSemantics &EnumToSemantics(Semantics S);
-  static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem);
-
-  static const fltSemantics &IEEEhalf() LLVM_READNONE;
-  static const fltSemantics &BFloat() LLVM_READNONE;
-  static const fltSemantics &IEEEsingle() LLVM_READNONE;
-  static const fltSemantics &IEEEdouble() LLVM_READNONE;
-  static const fltSemantics &IEEEquad() LLVM_READNONE;
-  static const fltSemantics &PPCDoubleDouble() LLVM_READNONE;
-  static const fltSemantics &PPCDoubleDoubleLegacy() LLVM_READNONE;
-  static const fltSemantics &Float8E5M2() LLVM_READNONE;
-  static const fltSemantics &Float8E5M2FNUZ() LLVM_READNONE;
-  static const fltSemantics &Float8E4M3() LLVM_READNONE;
-  static const fltSemantics &Float8E4M3FN() LLVM_READNONE;
-  static const fltSemantics &Float8E4M3FNUZ() LLVM_READNONE;
-  static const fltSemantics &Float8E4M3B11FNUZ() LLVM_READNONE;
-  static const fltSemantics &Float8E3M4() LLVM_READNONE;
-  static const fltSemantics &FloatTF32() LLVM_READNONE;
-  static const fltSemantics &Float8E8M0FNU() LLVM_READNONE;
-  static const fltSemantics &Float6E3M2FN() LLVM_READNONE;
-  static const fltSemantics &Float6E2M3FN() LLVM_READNONE;
-  static const fltSemantics &Float4E2M1FN() LLVM_READNONE;
-  static const fltSemantics &x87DoubleExtended() LLVM_READNONE;
+  LLVM_ABI static const llvm::fltSemantics &EnumToSemantics(Semantics S);
+  LLVM_ABI static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem);
+
+  LLVM_ABI static const fltSemantics &IEEEhalf() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &BFloat() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &IEEEsingle() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &IEEEdouble() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &IEEEquad() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &PPCDoubleDouble() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &PPCDoubleDoubleLegacy() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E5M2() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E5M2FNUZ() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E4M3() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E4M3FN() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E4M3FNUZ() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E4M3B11FNUZ() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E3M4() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &FloatTF32() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E8M0FNU() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float6E3M2FN() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float6E2M3FN() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float4E2M1FN() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &x87DoubleExtended() LLVM_READNONE;
 
   /// A Pseudo fltsemantic used to construct APFloats that cannot conflict with
   /// anything real.
-  static const fltSemantics &Bogus() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Bogus() LLVM_READNONE;
 
   // Returns true if any number described by this semantics can be precisely
   // represented by the specified semantics. Does not take into account
   // the value of fltNonfiniteBehavior, hasZero, hasSignedRepr.
-  static bool isRepresentableBy(const fltSemantics &A, const fltSemantics &B);
+  LLVM_ABI static bool isRepresentableBy(const fltSemantics &A,
+                                         const fltSemantics &B);
 
   /// @}
 
@@ -344,26 +346,27 @@ struct APFloatBase {
     IEK_Inf = INT_MAX
   };
 
-  static unsigned int semanticsPrecision(const fltSemantics &);
-  static ExponentType semanticsMinExponent(const fltSemantics &);
-  static ExponentType semanticsMaxExponent(const fltSemantics &);
-  static unsigned int semanticsSizeInBits(const fltSemantics &);
-  static unsigned int semanticsIntSizeInBits(const fltSemantics&, bool);
-  static bool semanticsHasZero(const fltSemantics &);
-  static bool semanticsHasSignedRepr(const fltSemantics &);
-  static bool semanticsHasInf(const fltSemantics &);
-  static bool semanticsHasNaN(const fltSemantics &);
-  static bool isIEEELikeFP(const fltSemantics &);
-  static bool hasSignBitInMSB(const fltSemantics &);
+  LLVM_ABI static unsigned int semanticsPrecision(const fltSemantics &);
+  LLVM_ABI static ExponentType semanticsMinExponent(const fltSemantics &);
+  LLVM_ABI static ExponentType semanticsMaxExponent(const fltSemantics &);
+  LLVM_ABI static unsigned int semanticsSizeInBits(const fltSemantics &);
+  LLVM_ABI static unsigned int semanticsIntSizeInBits(const fltSemantics &,
+                                                      bool);
+  LLVM_ABI static bool semanticsHasZero(const fltSemantics &);
+  LLVM_ABI static bool semanticsHasSignedRepr(const fltSemantics &);
+  LLVM_ABI static bool semanticsHasInf(const fltSemantics &);
+  LLVM_ABI static bool semanticsHasNaN(const fltSemantics &);
+  LLVM_ABI static bool isIEEELikeFP(const fltSemantics &);
+  LLVM_ABI static bool hasSignBitInMSB(const fltSemantics &);
 
   // Returns true if any number described by \p Src can be precisely represented
   // by a normal (not subnormal) value in \p Dst.
-  static bool isRepresentableAsNormalIn(const fltSemantics &Src,
-                                        const fltSemantics &Dst);
+  LLVM_ABI static bool isRepresentableAsNormalIn(const fltSemantics &Src,
+                                                 const fltSemantics &Dst);
 
   /// Returns the size of the floating point number (in bits) in the given
   /// semantics.
-  static unsigned getSizeInBits(const fltSemantics &Sem);
+  LLVM_ABI static unsigned getSizeInBits(const fltSemantics &Sem);
 };
 
 namespace detail {
@@ -404,15 +407,15 @@ class IEEEFloat final {
   /// \name Constructors
   /// @{
 
-  IEEEFloat(const fltSemantics &); // Default construct to +0.0
-  IEEEFloat(const fltSemantics &, integerPart);
-  IEEEFloat(const fltSemantics &, uninitializedTag);
-  IEEEFloat(const fltSemantics &, const APInt &);
-  explicit IEEEFloat(double d);
-  explicit IEEEFloat(float f);
-  IEEEFloat(const IEEEFloat &);
-  IEEEFloat(IEEEFloat &&);
-  ~IEEEFloat();
+  LLVM_ABI IEEEFloat(const fltSemantics &); // Default construct to +0.0
+  LLVM_ABI IEEEFloat(const fltSemantics &, integerPart);
+  LLVM_ABI IEEEFloat(const fltSemantics &, uninitializedTag);
+  LLVM_ABI IEEEFloat(const fltSemantics &, const APInt &);
+  LLVM_ABI explicit IEEEFloat(double d);
+  LLVM_ABI explicit IEEEFloat(float f);
+  LLVM_ABI IEEEFloat(const IEEEFloat &);
+  LLVM_ABI IEEEFloat(IEEEFloat &&);
+  LLVM_ABI ~IEEEFloat();
 
   /// @}
 
@@ -427,46 +430,49 @@ class IEEEFloat final {
   /// \name Arithmetic
   /// @{
 
-  opStatus add(const IEEEFloat &, roundingMode);
-  opStatus subtract(const IEEEFloat &, roundingMode);
-  opStatus multiply(const IEEEFloat &, roundingMode);
-  opStatus divide(const IEEEFloat &, roundingMode);
+  LLVM_ABI opStatus add(const IEEEFloat &, roundingMode);
+  LLVM_ABI opStatus subtract(const IEEEFloat &, roundingMode);
+  LLVM_ABI opStatus multiply(const IEEEFloat &, roundingMode);
+  LLVM_ABI opStatus divide(const IEEEFloat &, roundingMode);
   /// IEEE remainder.
-  opStatus remainder(const IEEEFloat &);
+  LLVM_ABI opStatus remainder(const IEEEFloat &);
   /// C fmod, or llvm frem.
-  opStatus mod(const IEEEFloat &);
-  opStatus fusedMultiplyAdd(const IEEEFloat &, const IEEEFloat &, roundingMode);
-  opStatus roundToIntegral(roundingMode);
+  LLVM_ABI opStatus mod(const IEEEFloat &);
+  LLVM_ABI opStatus fusedMultiplyAdd(const IEEEFloat &, const IEEEFloat &,
+                                     roundingMode);
+  LLVM_ABI opStatus roundToIntegral(roundingMode);
   /// IEEE-754R 5.3.1: nextUp/nextDown.
-  opStatus next(bool nextDown);
+  LLVM_ABI opStatus next(bool nextDown);
 
   /// @}
 
   /// \name Sign operations.
   /// @{
 
-  void changeSign();
+  LLVM_ABI void changeSign();
 
   /// @}
 
   /// \name Conversions
   /// @{
 
-  opStatus convert(const fltSemantics &, roundingMode, bool *);
-  opStatus convertToInteger(MutableArrayRef<integerPart>, unsigned int, bool,
-                            roundingMode, bool *) const;
-  opStatus convertFromAPInt(const APInt &, bool, roundingMode);
-  opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
-                                          bool, roundingMode);
-  opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
-                                          bool, roundingMode);
-  Expected<opStatus> convertFromString(StringRef, roundingMode);
-  APInt bitcastToAPInt() const;
-  double convertToDouble() const;
+  LLVM_ABI opStatus convert(const fltSemantics &, roundingMode, bool *);
+  LLVM_ABI opStatus convertToInteger(MutableArrayRef<integerPart>, unsigned int,
+                                     bool, roundingMode, bool *) const;
+  LLVM_ABI opStatus convertFromAPInt(const APInt &, bool, roundingMode);
+  LLVM_ABI opStatus convertFromSignExtendedInteger(const integerPart *,
+                                                   unsigned int, bool,
+                                                   roundingMode);
+  LLVM_ABI opStatus convertFromZeroExtendedInteger(const integerPart *,
+                                                   unsigned int, bool,
+                                                   roundingMode);
+  LLVM_ABI Expected<opStatus> convertFromString(StringRef, roundingMode);
+  LLVM_ABI APInt bitcastToAPInt() const;
+  LLVM_ABI double convertToDouble() const;
 #ifdef HAS_IEE754_FLOAT128
-  float128 convertToQuad() const;
+  LLVM_ABI float128 convertToQuad() const;
 #endif
-  float convertToFloat() const;
+  LLVM_ABI float convertToFloat() const;
 
   /// @}
 
@@ -477,16 +483,16 @@ class IEEEFloat final {
 
   /// IEEE comparison with another floating point number (NaNs compare
   /// unordered, 0==-0).
-  cmpResult compare(const IEEEFloat &) const;
+  LLVM_ABI cmpResult compare(const IEEEFloat &) const;
 
   /// Bitwise comparison for equality (QNaNs compare equal, 0!=-0).
-  bool bitwiseIsEqual(const IEEEFloat &) const;
+  LLVM_ABI bool bitwiseIsEqual(const IEEEFloat &) const;
 
   /// Write out a hexadecimal representation of the floating point value to DST,
   /// which must be of sufficient size, in the C99 form [-]0xh.hhhhp[+-]d.
   /// Return the number of characters written, excluding the terminating NUL.
-  unsigned int convertToHexString(char *dst, unsigned int hexDigits,
-                                  bool upperCase, roundingMode) const;
+  LLVM_ABI unsigned int convertToHexString(char *dst, unsigned int hexDigits,
+                                           bool upperCase, roundingMode) const;
 
   /// \name IEEE-754R 5.7.2 General operations.
   /// @{
@@ -514,7 +520,7 @@ class IEEEFloat final {
 
   /// IEEE-754R isSubnormal(): Returns true if and only if the float is a
   /// denormal.
-  bool isDenormal() const;
+  LLVM_ABI bool isDenormal() const;
 
   /// IEEE-754R isInfinite(): Returns true if and only if the float is infinity.
   bool isInfinity() const { return category == fcInfinity; }
@@ -523,7 +529,7 @@ class IEEEFloat final {
   bool isNaN() const { return category == fcNaN; }
 
   /// Returns true if and only if the float is a signaling NaN.
-  bool isSignaling() const;
+  LLVM_ABI bool isSignaling() const;
 
   /// @}
 
@@ -539,23 +545,23 @@ class IEEEFloat final {
 
   /// Returns true if and only if the number has the smallest possible non-zero
   /// magnitude in the current semantics.
-  bool isSmallest() const;
+  LLVM_ABI bool isSmallest() const;
 
   /// Returns true if this is the smallest (by magnitude) normalized finite
   /// number in the given semantics.
-  bool isSmallestNormalized() const;
+  LLVM_ABI bool isSmallestNormalized() const;
 
   /// Returns true if and only if the number has the largest possible finite
   /// magnitude in the current semantics.
-  bool isLargest() const;
+  LLVM_ABI bool isLargest() const;
 
   /// Returns true if and only if the number is an exact integer.
-  bool isInteger() const;
+  LLVM_ABI bool isInteger() const;
 
   /// @}
 
-  IEEEFloat &operator=(const IEEEFloat &);
-  IEEEFloat &operator=(IEEEFloat &&);
+  LLVM_ABI IEEEFloat &operator=(const IEEEFloat &);
+  LLVM_ABI IEEEFloat &operator=(IEEEFloat &&);
 
   /// Overload to compute a hash code for an APFloat value.
   ///
@@ -566,7 +572,7 @@ class IEEEFloat final {
   /// emphasizes producing different codes for different inputs in order to
   /// be used in canonicalization and memoization. As such, equality is
   /// bitwiseIsEqual, and 0 != -0.
-  friend hash_code hash_value(const IEEEFloat &Arg);
+  LLVM_ABI_FRIEND friend hash_code hash_value(const IEEEFloat &Arg);
 
   /// Converts this value into a decimal string.
   ///
@@ -594,17 +600,18 @@ class IEEEFloat final {
   /// 1.01E-2              5             2       0.0101
   /// 1.01E-2              4             2       0.0101
   /// 1.01E-2              4             1       1.01E-2
-  void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision = 0,
-                unsigned FormatMaxPadding = 3, bool TruncateZero = true) const;
+  LLVM_ABI void toString(SmallVectorImpl<char> &Str,
+                         unsigned FormatPrecision = 0,
+                         unsigned FormatMaxPadding = 3,
+                         bool TruncateZero = true) const;
 
   /// If this value has an exact multiplicative inverse, store it in inv and
   /// return true.
-  bool getExactInverse(APFloat *inv) const;
+  LLVM_ABI bool getExactInverse(APFloat *inv) const;
 
   // If this is an exact power of two, return the exponent while ignoring the
   // sign bit. If it's not an exact power of 2, return INT_MIN
-  LLVM_READONLY
-  int getExactLog2Abs() const;
+  LLVM_ABI LLVM_READONLY int getExactLog2Abs() const;
 
   // If this is an exact power of two, return the exponent. If it's not an exact
   // power of 2, return INT_MIN
@@ -622,33 +629,34 @@ class IEEEFloat final {
   ///   0   -> \c IEK_Zero
   ///   Inf -> \c IEK_Inf
   ///
-  friend int ilogb(const IEEEFloat &Arg);
+  LLVM_ABI_FRIEND friend int ilogb(const IEEEFloat &Arg);
 
   /// Returns: X * 2^Exp for integral exponents.
-  friend IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode);
+  LLVM_ABI_FRIEND friend IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode);
 
-  friend IEEEFloat frexp(const IEEEFloat &X, int &Exp, roundingMode);
+  LLVM_ABI_FRIEND friend IEEEFloat frexp(const IEEEFloat &X, int &Exp,
+                                         roundingMode);
 
   /// \name Special value setters.
   /// @{
 
-  void makeLargest(bool Neg = false);
-  void makeSmallest(bool Neg = false);
-  void makeNaN(bool SNaN = false, bool Neg = false,
-               const APInt *fill = nullptr);
-  void makeInf(bool Neg = false);
-  void makeZero(bool Neg = false);
-  void makeQuiet();
+  LLVM_ABI void makeLargest(bool Neg = false);
+  LLVM_ABI void makeSmallest(bool Neg = false);
+  LLVM_ABI void makeNaN(bool SNaN = false, bool Neg = false,
+                        const APInt *fill = nullptr);
+  LLVM_ABI void makeInf(bool Neg = false);
+  LLVM_ABI void makeZero(bool Neg = false);
+  LLVM_ABI void makeQuiet();
 
   /// Returns the smallest (by magnitude) normalized finite number in the given
   /// semantics.
   ///
   /// \param Negative - True iff the number should be negative
-  void makeSmallestNormalized(bool Negative = false);
+  LLVM_ABI void makeSmallestNormalized(bool Negative = false);
 
   /// @}
 
-  cmpResult compareAbsoluteValue(const IEEEFloat &) const;
+  LLVM_ABI cmpResult compareAbsoluteValue(const IEEEFloat &) const;
 
 private:
   /// \name Simple Queries
@@ -656,7 +664,7 @@ class IEEEFloat final {
 
   integerPart *significandParts();
   const integerPart *significandParts() const;
-  unsigned int partCount() const;
+  LLVM_ABI unsigned int partCount() const;
 
   /// @}
 
@@ -796,10 +804,10 @@ class IEEEFloat final {
   friend class IEEEFloatUnitTestHelper;
 };
 
-hash_code hash_value(const IEEEFloat &Arg);
-int ilogb(const IEEEFloat &Arg);
-IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode);
-IEEEFloat frexp(const IEEEFloat &Val, int &Exp, roundingMode RM);
+LLVM_ABI hash_code hash_value(const IEEEFloat &Arg);
+LLVM_ABI int ilogb(const IEEEFloat &Arg);
+LLVM_ABI IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode);
+LLVM_ABI IEEEFloat frexp(const IEEEFloat &Val, int &Exp, roundingMode RM);
 
 // This mode implements more precise float in terms of two APFloats.
 // The interface and layout is designed for arbitrary underlying semantics,
@@ -817,16 +825,17 @@ class DoubleAPFloat final {
                           DoubleAPFloat &Out, roundingMode RM);
 
 public:
-  DoubleAPFloat(const fltSemantics &S);
-  DoubleAPFloat(const fltSemantics &S, uninitializedTag);
-  DoubleAPFloat(const fltSemantics &S, integerPart);
-  DoubleAPFloat(const fltSemantics &S, const APInt &I);
-  DoubleAPFloat(const fltSemantics &S, APFloat &&First, APFloat &&Second);
-  DoubleAPFloat(const DoubleAPFloat &RHS);
-  DoubleAPFloat(DoubleAPFloat &&RHS);
+  LLVM_ABI DoubleAPFloat(const fltSemantics &S);
+  LLVM_ABI DoubleAPFloat(const fltSemantics &S, uninitializedTag);
+  LLVM_ABI DoubleAPFloat(const fltSemantics &S, integerPart);
+  LLVM_ABI DoubleAPFloat(const fltSemantics &S, const APInt &I);
+  LLVM_ABI DoubleAPFloat(const fltSemantics &S, APFloat &&First,
+                         APFloat &&Second);
+  LLVM_ABI DoubleAPFloat(const DoubleAPFloat &RHS);
+  LLVM_ABI DoubleAPFloat(DoubleAPFloat &&RHS);
   ~DoubleAPFloat();
 
-  DoubleAPFloat &operator=(const DoubleAPFloat &RHS);
+  LLVM_ABI DoubleAPFloat &operator=(const DoubleAPFloat &RHS);
   inline DoubleAPFloat &operator=(DoubleAPFloat &&RHS);
 
   bool needsCleanup() const { return Floats != nullptr; }
@@ -836,71 +845,78 @@ class DoubleAPFloat final {
   inline APFloat &getSecond();
   inline const APFloat &getSecond() const;
 
-  opStatus add(const DoubleAPFloat &RHS, roundingMode RM);
-  opStatus subtract(const DoubleAPFloat &RHS, roundingMode RM);
-  opStatus multiply(const DoubleAPFloat &RHS, roundingMode RM);
-  opStatus divide(const DoubleAPFloat &RHS, roundingMode RM);
-  opStatus remainder(const DoubleAPFloat &RHS);
-  opStatus mod(const DoubleAPFloat &RHS);
-  opStatus fusedMultiplyAdd(const DoubleAPFloat &Multiplicand,
-                            const DoubleAPFloat &Addend, roundingMode RM);
-  opStatus roundToIntegral(roundingMode RM);
-  void changeSign();
-  cmpResult compareAbsoluteValue(const DoubleAPFloat &RHS) const;
-
-  fltCategory getCategory() const;
-  bool isNegative() const;
-
-  void makeInf(bool Neg);
-  void makeZero(bool Neg);
-  void makeLargest(bool Neg);
-  void makeSmallest(bool Neg);
-  void makeSmallestNormalized(bool Neg);
-  void makeNaN(bool SNaN, bool Neg, const APInt *fill);
-
-  cmpResult compare(const DoubleAPFloat &RHS) const;
-  bool bitwiseIsEqual(const DoubleAPFloat &RHS) const;
-  APInt bitcastToAPInt() const;
-  Expected<opStatus> convertFromString(StringRef, roundingMode);
-  opStatus next(bool nextDown);
-
-  opStatus convertToInteger(MutableArrayRef<integerPart> Input,
-                            unsigned int Width, bool IsSigned, roundingMode RM,
-                            bool *IsExact) const;
-  opStatus convertFromAPInt(const APInt &Input, bool IsSigned, roundingMode RM);
-  opStatus convertFromSignExtendedInteger(const integerPart *Input,
-                                          unsigned int InputSize, bool IsSigned,
-                                          roundingMode RM);
-  opStatus convertFromZeroExtendedInteger(const integerPart *Input,
-                                          unsigned int InputSize, bool IsSigned,
-                                          roundingMode RM);
-  unsigned int convertToHexString(char *DST, unsigned int HexDigits,
-                                  bool UpperCase, roundingMode RM) const;
-
-  bool isDenormal() const;
-  bool isSmallest() const;
-  bool isSmallestNormalized() const;
-  bool isLargest() const;
-  bool isInteger() const;
-
-  void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
-                unsigned FormatMaxPadding, bool TruncateZero = true) const;
-
-  bool getExactInverse(APFloat *inv) const;
-
-  LLVM_READONLY
-  int getExactLog2() const;
-  LLVM_READONLY
-  int getExactLog2Abs() const;
-
-  friend DoubleAPFloat scalbn(const DoubleAPFloat &X, int Exp, roundingMode);
-  friend DoubleAPFloat frexp(const DoubleAPFloat &X, int &Exp, roundingMode);
-  friend hash_code hash_value(const DoubleAPFloat &Arg);
+  LLVM_ABI opStatus add(const DoubleAPFloat &RHS, roundingMode RM);
+  LLVM_ABI opStatus subtract(const DoubleAPFloat &RHS, roundingMode RM);
+  LLVM_ABI opStatus multiply(const DoubleAPFloat &RHS, roundingMode RM);
+  LLVM_ABI opStatus divide(const DoubleAPFloat &RHS, roundingMode RM);
+  LLVM_ABI opStatus remainder(const DoubleAPFloat &RHS);
+  LLVM_ABI opStatus mod(const DoubleAPFloat &RHS);
+  LLVM_ABI opStatus fusedMultiplyAdd(const DoubleAPFloat &Multiplicand,
+                                     const DoubleAPFloat &Addend,
+                                     roundingMode RM);
+  LLVM_ABI opStatus roundToIntegral(roundingMode RM);
+  LLVM_ABI void changeSign();
+  LLVM_ABI cmpResult compareAbsoluteValue(const DoubleAPFloat &RHS) const;
+
+  LLVM_ABI fltCategory getCategory() const;
+  LLVM_ABI bool isNegative() const;
+
+  LLVM_ABI void makeInf(bool Neg);
+  LLVM_ABI void makeZero(bool Neg);
+  LLVM_ABI void makeLargest(bool Neg);
+  LLVM_ABI void makeSmallest(bool Neg);
+  LLVM_ABI void makeSmallestNormalized(bool Neg);
+  LLVM_ABI void makeNaN(bool SNaN, bool Neg, const APInt *fill);
+
+  LLVM_ABI cmpResult compare(const DoubleAPFloat &RHS) const;
+  LLVM_ABI bool bitwiseIsEqual(const DoubleAPFloat &RHS) const;
+  LLVM_ABI APInt bitcastToAPInt() const;
+  LLVM_ABI Expected<opStatus> convertFromString(StringRef, roundingMode);
+  LLVM_ABI opStatus next(bool nextDown);
+
+  LLVM_ABI opStatus convertToInteger(MutableArrayRef<integerPart> Input,
+                                     unsigned int Width, bool IsSigned,
+                                     roundingMode RM, bool *IsExact) const;
+  LLVM_ABI opStatus convertFromAPInt(const APInt &Input, bool IsSigned,
+                                     roundingMode RM);
+  LLVM_ABI opStatus convertFromSignExtendedInteger(const integerPart *Input,
+                                                   unsigned int InputSize,
+                                                   bool IsSigned,
+                                                   roundingMode RM);
+  LLVM_ABI opStatus convertFromZeroExtendedInteger(const integerPart *Input,
+                                                   unsigned int InputSize,
+                                                   bool IsSigned,
+                                                   roundingMode RM);
+  LLVM_ABI unsigned int convertToHexString(char *DST, unsigned int HexDigits,
+                                           bool UpperCase,
+                                           roundingMode RM) const;
+
+  LLVM_ABI bool isDenormal() const;
+  LLVM_ABI bool isSmallest() const;
+  LLVM_ABI bool isSmallestNormalized() const;
+  LLVM_ABI bool isLargest() const;
+  LLVM_ABI bool isInteger() const;
+
+  LLVM_ABI void toString(SmallVectorImpl<char> &Str, unsigned FormatPrecision,
+                         unsigned FormatMaxPadding,
+                         bool TruncateZero = true) const;
+
+  LLVM_ABI bool getExactInverse(APFloat *inv) const;
+
+  LLVM_ABI LLVM_READONLY int getExactLog2() const;
+  LLVM_ABI LLVM_READONLY int getExactLog2Abs() const;
+
+  LLVM_ABI_FRIEND friend DoubleAPFloat scalbn(const DoubleAPFloat &X, int Exp,
+                                              roundingMode);
+  LLVM_ABI_FRIEND friend DoubleAPFloat frexp(const DoubleAPFloat &X, int &Exp,
+                                             roundingMode);
+  LLVM_ABI_FRIEND friend hash_code hash_value(const DoubleAPFloat &Arg);
 };
 
-hash_code hash_value(const DoubleAPFloat &Arg);
-DoubleAPFloat scalbn(const DoubleAPFloat &Arg, int Exp, roundingMode RM);
-DoubleAPFloat frexp(const DoubleAPFloat &X, int &Exp, roundingMode);
+LLVM_ABI hash_code hash_value(const DoubleAPFloat &Arg);
+LLVM_ABI DoubleAPFloat scalbn(const DoubleAPFloat &Arg, int Exp,
+                              roundingMode RM);
+LLVM_ABI DoubleAPFloat frexp(const DoubleAPFloat &X, int &Exp, roundingMode);
 
 } // End detail namespace
 
@@ -917,7 +933,7 @@ class APFloat : public APFloatBase {
     IEEEFloat IEEE;
     DoubleAPFloat Double;
 
-    explicit Storage(IEEEFloat F, const fltSemantics &S);
+    LLVM_ABI explicit Storage(IEEEFloat F, const fltSemantics &S);
     explicit Storage(DoubleAPFloat F, const fltSemantics &S)
         : Double(std::move(F)) {
       assert(&S == &PPCDoubleDouble());
@@ -1062,7 +1078,7 @@ class APFloat : public APFloatBase {
 
 public:
   APFloat(const fltSemantics &Semantics) : U(Semantics) {}
-  APFloat(const fltSemantics &Semantics, StringRef S);
+  LLVM_ABI APFloat(const fltSemantics &Semantics, StringRef S);
   APFloat(const fltSemantics &Semantics, integerPart I) : U(Semantics, I) {}
   template <typename T,
             typename = std::enable_if_t<std::is_floating_point<T>::value>>
@@ -1172,7 +1188,7 @@ class APFloat : public APFloatBase {
   /// Returns a float which is bitcasted from an all one value int.
   ///
   /// \param Semantics - type float semantics
-  static APFloat getAllOnesValue(const fltSemantics &Semantics);
+  LLVM_ABI static APFloat getAllOnesValue(const fltSemantics &Semantics);
 
   /// Returns true if the given semantics has actual significand.
   ///
@@ -1183,7 +1199,7 @@ class APFloat : public APFloatBase {
 
   /// Used to insert APFloat objects, or objects that contain APFloat objects,
   /// into FoldingSets.
-  void Profile(FoldingSetNodeID &NID) const;
+  LLVM_ABI void Profile(FoldingSetNodeID &NID) const;
 
   opStatus add(const APFloat &RHS, roundingMode RM) {
     assert(&getSemantics() == &RHS.getSemantics() &&
@@ -1326,16 +1342,16 @@ class APFloat : public APFloatBase {
     return Result;
   }
 
-  opStatus convert(const fltSemantics &ToSemantics, roundingMode RM,
-                   bool *losesInfo);
+  LLVM_ABI opStatus convert(const fltSemantics &ToSemantics, roundingMode RM,
+                            bool *losesInfo);
   opStatus convertToInteger(MutableArrayRef<integerPart> Input,
                             unsigned int Width, bool IsSigned, roundingMode RM,
                             bool *IsExact) const {
     APFLOAT_DISPATCH_ON_SEMANTICS(
         convertToInteger(Input, Width, IsSigned, RM, IsExact));
   }
-  opStatus convertToInteger(APSInt &Result, roundingMode RM,
-                            bool *IsExact) const;
+  LLVM_ABI opStatus convertToInteger(APSInt &Result, roundingMode RM,
+                                     bool *IsExact) const;
   opStatus convertFromAPInt(const APInt &Input, bool IsSigned,
                             roundingMode RM) {
     APFLOAT_DISPATCH_ON_SEMANTICS(convertFromAPInt(Input, IsSigned, RM));
@@ -1352,7 +1368,7 @@ class APFloat : public APFloatBase {
     APFLOAT_DISPATCH_ON_SEMANTICS(
         convertFromZeroExtendedInteger(Input, InputSize, IsSigned, RM));
   }
-  Expected<opStatus> convertFromString(StringRef, roundingMode);
+  LLVM_ABI Expected<opStatus> convertFromString(StringRef, roundingMode);
   APInt bitcastToAPInt() const {
     APFLOAT_DISPATCH_ON_SEMANTICS(bitcastToAPInt());
   }
@@ -1362,7 +1378,7 @@ class APFloat : public APFloatBase {
   /// \pre The APFloat must be built using semantics, that can be represented by
   /// the host double type without loss of precision. It can be IEEEdouble and
   /// shorter semantics, like IEEEsingle and others.
-  double convertToDouble() const;
+  LLVM_ABI double convertToDouble() const;
 
   /// Converts this APFloat to host float value.
   ///
@@ -1370,7 +1386,7 @@ class APFloat : public APFloatBase {
   /// the host float type without loss of precision. It can be IEEEquad and
   /// shorter semantics, like IEEEdouble and others.
 #ifdef HAS_IEE754_FLOAT128
-  float128 convertToQuad() const;
+  LLVM_ABI float128 convertToQuad() const;
 #endif
 
   /// Converts this APFloat to host float value.
@@ -1378,7 +1394,7 @@ class APFloat : public APFloatBase {
   /// \pre The APFloat must be built using semantics, that can be represented by
   /// the host float type without loss of precision. It can be IEEEsingle and
   /// shorter semantics, like IEEEhalf.
-  float convertToFloat() const;
+  LLVM_ABI float convertToFloat() const;
 
   bool operator==(const APFloat &RHS) const { return compare(RHS) == cmpEqual; }
 
@@ -1471,7 +1487,7 @@ class APFloat : public APFloatBase {
   }
 
   /// Return the FPClassTest which will return true for the value.
-  FPClassTest classify() const;
+  LLVM_ABI FPClassTest classify() const;
 
   APFloat &operator=(const APFloat &RHS) = default;
   APFloat &operator=(APFloat &&RHS) = default;
@@ -1482,7 +1498,7 @@ class APFloat : public APFloatBase {
         toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero));
   }
 
-  void print(raw_ostream &) const;
+  LLVM_ABI void print(raw_ostream &) const;
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
   LLVM_DUMP_METHOD void dump() const;
@@ -1502,7 +1518,7 @@ class APFloat : public APFloatBase {
     APFLOAT_DISPATCH_ON_SEMANTICS(getExactLog2());
   }
 
-  friend hash_code hash_value(const APFloat &Arg);
+  LLVM_ABI_FRIEND friend hash_code hash_value(const APFloat &Arg);
   friend int ilogb(const APFloat &Arg) { return ilogb(Arg.getIEEE()); }
   friend APFloat scalbn(APFloat X, int Exp, roundingMode RM);
   friend APFloat frexp(const APFloat &X, int &Exp, roundingMode RM);
@@ -1517,7 +1533,7 @@ static_assert(sizeof(APFloat) == sizeof(detail::IEEEFloat),
 ///
 /// These additional declarations are required in order to compile LLVM with IBM
 /// xlC compiler.
-hash_code hash_value(const APFloat &Arg);
+LLVM_ABI hash_code hash_value(const APFloat &Arg);
 inline APFloat scalbn(APFloat X, int Exp, APFloat::roundingMode RM) {
   if (APFloat::usesLayout<detail::IEEEFloat>(X.getSemantics()))
     return APFloat(scalbn(X.U.IEEE, Exp, RM), X.getSemantics());
diff --git a/llvm/include/llvm/ADT/APInt.h b/llvm/include/llvm/ADT/APInt.h
index afdd2cfddb12b..fe48c60466e96 100644
--- a/llvm/include/llvm/ADT/APInt.h
+++ b/llvm/include/llvm/ADT/APInt.h
@@ -145,7 +145,7 @@ class [[nodiscard]] APInt {
   ///
   /// \param numBits the bit width of the constructed APInt
   /// \param bigVal a sequence of words to form the initial value of the APInt
-  APInt(unsigned numBits, ArrayRef<uint64_t> bigVal);
+  LLVM_ABI APInt(unsigned numBits, ArrayRef<uint64_t> bigVal);
 
   /// Equivalent to APInt(numBits, ArrayRef<uint64_t>(bigVal, numWords)), but
   /// deprecated because this constructor is prone to ambiguity with the
@@ -154,7 +154,7 @@ class [[nodiscard]] APInt {
   /// If this overload is ever deleted, care should be taken to prevent calls
   /// from being incorrectly captured by the APInt(unsigned, uint64_t, bool)
   /// constructor.
-  APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
+  LLVM_ABI APInt(unsigned numBits, unsigned numWords, const uint64_t bigVal[]);
 
   /// Construct an APInt from a string representation.
   ///
@@ -167,7 +167,7 @@ class [[nodiscard]] APInt {
   /// \param numBits the bit width of the constructed APInt
   /// \param str the string to be interpreted
   /// \param radix the radix to use for the conversion
-  APInt(unsigned numBits, StringRef str, uint8_t radix);
+  LLVM_ABI APInt(unsigned numBits, StringRef str, uint8_t radix);
 
   /// Default constructor that creates an APInt with a 1-bit zero value.
   explicit APInt() { U.VAL = 0; }
@@ -310,7 +310,7 @@ class [[nodiscard]] APInt {
   }
 
   /// Return a value containing V broadcasted over NewLen bits.
-  static APInt getSplat(unsigned NewLen, const APInt &V);
+  LLVM_ABI static APInt getSplat(unsigned NewLen, const APInt &V);
 
   /// @}
   /// \name Value Tests
@@ -458,7 +458,7 @@ class [[nodiscard]] APInt {
 
   /// Checks if this APInt -interpreted as an address- is aligned to the
   /// provided value.
-  bool isAligned(Align A) const;
+  LLVM_ABI bool isAligned(Align A) const;
 
   /// Check if the APInt's value is returned by getSignMask.
   ///
@@ -481,7 +481,7 @@ class [[nodiscard]] APInt {
   /// e.g. 0x01010101 satisfies isSplat(8).
   /// \param SplatSizeInBits The size of the pattern in bits. Must divide bit
   /// width without remainder.
-  bool isSplat(unsigned SplatSizeInBits) const;
+  LLVM_ABI bool isSplat(unsigned SplatSizeInBits) const;
 
   /// \returns true if this APInt value is a sequence of \param numBits ones
   /// starting at the least significant bit with the remainder zero.
@@ -538,7 +538,7 @@ class [[nodiscard]] APInt {
   /// bits and right shift to the least significant bit.
   ///
   /// \returns the high "numBits" bits of this APInt.
-  APInt getHiBits(unsigned numBits) const;
+  LLVM_ABI APInt getHiBits(unsigned numBits) const;
 
   /// Compute an APInt containing numBits lowbits from this APInt.
   ///
@@ -546,7 +546,7 @@ class [[nodiscard]] APInt {
   /// bits.
   ///
   /// \returns the low "numBits" bits of this APInt.
-  APInt getLoBits(unsigned numBits) const;
+  LLVM_ABI APInt getLoBits(unsigned numBits) const;
 
   /// Determine if two APInts have the same value, after zero-extending
   /// one of them (if needed!) to ensure that the bit-widths match.
@@ -588,7 +588,7 @@ class [[nodiscard]] APInt {
   /// Prefix increment operator.
   ///
   /// \returns *this incremented by one
-  APInt &operator++();
+  LLVM_ABI APInt &operator++();
 
   /// Postfix decrement operator. Decrement *this by 1.
   ///
@@ -602,7 +602,7 @@ class [[nodiscard]] APInt {
   /// Prefix decrement operator.
   ///
   /// \returns *this decremented by one.
-  APInt &operator--();
+  LLVM_ABI APInt &operator--();
 
   /// Logical negation operation on this APInt returns true if zero, like normal
   /// integers.
@@ -758,24 +758,24 @@ class [[nodiscard]] APInt {
   /// Multiplies this APInt by RHS and assigns the result to *this.
   ///
   /// \returns *this
-  APInt &operator*=(const APInt &RHS);
-  APInt &operator*=(uint64_t RHS);
+  LLVM_ABI APInt &operator*=(const APInt &RHS);
+  LLVM_ABI APInt &operator*=(uint64_t RHS);
 
   /// Addition assignment operator.
   ///
   /// Adds RHS to *this and assigns the result to *this.
   ///
   /// \returns *this
-  APInt &operator+=(const APInt &RHS);
-  APInt &operator+=(uint64_t RHS);
+  LLVM_ABI APInt &operator+=(const APInt &RHS);
+  LLVM_ABI APInt &operator+=(uint64_t RHS);
 
   /// Subtraction assignment operator.
   ///
   /// Subtracts RHS from *this and assigns the result to *this.
   ///
   /// \returns *this
-  APInt &operator-=(const APInt &RHS);
-  APInt &operator-=(uint64_t RHS);
+  LLVM_ABI APInt &operator-=(const APInt &RHS);
+  LLVM_ABI APInt &operator-=(uint64_t RHS);
 
   /// Left-shift assignment function.
   ///
@@ -800,7 +800,7 @@ class [[nodiscard]] APInt {
   /// Shifts *this left by shiftAmt and assigns the result to *this.
   ///
   /// \returns *this after shifting left by ShiftAmt
-  APInt &operator<<=(const APInt &ShiftAmt);
+  LLVM_ABI APInt &operator<<=(const APInt &ShiftAmt);
 
   /// @}
   /// \name Binary Operators
@@ -809,7 +809,7 @@ class [[nodiscard]] APInt {
   /// Multiplication operator.
   ///
   /// Multiplies this APInt by RHS and returns the result.
-  APInt operator*(const APInt &RHS) const;
+  LLVM_ABI APInt operator*(const APInt &RHS) const;
 
   /// Left logical shift operator.
   ///
@@ -897,10 +897,10 @@ class [[nodiscard]] APInt {
   }
 
   /// Rotate left by rotateAmt.
-  APInt rotl(unsigned rotateAmt) const;
+  LLVM_ABI APInt rotl(unsigned rotateAmt) const;
 
   /// Rotate right by rotateAmt.
-  APInt rotr(unsigned rotateAmt) const;
+  LLVM_ABI APInt rotr(unsigned rotateAmt) const;
 
   /// Arithmetic right-shift function.
   ///
@@ -912,7 +912,7 @@ class [[nodiscard]] APInt {
   }
 
   /// Arithmetic right-shift this APInt by shiftAmt in place.
-  void ashrInPlace(const APInt &shiftAmt);
+  LLVM_ABI void ashrInPlace(const APInt &shiftAmt);
 
   /// Logical right-shift function.
   ///
@@ -924,7 +924,7 @@ class [[nodiscard]] APInt {
   }
 
   /// Logical right-shift this APInt by ShiftAmt in place.
-  void lshrInPlace(const APInt &ShiftAmt);
+  LLVM_ABI void lshrInPlace(const APInt &ShiftAmt);
 
   /// Left-shift function.
   ///
@@ -936,10 +936,10 @@ class [[nodiscard]] APInt {
   }
 
   /// Rotate left by rotateAmt.
-  APInt rotl(const APInt &rotateAmt) const;
+  LLVM_ABI APInt rotl(const APInt &rotateAmt) const;
 
   /// Rotate right by rotateAmt.
-  APInt rotr(const APInt &rotateAmt) const;
+  LLVM_ABI APInt rotr(const APInt &rotateAmt) const;
 
   /// Concatenate the bits from "NewLSB" onto the bottom of *this.  This is
   /// equivalent to:
@@ -959,16 +959,16 @@ class [[nodiscard]] APInt {
   ///
   /// \returns a new APInt value containing the division result, rounded towards
   /// zero.
-  APInt udiv(const APInt &RHS) const;
-  APInt udiv(uint64_t RHS) const;
+  LLVM_ABI APInt udiv(const APInt &RHS) const;
+  LLVM_ABI APInt udiv(uint64_t RHS) const;
 
   /// Signed division function for APInt.
   ///
   /// Signed divide this APInt by APInt RHS.
   ///
   /// The result is rounded towards zero.
-  APInt sdiv(const APInt &RHS) const;
-  APInt sdiv(int64_t RHS) const;
+  LLVM_ABI APInt sdiv(const APInt &RHS) const;
+  LLVM_ABI APInt sdiv(int64_t RHS) const;
 
   /// Unsigned remainder operation.
   ///
@@ -977,8 +977,8 @@ class [[nodiscard]] APInt {
   /// of this operation.
   ///
   /// \returns a new APInt value containing the remainder result
-  APInt urem(const APInt &RHS) const;
-  uint64_t urem(uint64_t RHS) const;
+  LLVM_ABI APInt urem(const APInt &RHS) const;
+  LLVM_ABI uint64_t urem(uint64_t RHS) const;
 
   /// Function for signed remainder operation.
   ///
@@ -986,8 +986,8 @@ class [[nodiscard]] APInt {
   ///
   /// Note that this is a true remainder operation and not a modulo operation
   /// because the sign follows the sign of the dividend which is *this.
-  APInt srem(const APInt &RHS) const;
-  int64_t srem(int64_t RHS) const;
+  LLVM_ABI APInt srem(const APInt &RHS) const;
+  LLVM_ABI int64_t srem(int64_t RHS) const;
 
   /// Dual division/remainder interface.
   ///
@@ -996,46 +996,46 @@ class [[nodiscard]] APInt {
   /// computation making it a little more efficient. The pair of input arguments
   /// may overlap with the pair of output arguments. It is safe to call
   /// udivrem(X, Y, X, Y), for example.
-  static void udivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient,
-                      APInt &Remainder);
-  static void udivrem(const APInt &LHS, uint64_t RHS, APInt &Quotient,
-                      uint64_t &Remainder);
+  LLVM_ABI static void udivrem(const APInt &LHS, const APInt &RHS,
+                               APInt &Quotient, APInt &Remainder);
+  LLVM_ABI static void udivrem(const APInt &LHS, uint64_t RHS, APInt &Quotient,
+                               uint64_t &Remainder);
 
-  static void sdivrem(const APInt &LHS, const APInt &RHS, APInt &Quotient,
-                      APInt &Remainder);
-  static void sdivrem(const APInt &LHS, int64_t RHS, APInt &Quotient,
-                      int64_t &Remainder);
+  LLVM_ABI static void sdivrem(const APInt &LHS, const APInt &RHS,
+                               APInt &Quotient, APInt &Remainder);
+  LLVM_ABI static void sdivrem(const APInt &LHS, int64_t RHS, APInt &Quotient,
+                               int64_t &Remainder);
 
   // Operations that return overflow indicators.
-  APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
-  APInt uadd_ov(const APInt &RHS, bool &Overflow) const;
-  APInt ssub_ov(const APInt &RHS, bool &Overflow) const;
-  APInt usub_ov(const APInt &RHS, bool &Overflow) const;
-  APInt sdiv_ov(const APInt &RHS, bool &Overflow) const;
-  APInt smul_ov(const APInt &RHS, bool &Overflow) const;
-  APInt umul_ov(const APInt &RHS, bool &Overflow) const;
-  APInt sshl_ov(const APInt &Amt, bool &Overflow) const;
-  APInt sshl_ov(unsigned Amt, bool &Overflow) const;
-  APInt ushl_ov(const APInt &Amt, bool &Overflow) const;
-  APInt ushl_ov(unsigned Amt, bool &Overflow) const;
+  LLVM_ABI APInt sadd_ov(const APInt &RHS, bool &Overflow) const;
+  LLVM_ABI APInt uadd_ov(const APInt &RHS, bool &Overflow) const;
+  LLVM_ABI APInt ssub_ov(const APInt &RHS, bool &Overflow) const;
+  LLVM_ABI APInt usub_ov(const APInt &RHS, bool &Overflow) const;
+  LLVM_ABI APInt sdiv_ov(const APInt &RHS, bool &Overflow) const;
+  LLVM_ABI APInt smul_ov(const APInt &RHS, bool &Overflow) const;
+  LLVM_ABI APInt umul_ov(const APInt &RHS, bool &Overflow) const;
+  LLVM_ABI APInt sshl_ov(const APInt &Amt, bool &Overflow) const;
+  LLVM_ABI APInt sshl_ov(unsigned Amt, bool &Overflow) const;
+  LLVM_ABI APInt ushl_ov(const APInt &Amt, bool &Overflow) const;
+  LLVM_ABI APInt ushl_ov(unsigned Amt, bool &Overflow) const;
 
   /// Signed integer floor division operation.
   ///
   /// Rounds towards negative infinity, i.e. 5 / -2 = -3. Iff minimum value
   /// divided by -1 set Overflow to true.
-  APInt sfloordiv_ov(const APInt &RHS, bool &Overflow) const;
+  LLVM_ABI APInt sfloordiv_ov(const APInt &RHS, bool &Overflow) const;
 
   // Operations that saturate
-  APInt sadd_sat(const APInt &RHS) const;
-  APInt uadd_sat(const APInt &RHS) const;
-  APInt ssub_sat(const APInt &RHS) const;
-  APInt usub_sat(const APInt &RHS) const;
-  APInt smul_sat(const APInt &RHS) const;
-  APInt umul_sat(const APInt &RHS) const;
-  APInt sshl_sat(const APInt &RHS) const;
-  APInt sshl_sat(unsigned RHS) const;
-  APInt ushl_sat(const APInt &RHS) const;
-  APInt ushl_sat(unsigned RHS) const;
+  LLVM_ABI APInt sadd_sat(const APInt &RHS) const;
+  LLVM_ABI APInt uadd_sat(const APInt &RHS) const;
+  LLVM_ABI APInt ssub_sat(const APInt &RHS) const;
+  LLVM_ABI APInt usub_sat(const APInt &RHS) const;
+  LLVM_ABI APInt smul_sat(const APInt &RHS) const;
+  LLVM_ABI APInt umul_sat(const APInt &RHS) const;
+  LLVM_ABI APInt sshl_sat(const APInt &RHS) const;
+  LLVM_ABI APInt sshl_sat(unsigned RHS) const;
+  LLVM_ABI APInt ushl_sat(const APInt &RHS) const;
+  LLVM_ABI APInt ushl_sat(unsigned RHS) const;
 
   /// Array-indexing support.
   ///
@@ -1269,20 +1269,20 @@ class [[nodiscard]] APInt {
   ///
   /// Truncate the APInt to a specified width. It is an error to specify a width
   /// that is greater than the current width.
-  APInt trunc(unsigned width) const;
+  LLVM_ABI APInt trunc(unsigned width) const;
 
   /// Truncate to new width with unsigned saturation.
   ///
   /// If the APInt, treated as unsigned integer, can be losslessly truncated to
   /// the new bitwidth, then return truncated APInt. Else, return max value.
-  APInt truncUSat(unsigned width) const;
+  LLVM_ABI APInt truncUSat(unsigned width) const;
 
   /// Truncate to new width with signed saturation.
   ///
   /// If this APInt, treated as signed integer, can be losslessly truncated to
   /// the new bitwidth, then return truncated APInt. Else, return either
   /// signed min value if the APInt was negative, or signed max value.
-  APInt truncSSat(unsigned width) const;
+  LLVM_ABI APInt truncSSat(unsigned width) const;
 
   /// Sign extend to a new width.
   ///
@@ -1290,26 +1290,26 @@ class [[nodiscard]] APInt {
   /// bit is set, the fill on the left will be done with 1 bits, otherwise zero.
   /// It is an error to specify a width that is less than the
   /// current width.
-  APInt sext(unsigned width) const;
+  LLVM_ABI APInt sext(unsigned width) const;
 
   /// Zero extend to a new width.
   ///
   /// This operation zero extends the APInt to a new width. The high order bits
   /// are filled with 0 bits.  It is an error to specify a width that is less
   /// than the current width.
-  APInt zext(unsigned width) const;
+  LLVM_ABI APInt zext(unsigned width) const;
 
   /// Sign extend or truncate to width
   ///
   /// Make this APInt have the bit width given by \p width. The value is sign
   /// extended, truncated, or left alone to make it that width.
-  APInt sextOrTrunc(unsigned width) const;
+  LLVM_ABI APInt sextOrTrunc(unsigned width) const;
 
   /// Zero extend or truncate to width
   ///
   /// Make this APInt have the bit width given by \p width. The value is zero
   /// extended, truncated, or left alone to make it that width.
-  APInt zextOrTrunc(unsigned width) const;
+  LLVM_ABI APInt zextOrTrunc(unsigned width) const;
 
   /// @}
   /// \name Bit Manipulation Operators
@@ -1462,7 +1462,7 @@ class [[nodiscard]] APInt {
   ///
   /// Toggle a given bit to its opposite value whose position is given
   /// as "bitPosition".
-  void flipBit(unsigned bitPosition);
+  LLVM_ABI void flipBit(unsigned bitPosition);
 
   /// Negate this APInt in place.
   void negate() {
@@ -1471,12 +1471,14 @@ class [[nodiscard]] APInt {
   }
 
   /// Insert the bits from a smaller APInt starting at bitPosition.
-  void insertBits(const APInt &SubBits, unsigned bitPosition);
-  void insertBits(uint64_t SubBits, unsigned bitPosition, unsigned numBits);
+  LLVM_ABI void insertBits(const APInt &SubBits, unsigned bitPosition);
+  LLVM_ABI void insertBits(uint64_t SubBits, unsigned bitPosition,
+                           unsigned numBits);
 
   /// Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
-  APInt extractBits(unsigned numBits, unsigned bitPosition) const;
-  uint64_t extractBitsAsZExtValue(unsigned numBits, unsigned bitPosition) const;
+  LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const;
+  LLVM_ABI uint64_t extractBitsAsZExtValue(unsigned numBits,
+                                           unsigned bitPosition) const;
 
   /// @}
   /// \name Value Characterization Functions
@@ -1578,12 +1580,13 @@ class [[nodiscard]] APInt {
   ///
   /// This method determines how many bits are required to hold the APInt
   /// equivalent of the string given by \p str.
-  static unsigned getBitsNeeded(StringRef str, uint8_t radix);
+  LLVM_ABI static unsigned getBitsNeeded(StringRef str, uint8_t radix);
 
   /// Get the bits that are sufficient to represent the string value. This may
   /// over estimate the amount of bits required, but it does not require
   /// parsing the value in the string.
-  static unsigned getSufficientBitsNeeded(StringRef Str, uint8_t Radix);
+  LLVM_ABI static unsigned getSufficientBitsNeeded(StringRef Str,
+                                                   uint8_t Radix);
 
   /// The APInt version of std::countl_zero.
   ///
@@ -1673,14 +1676,15 @@ class [[nodiscard]] APInt {
   /// @}
   /// \name Conversion Functions
   /// @{
-  void print(raw_ostream &OS, bool isSigned) const;
+  LLVM_ABI void print(raw_ostream &OS, bool isSigned) const;
 
   /// Converts an APInt to a string and append it to Str.  Str is commonly a
   /// SmallString. If Radix > 10, UpperCase determine the case of letter
   /// digits.
-  void toString(SmallVectorImpl<char> &Str, unsigned Radix, bool Signed,
-                bool formatAsCLiteral = false, bool UpperCase = true,
-                bool InsertSeparators = false) const;
+  LLVM_ABI void toString(SmallVectorImpl<char> &Str, unsigned Radix,
+                         bool Signed, bool formatAsCLiteral = false,
+                         bool UpperCase = true,
+                         bool InsertSeparators = false) const;
 
   /// Considers the APInt to be unsigned and converts it into a string in the
   /// radix given. The radix can be 2, 8, 10 16, or 36.
@@ -1695,14 +1699,14 @@ class [[nodiscard]] APInt {
   }
 
   /// \returns a byte-swapped representation of this APInt Value.
-  APInt byteSwap() const;
+  LLVM_ABI APInt byteSwap() const;
 
   /// \returns the value with the bit representation reversed of this APInt
   /// Value.
-  APInt reverseBits() const;
+  LLVM_ABI APInt reverseBits() const;
 
   /// Converts this APInt to a double value.
-  double roundToDouble(bool isSigned) const;
+  LLVM_ABI double roundToDouble(bool isSigned) const;
 
   /// Converts this unsigned APInt to a double value.
   double roundToDouble() const { return roundToDouble(false); }
@@ -1772,7 +1776,7 @@ class [[nodiscard]] APInt {
   ///
   /// to get around any mathematical concerns resulting from
   /// referencing 2 in a space where 2 does no exist.
-  unsigned nearestLogBase2() const;
+  LLVM_ABI unsigned nearestLogBase2() const;
 
   /// \returns the log base 2 of this APInt if its an exact power of two, -1
   /// otherwise
@@ -1783,7 +1787,7 @@ class [[nodiscard]] APInt {
   }
 
   /// Compute the square root.
-  APInt sqrt() const;
+  LLVM_ABI APInt sqrt() const;
 
   /// Get the absolute value.  If *this is < 0 then return -(*this), otherwise
   /// *this.  Note that the "most negative" signed number (e.g. -128 for 8 bit
@@ -1795,7 +1799,7 @@ class [[nodiscard]] APInt {
   }
 
   /// \returns the multiplicative inverse of an odd APInt modulo 2^BitWidth.
-  APInt multiplicativeInverse() const;
+  LLVM_ABI APInt multiplicativeInverse() const;
 
   /// @}
   /// \name Building-block Operations for APInt and APFloat
@@ -1809,48 +1813,50 @@ class [[nodiscard]] APInt {
 
   /// Sets the least significant part of a bignum to the input value, and zeroes
   /// out higher parts.
-  static void tcSet(WordType *, WordType, unsigned);
+  LLVM_ABI static void tcSet(WordType *, WordType, unsigned);
 
   /// Assign one bignum to another.
-  static void tcAssign(WordType *, const WordType *, unsigned);
+  LLVM_ABI static void tcAssign(WordType *, const WordType *, unsigned);
 
   /// Returns true if a bignum is zero, false otherwise.
-  static bool tcIsZero(const WordType *, unsigned);
+  LLVM_ABI static bool tcIsZero(const WordType *, unsigned);
 
   /// Extract the given bit of a bignum; returns 0 or 1.  Zero-based.
-  static int tcExtractBit(const WordType *, unsigned bit);
+  LLVM_ABI static int tcExtractBit(const WordType *, unsigned bit);
 
   /// Copy the bit vector of width srcBITS from SRC, starting at bit srcLSB, to
   /// DST, of dstCOUNT parts, such that the bit srcLSB becomes the least
   /// significant bit of DST.  All high bits above srcBITS in DST are
   /// zero-filled.
-  static void tcExtract(WordType *, unsigned dstCount, const WordType *,
-                        unsigned srcBits, unsigned srcLSB);
+  LLVM_ABI static void tcExtract(WordType *, unsigned dstCount,
+                                 const WordType *, unsigned srcBits,
+                                 unsigned srcLSB);
 
   /// Set the given bit of a bignum.  Zero-based.
-  static void tcSetBit(WordType *, unsigned bit);
+  LLVM_ABI static void tcSetBit(WordType *, unsigned bit);
 
   /// Clear the given bit of a bignum.  Zero-based.
-  static void tcClearBit(WordType *, unsigned bit);
+  LLVM_ABI static void tcClearBit(WordType *, unsigned bit);
 
   /// Returns the bit number of the least or most significant set bit of a
   /// number.  If the input number has no bits set -1U is returned.
-  static unsigned tcLSB(const WordType *, unsigned n);
-  static unsigned tcMSB(const WordType *parts, unsigned n);
+  LLVM_ABI static unsigned tcLSB(const WordType *, unsigned n);
+  LLVM_ABI static unsigned tcMSB(const WordType *parts, unsigned n);
 
   /// Negate a bignum in-place.
-  static void tcNegate(WordType *, unsigned);
+  LLVM_ABI static void tcNegate(WordType *, unsigned);
 
   /// DST += RHS + CARRY where CARRY is zero or one.  Returns the carry flag.
-  static WordType tcAdd(WordType *, const WordType *, WordType carry, unsigned);
+  LLVM_ABI static WordType tcAdd(WordType *, const WordType *, WordType carry,
+                                 unsigned);
   /// DST += RHS.  Returns the carry flag.
-  static WordType tcAddPart(WordType *, WordType, unsigned);
+  LLVM_ABI static WordType tcAddPart(WordType *, WordType, unsigned);
 
   /// DST -= RHS + CARRY where CARRY is zero or one. Returns the carry flag.
-  static WordType tcSubtract(WordType *, const WordType *, WordType carry,
-                             unsigned);
+  LLVM_ABI static WordType tcSubtract(WordType *, const WordType *,
+                                      WordType carry, unsigned);
   /// DST -= RHS.  Returns the carry flag.
-  static WordType tcSubtractPart(WordType *, WordType, unsigned);
+  LLVM_ABI static WordType tcSubtractPart(WordType *, WordType, unsigned);
 
   /// DST += SRC * MULTIPLIER + PART   if add is true
   /// DST  = SRC * MULTIPLIER + PART   if add is false
@@ -1862,21 +1868,22 @@ class [[nodiscard]] APInt {
   /// Otherwise DST is filled with the least significant DSTPARTS parts of the
   /// result, and if all of the omitted higher parts were zero return zero,
   /// otherwise overflow occurred and return one.
-  static int tcMultiplyPart(WordType *dst, const WordType *src,
-                            WordType multiplier, WordType carry,
-                            unsigned srcParts, unsigned dstParts, bool add);
+  LLVM_ABI static int tcMultiplyPart(WordType *dst, const WordType *src,
+                                     WordType multiplier, WordType carry,
+                                     unsigned srcParts, unsigned dstParts,
+                                     bool add);
 
   /// DST = LHS * RHS, where DST has the same width as the operands and is
   /// filled with the least significant parts of the result.  Returns one if
   /// overflow occurred, otherwise zero.  DST must be disjoint from both
   /// operands.
-  static int tcMultiply(WordType *, const WordType *, const WordType *,
-                        unsigned);
+  LLVM_ABI static int tcMultiply(WordType *, const WordType *, const WordType *,
+                                 unsigned);
 
   /// DST = LHS * RHS, where DST has width the sum of the widths of the
   /// operands. No overflow occurs. DST must be disjoint from both operands.
-  static void tcFullMultiply(WordType *, const WordType *, const WordType *,
-                             unsigned, unsigned);
+  LLVM_ABI static void tcFullMultiply(WordType *, const WordType *,
+                                      const WordType *, unsigned, unsigned);
 
   /// If RHS is zero LHS and REMAINDER are left unchanged, return one.
   /// Otherwise set LHS to LHS / RHS with the fractional part discarded, set
@@ -1887,19 +1894,20 @@ class [[nodiscard]] APInt {
   /// SCRATCH is a bignum of the same size as the operands and result for use by
   /// the routine; its contents need not be initialized and are destroyed.  LHS,
   /// REMAINDER and SCRATCH must be distinct.
-  static int tcDivide(WordType *lhs, const WordType *rhs, WordType *remainder,
-                      WordType *scratch, unsigned parts);
+  LLVM_ABI static int tcDivide(WordType *lhs, const WordType *rhs,
+                               WordType *remainder, WordType *scratch,
+                               unsigned parts);
 
   /// Shift a bignum left Count bits. Shifted in bits are zero. There are no
   /// restrictions on Count.
-  static void tcShiftLeft(WordType *, unsigned Words, unsigned Count);
+  LLVM_ABI static void tcShiftLeft(WordType *, unsigned Words, unsigned Count);
 
   /// Shift a bignum right Count bits.  Shifted in bits are zero.  There are no
   /// restrictions on Count.
-  static void tcShiftRight(WordType *, unsigned Words, unsigned Count);
+  LLVM_ABI static void tcShiftRight(WordType *, unsigned Words, unsigned Count);
 
   /// Comparison (unsigned) of two bignums.
-  static int tcCompare(const WordType *, const WordType *, unsigned);
+  LLVM_ABI static int tcCompare(const WordType *, const WordType *, unsigned);
 
   /// Increment a bignum in-place.  Return the carry flag.
   static WordType tcIncrement(WordType *dst, unsigned parts) {
@@ -1913,7 +1921,7 @@ class [[nodiscard]] APInt {
 
   /// Used to insert APInt objects, or objects that contain APInt objects, into
   ///  FoldingSets.
-  void Profile(FoldingSetNodeID &id) const;
+  LLVM_ABI void Profile(FoldingSetNodeID &id) const;
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
   /// debug method
@@ -2024,78 +2032,78 @@ class [[nodiscard]] APInt {
                      WordType *Remainder);
 
   /// out-of-line slow case for inline constructor
-  void initSlowCase(uint64_t val, bool isSigned);
+  LLVM_ABI void initSlowCase(uint64_t val, bool isSigned);
 
   /// shared code between two array constructors
   void initFromArray(ArrayRef<uint64_t> array);
 
   /// out-of-line slow case for inline copy constructor
-  void initSlowCase(const APInt &that);
+  LLVM_ABI void initSlowCase(const APInt &that);
 
   /// out-of-line slow case for shl
-  void shlSlowCase(unsigned ShiftAmt);
+  LLVM_ABI void shlSlowCase(unsigned ShiftAmt);
 
   /// out-of-line slow case for lshr.
-  void lshrSlowCase(unsigned ShiftAmt);
+  LLVM_ABI void lshrSlowCase(unsigned ShiftAmt);
 
   /// out-of-line slow case for ashr.
-  void ashrSlowCase(unsigned ShiftAmt);
+  LLVM_ABI void ashrSlowCase(unsigned ShiftAmt);
 
   /// out-of-line slow case for operator=
-  void assignSlowCase(const APInt &RHS);
+  LLVM_ABI void assignSlowCase(const APInt &RHS);
 
   /// out-of-line slow case for operator==
-  bool equalSlowCase(const APInt &RHS) const LLVM_READONLY;
+  LLVM_ABI bool equalSlowCase(const APInt &RHS) const LLVM_READONLY;
 
   /// out-of-line slow case for countLeadingZeros
-  unsigned countLeadingZerosSlowCase() const LLVM_READONLY;
+  LLVM_ABI unsigned countLeadingZerosSlowCase() const LLVM_READONLY;
 
   /// out-of-line slow case for countLeadingOnes.
-  unsigned countLeadingOnesSlowCase() const LLVM_READONLY;
+  LLVM_ABI unsigned countLeadingOnesSlowCase() const LLVM_READONLY;
 
   /// out-of-line slow case for countTrailingZeros.
-  unsigned countTrailingZerosSlowCase() const LLVM_READONLY;
+  LLVM_ABI unsigned countTrailingZerosSlowCase() const LLVM_READONLY;
 
   /// out-of-line slow case for countTrailingOnes
-  unsigned countTrailingOnesSlowCase() const LLVM_READONLY;
+  LLVM_ABI unsigned countTrailingOnesSlowCase() const LLVM_READONLY;
 
   /// out-of-line slow case for countPopulation
-  unsigned countPopulationSlowCase() const LLVM_READONLY;
+  LLVM_ABI unsigned countPopulationSlowCase() const LLVM_READONLY;
 
   /// out-of-line slow case for intersects.
-  bool intersectsSlowCase(const APInt &RHS) const LLVM_READONLY;
+  LLVM_ABI bool intersectsSlowCase(const APInt &RHS) const LLVM_READONLY;
 
   /// out-of-line slow case for isSubsetOf.
-  bool isSubsetOfSlowCase(const APInt &RHS) const LLVM_READONLY;
+  LLVM_ABI bool isSubsetOfSlowCase(const APInt &RHS) const LLVM_READONLY;
 
   /// out-of-line slow case for setBits.
-  void setBitsSlowCase(unsigned loBit, unsigned hiBit);
+  LLVM_ABI void setBitsSlowCase(unsigned loBit, unsigned hiBit);
 
   /// out-of-line slow case for clearBits.
-  void clearBitsSlowCase(unsigned LoBit, unsigned HiBit);
+  LLVM_ABI void clearBitsSlowCase(unsigned LoBit, unsigned HiBit);
 
   /// out-of-line slow case for flipAllBits.
-  void flipAllBitsSlowCase();
+  LLVM_ABI void flipAllBitsSlowCase();
 
   /// out-of-line slow case for concat.
-  APInt concatSlowCase(const APInt &NewLSB) const;
+  LLVM_ABI APInt concatSlowCase(const APInt &NewLSB) const;
 
   /// out-of-line slow case for operator&=.
-  void andAssignSlowCase(const APInt &RHS);
+  LLVM_ABI void andAssignSlowCase(const APInt &RHS);
 
   /// out-of-line slow case for operator|=.
-  void orAssignSlowCase(const APInt &RHS);
+  LLVM_ABI void orAssignSlowCase(const APInt &RHS);
 
   /// out-of-line slow case for operator^=.
-  void xorAssignSlowCase(const APInt &RHS);
+  LLVM_ABI void xorAssignSlowCase(const APInt &RHS);
 
   /// Unsigned comparison. Returns -1, 0, or 1 if this APInt is less than, equal
   /// to, or greater than RHS.
-  int compare(const APInt &RHS) const LLVM_READONLY;
+  LLVM_ABI int compare(const APInt &RHS) const LLVM_READONLY;
 
   /// Signed comparison. Returns -1, 0, or 1 if this APInt is less than, equal
   /// to, or greater than RHS.
-  int compareSigned(const APInt &RHS) const LLVM_READONLY;
+  LLVM_ABI int compareSigned(const APInt &RHS) const LLVM_READONLY;
 
   /// @}
 };
@@ -2267,28 +2275,28 @@ inline APInt abdu(const APInt &A, const APInt &B) {
 }
 
 /// Compute the floor of the signed average of C1 and C2
-APInt avgFloorS(const APInt &C1, const APInt &C2);
+LLVM_ABI APInt avgFloorS(const APInt &C1, const APInt &C2);
 
 /// Compute the floor of the unsigned average of C1 and C2
-APInt avgFloorU(const APInt &C1, const APInt &C2);
+LLVM_ABI APInt avgFloorU(const APInt &C1, const APInt &C2);
 
 /// Compute the ceil of the signed average of C1 and C2
-APInt avgCeilS(const APInt &C1, const APInt &C2);
+LLVM_ABI APInt avgCeilS(const APInt &C1, const APInt &C2);
 
 /// Compute the ceil of the unsigned average of C1 and C2
-APInt avgCeilU(const APInt &C1, const APInt &C2);
+LLVM_ABI APInt avgCeilU(const APInt &C1, const APInt &C2);
 
 /// Performs (2*N)-bit multiplication on sign-extended operands.
 /// Returns the high N bits of the multiplication result.
-APInt mulhs(const APInt &C1, const APInt &C2);
+LLVM_ABI APInt mulhs(const APInt &C1, const APInt &C2);
 
 /// Performs (2*N)-bit multiplication on zero-extended operands.
 /// Returns the high N bits of the multiplication result.
-APInt mulhu(const APInt &C1, const APInt &C2);
+LLVM_ABI APInt mulhu(const APInt &C1, const APInt &C2);
 
 /// Compute X^N for N>=0.
 /// 0^0 is supported and returns 1.
-APInt pow(const APInt &X, int64_t N);
+LLVM_ABI APInt pow(const APInt &X, int64_t N);
 
 /// Compute GCD of two unsigned APInt values.
 ///
@@ -2296,7 +2304,7 @@ APInt pow(const APInt &X, int64_t N);
 /// using Stein's algorithm.
 ///
 /// \returns the greatest common divisor of A and B.
-APInt GreatestCommonDivisor(APInt A, APInt B);
+LLVM_ABI APInt GreatestCommonDivisor(APInt A, APInt B);
 
 /// Converts the given APInt to a double value.
 ///
@@ -2327,7 +2335,7 @@ inline float RoundSignedAPIntToFloat(const APInt &APIVal) {
 /// Converts the given double value into a APInt.
 ///
 /// This function convert a double value to an APInt value.
-APInt RoundDoubleToAPInt(double Double, unsigned width);
+LLVM_ABI APInt RoundDoubleToAPInt(double Double, unsigned width);
 
 /// Converts a float value into a APInt.
 ///
@@ -2337,10 +2345,10 @@ inline APInt RoundFloatToAPInt(float Float, unsigned width) {
 }
 
 /// Return A unsign-divided by B, rounded by the given rounding mode.
-APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM);
+LLVM_ABI APInt RoundingUDiv(const APInt &A, const APInt &B, APInt::Rounding RM);
 
 /// Return A sign-divided by B, rounded by the given rounding mode.
-APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM);
+LLVM_ABI APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM);
 
 /// Let q(n) = An^2 + Bn + C, and BW = bit width of the value range
 /// (e.g. 32 for i32).
@@ -2375,13 +2383,13 @@ APInt RoundingSDiv(const APInt &A, const APInt &B, APInt::Rounding RM);
 ///
 /// The returned value may have a different bit width from the input
 /// coefficients.
-std::optional<APInt> SolveQuadraticEquationWrap(APInt A, APInt B, APInt C,
-                                                unsigned RangeWidth);
+LLVM_ABI std::optional<APInt>
+SolveQuadraticEquationWrap(APInt A, APInt B, APInt C, unsigned RangeWidth);
 
 /// Compare two values, and if they are different, return the position of the
 /// most significant bit that is different in the values.
-std::optional<unsigned> GetMostSignificantDifferentBit(const APInt &A,
-                                                       const APInt &B);
+LLVM_ABI std::optional<unsigned> GetMostSignificantDifferentBit(const APInt &A,
+                                                                const APInt &B);
 
 /// Splat/Merge neighboring bits to widen/narrow the bitmask represented
 /// by \param A to \param NewBitWidth bits.
@@ -2394,21 +2402,23 @@ std::optional<unsigned> GetMostSignificantDifferentBit(const APInt &A,
 /// e.g. ScaleBitMask(0b0101, 8) -> 0b00110011
 /// e.g. ScaleBitMask(0b00011011, 4) -> 0b0001
 /// A.getBitwidth() or NewBitWidth must be a whole multiples of the other.
-APInt ScaleBitMask(const APInt &A, unsigned NewBitWidth,
-                   bool MatchAllBits = false);
+LLVM_ABI APInt ScaleBitMask(const APInt &A, unsigned NewBitWidth,
+                            bool MatchAllBits = false);
 } // namespace APIntOps
 
 // See friend declaration above. This additional declaration is required in
 // order to compile LLVM with IBM xlC compiler.
-hash_code hash_value(const APInt &Arg);
+LLVM_ABI hash_code hash_value(const APInt &Arg);
 
 /// StoreIntToMemory - Fills the StoreBytes bytes of memory starting from Dst
 /// with the integer held in IntVal.
-void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst, unsigned StoreBytes);
+LLVM_ABI void StoreIntToMemory(const APInt &IntVal, uint8_t *Dst,
+                               unsigned StoreBytes);
 
 /// LoadIntFromMemory - Loads the integer stored in the LoadBytes bytes starting
 /// from Src into IntVal, which is assumed to be wide enough and to hold zero.
-void LoadIntFromMemory(APInt &IntVal, const uint8_t *Src, unsigned LoadBytes);
+LLVM_ABI void LoadIntFromMemory(APInt &IntVal, const uint8_t *Src,
+                                unsigned LoadBytes);
 
 /// Provide DenseMapInfo for APInt.
 template <> struct DenseMapInfo<APInt, void> {
@@ -2424,7 +2434,7 @@ template <> struct DenseMapInfo<APInt, void> {
     return V;
   }
 
-  static unsigned getHashValue(const APInt &Key);
+  LLVM_ABI static unsigned getHashValue(const APInt &Key);
 
   static bool isEqual(const APInt &LHS, const APInt &RHS) {
     return LHS.getBitWidth() == RHS.getBitWidth() && LHS == RHS;
diff --git a/llvm/include/llvm/ADT/APSInt.h b/llvm/include/llvm/ADT/APSInt.h
index 90b988875a24d..88a7a6e71c817 100644
--- a/llvm/include/llvm/ADT/APSInt.h
+++ b/llvm/include/llvm/ADT/APSInt.h
@@ -16,6 +16,7 @@
 #define LLVM_ADT_APSINT_H
 
 #include "llvm/ADT/APInt.h"
+#include "llvm/Support/Compiler.h"
 
 namespace llvm {
 
@@ -41,7 +42,7 @@ class [[nodiscard]] APSInt : public APInt {
   /// constructed APSInt is determined automatically.
   ///
   /// \param Str the string to be interpreted.
-  explicit APSInt(StringRef Str);
+  LLVM_ABI explicit APSInt(StringRef Str);
 
   /// Determine sign of this APSInt.
   ///
@@ -351,7 +352,7 @@ class [[nodiscard]] APSInt : public APInt {
 
   /// Used to insert APSInt objects, or objects that contain APSInt objects,
   /// into FoldingSets.
-  void Profile(FoldingSetNodeID &ID) const;
+  LLVM_ABI void Profile(FoldingSetNodeID &ID) const;
 };
 
 inline bool operator==(int64_t V1, const APSInt &V2) { return V2 == V1; }
diff --git a/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h b/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h
index c3872af2a0b4e..028b114385cd4 100644
--- a/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h
+++ b/llvm/include/llvm/ADT/DAGDeltaAlgorithm.h
@@ -8,6 +8,7 @@
 #ifndef LLVM_ADT_DAGDELTAALGORITHM_H
 #define LLVM_ADT_DAGDELTAALGORITHM_H
 
+#include "llvm/Support/Compiler.h"
 #include <set>
 #include <utility>
 #include <vector>
@@ -35,7 +36,7 @@ namespace llvm {
 /// substantially fewer tests with appropriate dependencies. \see DeltaAlgorithm
 /// for more information on the properties which the predicate function itself
 /// should satisfy.
-class DAGDeltaAlgorithm {
+class LLVM_ABI DAGDeltaAlgorithm {
   virtual void anchor();
 
 public:
diff --git a/llvm/include/llvm/ADT/DeltaAlgorithm.h b/llvm/include/llvm/ADT/DeltaAlgorithm.h
index e1743fd001968..dbb64579b39c8 100644
--- a/llvm/include/llvm/ADT/DeltaAlgorithm.h
+++ b/llvm/include/llvm/ADT/DeltaAlgorithm.h
@@ -8,6 +8,7 @@
 #ifndef LLVM_ADT_DELTAALGORITHM_H
 #define LLVM_ADT_DELTAALGORITHM_H
 
+#include "llvm/Support/Compiler.h"
 #include <set>
 #include <vector>
 
@@ -32,7 +33,7 @@ namespace llvm {
 /// requirements, and the algorithm will generally produce reasonable
 /// results. However, it may run substantially more tests than with a good
 /// predicate.
-class DeltaAlgorithm {
+class LLVM_ABI DeltaAlgorithm {
 public:
   using change_ty = unsigned;
   // FIXME: Use a decent data structure.
diff --git a/llvm/include/llvm/ADT/DeltaTree.h b/llvm/include/llvm/ADT/DeltaTree.h
index 5db9d74d9d529..2d7ee87930377 100644
--- a/llvm/include/llvm/ADT/DeltaTree.h
+++ b/llvm/include/llvm/ADT/DeltaTree.h
@@ -13,6 +13,8 @@
 #ifndef LLVM_ADT_DELTATREE_H
 #define LLVM_ADT_DELTATREE_H
 
+#include "llvm/Support/Compiler.h"
+
 namespace llvm {
 
 /// DeltaTree - a multiway search tree (BTree) structure with some fancy
@@ -26,23 +28,23 @@ class DeltaTree {
   void *Root; // "DeltaTreeNode *"
 
 public:
-  DeltaTree();
+  LLVM_ABI DeltaTree();
 
   // Note: Currently we only support copying when the RHS is empty.
-  DeltaTree(const DeltaTree &RHS);
+  LLVM_ABI DeltaTree(const DeltaTree &RHS);
 
   DeltaTree &operator=(const DeltaTree &) = delete;
-  ~DeltaTree();
+  LLVM_ABI ~DeltaTree();
 
   /// getDeltaAt - Return the accumulated delta at the specified file offset.
   /// This includes all insertions or delections that occurred *before* the
   /// specified file index.
-  int getDeltaAt(unsigned FileIndex) const;
+  LLVM_ABI int getDeltaAt(unsigned FileIndex) const;
 
   /// AddDelta - When a change is made that shifts around the text buffer,
   /// this method is used to record that info.  It inserts a delta of 'Delta'
   /// into the current DeltaTree at offset FileIndex.
-  void AddDelta(unsigned FileIndex, int Delta);
+  LLVM_ABI void AddDelta(unsigned FileIndex, int Delta);
 };
 
 } // namespace llvm
diff --git a/llvm/include/llvm/ADT/DynamicAPInt.h b/llvm/include/llvm/ADT/DynamicAPInt.h
index bb65a08a968d9..48c5c6eac9013 100644
--- a/llvm/include/llvm/ADT/DynamicAPInt.h
+++ b/llvm/include/llvm/ADT/DynamicAPInt.h
@@ -17,6 +17,7 @@
 #define LLVM_ADT_DYNAMICAPINT_H
 
 #include "llvm/ADT/SlowDynamicAPInt.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/MathExtras.h"
 #include <numeric>
 
@@ -213,9 +214,10 @@ class DynamicAPInt {
 
   friend hash_code hash_value(const DynamicAPInt &x); // NOLINT
 
-  void static_assert_layout(); // NOLINT
+  LLVM_ABI void static_assert_layout(); // NOLINT
+
+  LLVM_ABI raw_ostream &print(raw_ostream &OS) const;
 
-  raw_ostream &print(raw_ostream &OS) const;
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
   LLVM_DUMP_METHOD void dump() const;
 #endif
@@ -228,7 +230,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, const DynamicAPInt &X) {
 
 /// Redeclarations of friend declaration above to
 /// make it discoverable by lookups.
-hash_code hash_value(const DynamicAPInt &X); // NOLINT
+LLVM_ABI hash_code hash_value(const DynamicAPInt &X); // NOLINT
 
 /// This just calls through to the operator int64_t, but it's useful when a
 /// function pointer is required. (Although this is marked inline, it is still
diff --git a/llvm/include/llvm/ADT/FloatingPointMode.h b/llvm/include/llvm/ADT/FloatingPointMode.h
index 639d931ef88fe..0314b4cb1c38a 100644
--- a/llvm/include/llvm/ADT/FloatingPointMode.h
+++ b/llvm/include/llvm/ADT/FloatingPointMode.h
@@ -17,6 +17,7 @@
 
 #include "llvm/ADT/BitmaskEnum.h"
 #include "llvm/ADT/StringSwitch.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace llvm {
@@ -267,17 +268,17 @@ enum FPClassTest : unsigned {
 LLVM_DECLARE_ENUM_AS_BITMASK(FPClassTest, /* LargestValue */ fcPosInf);
 
 /// Return the test mask which returns true if the value's sign bit is flipped.
-FPClassTest fneg(FPClassTest Mask);
+LLVM_ABI FPClassTest fneg(FPClassTest Mask);
 
 /// Return the test mask which returns true after fabs is applied to the value.
-FPClassTest inverse_fabs(FPClassTest Mask);
+LLVM_ABI FPClassTest inverse_fabs(FPClassTest Mask);
 
 /// Return the test mask which returns true if the value could have the same set
 /// of classes, but with a different sign.
-FPClassTest unknown_sign(FPClassTest Mask);
+LLVM_ABI FPClassTest unknown_sign(FPClassTest Mask);
 
 /// Write a human readable form of \p Mask to \p OS
-raw_ostream &operator<<(raw_ostream &OS, FPClassTest Mask);
+LLVM_ABI raw_ostream &operator<<(raw_ostream &OS, FPClassTest Mask);
 
 } // namespace llvm
 
diff --git a/llvm/include/llvm/ADT/FoldingSet.h b/llvm/include/llvm/ADT/FoldingSet.h
index 3c2eaade57e47..82a88c440ff24 100644
--- a/llvm/include/llvm/ADT/FoldingSet.h
+++ b/llvm/include/llvm/ADT/FoldingSet.h
@@ -21,6 +21,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/iterator.h"
 #include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/xxhash.h"
 #include <cassert>
 #include <cstddef>
@@ -126,10 +127,10 @@ class FoldingSetBase {
   /// is greater than twice the number of buckets.
   unsigned NumNodes;
 
-  explicit FoldingSetBase(unsigned Log2InitSize = 6);
-  FoldingSetBase(FoldingSetBase &&Arg);
-  FoldingSetBase &operator=(FoldingSetBase &&RHS);
-  ~FoldingSetBase();
+  LLVM_ABI explicit FoldingSetBase(unsigned Log2InitSize = 6);
+  LLVM_ABI FoldingSetBase(FoldingSetBase &&Arg);
+  LLVM_ABI FoldingSetBase &operator=(FoldingSetBase &&RHS);
+  LLVM_ABI ~FoldingSetBase();
 
 public:
   //===--------------------------------------------------------------------===//
@@ -149,7 +150,7 @@ class FoldingSetBase {
   };
 
   /// clear - Remove all nodes from the folding set.
-  void clear();
+  LLVM_ABI void clear();
 
   /// size - Returns the number of nodes in the folding set.
   unsigned size() const { return NumNodes; }
@@ -203,27 +204,29 @@ class FoldingSetBase {
   /// reserve - Increase the number of buckets such that adding the
   /// EltCount-th node won't cause a rebucket operation. reserve is permitted
   /// to allocate more space than requested by EltCount.
-  void reserve(unsigned EltCount, const FoldingSetInfo &Info);
+  LLVM_ABI void reserve(unsigned EltCount, const FoldingSetInfo &Info);
 
   /// RemoveNode - Remove a node from the folding set, returning true if one
   /// was removed or false if the node was not in the folding set.
-  bool RemoveNode(Node *N);
+  LLVM_ABI bool RemoveNode(Node *N);
 
   /// GetOrInsertNode - If there is an existing simple Node exactly
   /// equal to the specified node, return it.  Otherwise, insert 'N' and return
   /// it instead.
-  Node *GetOrInsertNode(Node *N, const FoldingSetInfo &Info);
+  LLVM_ABI Node *GetOrInsertNode(Node *N, const FoldingSetInfo &Info);
 
   /// FindNodeOrInsertPos - Look up the node specified by ID.  If it exists,
   /// return it.  If not, return the insertion token that will make insertion
   /// faster.
-  Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos,
-                            const FoldingSetInfo &Info);
+  LLVM_ABI Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID,
+                                     void *&InsertPos,
+                                     const FoldingSetInfo &Info);
 
   /// InsertNode - Insert the specified node into the folding set, knowing that
   /// it is not already in the folding set.  InsertPos must be obtained from
   /// FindNodeOrInsertPos.
-  void InsertNode(Node *N, void *InsertPos, const FoldingSetInfo &Info);
+  LLVM_ABI void InsertNode(Node *N, void *InsertPos,
+                           const FoldingSetInfo &Info);
 };
 
 //===----------------------------------------------------------------------===//
@@ -308,13 +311,13 @@ class FoldingSetNodeIDRef {
         reinterpret_cast<const uint8_t *>(Data), sizeof(unsigned) * Size)));
   }
 
-  bool operator==(FoldingSetNodeIDRef) const;
+  LLVM_ABI bool operator==(FoldingSetNodeIDRef) const;
 
   bool operator!=(FoldingSetNodeIDRef RHS) const { return !(*this == RHS); }
 
   /// Used to compare the "ordering" of two nodes as defined by the
   /// profiled bits and their ordering defined by memcmp().
-  bool operator<(FoldingSetNodeIDRef) const;
+  LLVM_ABI bool operator<(FoldingSetNodeIDRef) const;
 
   const unsigned *getData() const { return Data; }
   size_t getSize() const { return Size; }
@@ -364,8 +367,8 @@ class FoldingSetNodeID {
   }
 
   void AddBoolean(bool B) { AddInteger(B ? 1U : 0U); }
-  void AddString(StringRef String);
-  void AddNodeID(const FoldingSetNodeID &ID);
+  LLVM_ABI void AddString(StringRef String);
+  LLVM_ABI void AddNodeID(const FoldingSetNodeID &ID);
 
   template <typename T>
   inline void Add(const T &x) { FoldingSetTrait<T>::Profile(x, *this); }
@@ -388,21 +391,21 @@ class FoldingSetNodeID {
   }
 
   /// operator== - Used to compare two nodes to each other.
-  bool operator==(const FoldingSetNodeID &RHS) const;
-  bool operator==(const FoldingSetNodeIDRef RHS) const;
+  LLVM_ABI bool operator==(const FoldingSetNodeID &RHS) const;
+  LLVM_ABI bool operator==(const FoldingSetNodeIDRef RHS) const;
 
   bool operator!=(const FoldingSetNodeID &RHS) const { return !(*this == RHS); }
   bool operator!=(const FoldingSetNodeIDRef RHS) const { return !(*this ==RHS);}
 
   /// Used to compare the "ordering" of two nodes as defined by the
   /// profiled bits and their ordering defined by memcmp().
-  bool operator<(const FoldingSetNodeID &RHS) const;
-  bool operator<(const FoldingSetNodeIDRef RHS) const;
+  LLVM_ABI bool operator<(const FoldingSetNodeID &RHS) const;
+  LLVM_ABI bool operator<(const FoldingSetNodeIDRef RHS) const;
 
   /// Intern - Copy this node's data to a memory region allocated from the
   /// given allocator and return a FoldingSetNodeIDRef describing the
   /// interned data.
-  FoldingSetNodeIDRef Intern(BumpPtrAllocator &Allocator) const;
+  LLVM_ABI FoldingSetNodeIDRef Intern(BumpPtrAllocator &Allocator) const;
 };
 
 // Convenience type to hide the implementation of the folding set.
@@ -709,9 +712,9 @@ class FoldingSetIteratorImpl {
 protected:
   FoldingSetNode *NodePtr;
 
-  FoldingSetIteratorImpl(void **Bucket);
+  LLVM_ABI FoldingSetIteratorImpl(void **Bucket);
 
-  void advance();
+  LLVM_ABI void advance();
 
 public:
   bool operator==(const FoldingSetIteratorImpl &RHS) const {
@@ -751,7 +754,7 @@ class FoldingSetBucketIteratorImpl {
 protected:
   void *Ptr;
 
-  explicit FoldingSetBucketIteratorImpl(void **Bucket);
+  LLVM_ABI explicit FoldingSetBucketIteratorImpl(void **Bucket);
 
   FoldingSetBucketIteratorImpl(void **Bucket, bool) : Ptr(Bucket) {}
 
diff --git a/llvm/include/llvm/ADT/IntEqClasses.h b/llvm/include/llvm/ADT/IntEqClasses.h
index 9ee8a46be411e..5bb3873e42c6e 100644
--- a/llvm/include/llvm/ADT/IntEqClasses.h
+++ b/llvm/include/llvm/ADT/IntEqClasses.h
@@ -22,6 +22,7 @@
 #define LLVM_ADT_INTEQCLASSES_H
 
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Compiler.h"
 
 namespace llvm {
 
@@ -44,7 +45,7 @@ class IntEqClasses {
   /// grow - Increase capacity to hold 0 .. N-1, putting new integers in unique
   /// equivalence classes.
   /// This requires an uncompressed map.
-  void grow(unsigned N);
+  LLVM_ABI void grow(unsigned N);
 
   /// clear - Clear all classes so that grow() will assign a unique class to
   /// every integer.
@@ -56,16 +57,16 @@ class IntEqClasses {
   /// Join the equivalence classes of a and b. After joining classes,
   /// findLeader(a) == findLeader(b). This requires an uncompressed map.
   /// Returns the new leader.
-  unsigned join(unsigned a, unsigned b);
+  LLVM_ABI unsigned join(unsigned a, unsigned b);
 
   /// findLeader - Compute the leader of a's equivalence class. This is the
   /// smallest member of the class.
   /// This requires an uncompressed map.
-  unsigned findLeader(unsigned a) const;
+  LLVM_ABI unsigned findLeader(unsigned a) const;
 
   /// compress - Compress equivalence classes by numbering them 0 .. M.
   /// This makes the equivalence class map immutable.
-  void compress();
+  LLVM_ABI void compress();
 
   /// getNumClasses - Return the number of equivalence classes after compress()
   /// was called.
@@ -80,7 +81,7 @@ class IntEqClasses {
 
   /// uncompress - Change back to the uncompressed representation that allows
   /// editing.
-  void uncompress();
+  LLVM_ABI void uncompress();
 };
 
 } // End llvm namespace
diff --git a/llvm/include/llvm/ADT/IntervalMap.h b/llvm/include/llvm/ADT/IntervalMap.h
index 6b21e6c6d75a8..3463194fb301a 100644
--- a/llvm/include/llvm/ADT/IntervalMap.h
+++ b/llvm/include/llvm/ADT/IntervalMap.h
@@ -107,6 +107,7 @@
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Allocator.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/RecyclingAllocator.h"
 #include <algorithm>
 #include <cassert>
@@ -411,9 +412,9 @@ void adjustSiblingSizes(NodeT *Node[], unsigned Nodes,
 /// @param Position Insert position.
 /// @param Grow     Reserve space for a new element at Position.
 /// @return         (node, offset) for Position.
-IdxPair distribute(unsigned Nodes, unsigned Elements, unsigned Capacity,
-                   const unsigned *CurSize, unsigned NewSize[],
-                   unsigned Position, bool Grow);
+LLVM_ABI IdxPair distribute(unsigned Nodes, unsigned Elements,
+                            unsigned Capacity, const unsigned *CurSize,
+                            unsigned NewSize[], unsigned Position, bool Grow);
 
 //===----------------------------------------------------------------------===//
 //---                   IntervalMapImpl::NodeSizer                         ---//
@@ -867,17 +868,17 @@ class Path {
   /// @param Root The new root node.
   /// @param Size Number of entries in the new root.
   /// @param Offsets Offsets into the root and first branch nodes.
-  void replaceRoot(void *Root, unsigned Size, IdxPair Offsets);
+  LLVM_ABI void replaceRoot(void *Root, unsigned Size, IdxPair Offsets);
 
   /// getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
   /// @param Level Get the sibling to node(Level).
   /// @return Left sibling, or NodeRef().
-  NodeRef getLeftSibling(unsigned Level) const;
+  LLVM_ABI NodeRef getLeftSibling(unsigned Level) const;
 
   /// moveLeft - Move path to the left sibling at Level. Leave nodes below Level
   /// unaltered.
   /// @param Level Move node(Level).
-  void moveLeft(unsigned Level);
+  LLVM_ABI void moveLeft(unsigned Level);
 
   /// fillLeft - Grow path to Height by taking leftmost branches.
   /// @param Height The target height.
@@ -889,12 +890,12 @@ class Path {
   /// getLeftSibling - Get the left sibling node at Level, or a null NodeRef.
   /// @param Level Get the sibling to node(Level).
   /// @return Left sibling, or NodeRef().
-  NodeRef getRightSibling(unsigned Level) const;
+  LLVM_ABI NodeRef getRightSibling(unsigned Level) const;
 
   /// moveRight - Move path to the left sibling at Level. Leave nodes below
   /// Level unaltered.
   /// @param Level Move node(Level).
-  void moveRight(unsigned Level);
+  LLVM_ABI void moveRight(unsigned Level);
 
   /// atBegin - Return true if path is at begin().
   bool atBegin() const {
diff --git a/llvm/include/llvm/ADT/RewriteBuffer.h b/llvm/include/llvm/ADT/RewriteBuffer.h
index 8197a06f882c1..b39271849aa2b 100644
--- a/llvm/include/llvm/ADT/RewriteBuffer.h
+++ b/llvm/include/llvm/ADT/RewriteBuffer.h
@@ -12,6 +12,7 @@
 #include "llvm/ADT/DeltaTree.h"
 #include "llvm/ADT/RewriteRope.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
 
 namespace clang {
 class Rewriter;
@@ -57,16 +58,17 @@ class RewriteBuffer {
   /// Rewriter::overwriteChangedFiles() instead.
   ///
   /// The original buffer is not actually changed.
-  raw_ostream &write(raw_ostream &Stream) const;
+  LLVM_ABI raw_ostream &write(raw_ostream &Stream) const;
 
   /// RemoveText - Remove the specified text.
-  void RemoveText(unsigned OrigOffset, unsigned Size,
-                  bool removeLineIfEmpty = false);
+  LLVM_ABI void RemoveText(unsigned OrigOffset, unsigned Size,
+                           bool removeLineIfEmpty = false);
 
   /// InsertText - Insert some text at the specified point, where the offset in
   /// the buffer is specified relative to the original SourceBuffer.  The
   /// text is inserted after the specified location.
-  void InsertText(unsigned OrigOffset, StringRef Str, bool InsertAfter = true);
+  LLVM_ABI void InsertText(unsigned OrigOffset, StringRef Str,
+                           bool InsertAfter = true);
 
   /// InsertTextBefore - Insert some text before the specified point, where the
   /// offset in the buffer is specified relative to the original
@@ -86,7 +88,8 @@ class RewriteBuffer {
   /// ReplaceText - This method replaces a range of characters in the input
   /// buffer with a new string.  This is effectively a combined "remove/insert"
   /// operation.
-  void ReplaceText(unsigned OrigOffset, unsigned OrigLength, StringRef NewStr);
+  LLVM_ABI void ReplaceText(unsigned OrigOffset, unsigned OrigLength,
+                            StringRef NewStr);
 
 private:
   /// getMappedOffset - Given an offset into the original SourceBuffer that this
diff --git a/llvm/include/llvm/ADT/RewriteRope.h b/llvm/include/llvm/ADT/RewriteRope.h
index 784f3c07eaa62..1f0e797411cd5 100644
--- a/llvm/include/llvm/ADT/RewriteRope.h
+++ b/llvm/include/llvm/ADT/RewriteRope.h
@@ -15,6 +15,7 @@
 
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
 #include <cassert>
 #include <cstddef>
 #include <iterator>
@@ -102,7 +103,7 @@ class RopePieceBTreeIterator {
   using reference = value_type &;
 
   RopePieceBTreeIterator() = default;
-  RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
+  LLVM_ABI RopePieceBTreeIterator(const void /*RopePieceBTreeNode*/ *N);
 
   char operator*() const { return (*CurPiece)[CurChar]; }
 
@@ -131,7 +132,7 @@ class RopePieceBTreeIterator {
     return llvm::StringRef(&(*CurPiece)[0], CurPiece->size());
   }
 
-  void MoveToNextPiece();
+  LLVM_ABI void MoveToNextPiece();
 };
 
 //===--------------------------------------------------------------------===//
@@ -142,23 +143,23 @@ class RopePieceBTree {
   void /*RopePieceBTreeNode*/ *Root;
 
 public:
-  RopePieceBTree();
-  RopePieceBTree(const RopePieceBTree &RHS);
+  LLVM_ABI RopePieceBTree();
+  LLVM_ABI RopePieceBTree(const RopePieceBTree &RHS);
   RopePieceBTree &operator=(const RopePieceBTree &) = delete;
-  ~RopePieceBTree();
+  LLVM_ABI ~RopePieceBTree();
 
   using iterator = RopePieceBTreeIterator;
 
   iterator begin() const { return iterator(Root); }
   iterator end() const { return iterator(); }
-  unsigned size() const;
+  LLVM_ABI unsigned size() const;
   unsigned empty() const { return size() == 0; }
 
-  void clear();
+  LLVM_ABI void clear();
 
-  void insert(unsigned Offset, const RopePiece &R);
+  LLVM_ABI void insert(unsigned Offset, const RopePiece &R);
 
-  void erase(unsigned Offset, unsigned NumBytes);
+  LLVM_ABI void erase(unsigned Offset, unsigned NumBytes);
 };
 
 //===--------------------------------------------------------------------===//
@@ -215,7 +216,7 @@ class RewriteRope {
   }
 
 private:
-  RopePiece MakeRopeString(const char *Start, const char *End);
+  LLVM_ABI RopePiece MakeRopeString(const char *Start, const char *End);
 };
 
 } // namespace llvm
diff --git a/llvm/include/llvm/ADT/SlowDynamicAPInt.h b/llvm/include/llvm/ADT/SlowDynamicAPInt.h
index c9aef96b9e1c3..702e0398e40fc 100644
--- a/llvm/include/llvm/ADT/SlowDynamicAPInt.h
+++ b/llvm/include/llvm/ADT/SlowDynamicAPInt.h
@@ -19,6 +19,7 @@
 #define LLVM_ADT_SLOWDYNAMICAPINT_H
 
 #include "llvm/ADT/APInt.h"
+#include "llvm/Support/Compiler.h"
 
 namespace llvm {
 class DynamicAPInt;
@@ -35,50 +36,51 @@ class SlowDynamicAPInt {
   APInt Val;
 
 public:
-  explicit SlowDynamicAPInt(int64_t Val);
-  SlowDynamicAPInt();
-  explicit SlowDynamicAPInt(const APInt &Val);
-  SlowDynamicAPInt &operator=(int64_t Val);
-  explicit operator int64_t() const;
-  SlowDynamicAPInt operator-() const;
-  bool operator==(const SlowDynamicAPInt &O) const;
-  bool operator!=(const SlowDynamicAPInt &O) const;
-  bool operator>(const SlowDynamicAPInt &O) const;
-  bool operator<(const SlowDynamicAPInt &O) const;
-  bool operator<=(const SlowDynamicAPInt &O) const;
-  bool operator>=(const SlowDynamicAPInt &O) const;
-  SlowDynamicAPInt operator+(const SlowDynamicAPInt &O) const;
-  SlowDynamicAPInt operator-(const SlowDynamicAPInt &O) const;
-  SlowDynamicAPInt operator*(const SlowDynamicAPInt &O) const;
-  SlowDynamicAPInt operator/(const SlowDynamicAPInt &O) const;
-  SlowDynamicAPInt operator%(const SlowDynamicAPInt &O) const;
-  SlowDynamicAPInt &operator+=(const SlowDynamicAPInt &O);
-  SlowDynamicAPInt &operator-=(const SlowDynamicAPInt &O);
-  SlowDynamicAPInt &operator*=(const SlowDynamicAPInt &O);
-  SlowDynamicAPInt &operator/=(const SlowDynamicAPInt &O);
-  SlowDynamicAPInt &operator%=(const SlowDynamicAPInt &O);
-
-  SlowDynamicAPInt &operator++();
-  SlowDynamicAPInt &operator--();
-
-  friend SlowDynamicAPInt abs(const SlowDynamicAPInt &X);
-  friend SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS,
-                                  const SlowDynamicAPInt &RHS);
-  friend SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS,
-                                   const SlowDynamicAPInt &RHS);
+  LLVM_ABI explicit SlowDynamicAPInt(int64_t Val);
+  LLVM_ABI SlowDynamicAPInt();
+  LLVM_ABI explicit SlowDynamicAPInt(const APInt &Val);
+  LLVM_ABI SlowDynamicAPInt &operator=(int64_t Val);
+  LLVM_ABI explicit operator int64_t() const;
+  LLVM_ABI SlowDynamicAPInt operator-() const;
+  LLVM_ABI bool operator==(const SlowDynamicAPInt &O) const;
+  LLVM_ABI bool operator!=(const SlowDynamicAPInt &O) const;
+  LLVM_ABI bool operator>(const SlowDynamicAPInt &O) const;
+  LLVM_ABI bool operator<(const SlowDynamicAPInt &O) const;
+  LLVM_ABI bool operator<=(const SlowDynamicAPInt &O) const;
+  LLVM_ABI bool operator>=(const SlowDynamicAPInt &O) const;
+  LLVM_ABI SlowDynamicAPInt operator+(const SlowDynamicAPInt &O) const;
+  LLVM_ABI SlowDynamicAPInt operator-(const SlowDynamicAPInt &O) const;
+  LLVM_ABI SlowDynamicAPInt operator*(const SlowDynamicAPInt &O) const;
+  LLVM_ABI SlowDynamicAPInt operator/(const SlowDynamicAPInt &O) const;
+  LLVM_ABI SlowDynamicAPInt operator%(const SlowDynamicAPInt &O) const;
+  LLVM_ABI SlowDynamicAPInt &operator+=(const SlowDynamicAPInt &O);
+  LLVM_ABI SlowDynamicAPInt &operator-=(const SlowDynamicAPInt &O);
+  LLVM_ABI SlowDynamicAPInt &operator*=(const SlowDynamicAPInt &O);
+  LLVM_ABI SlowDynamicAPInt &operator/=(const SlowDynamicAPInt &O);
+  LLVM_ABI SlowDynamicAPInt &operator%=(const SlowDynamicAPInt &O);
+
+  LLVM_ABI SlowDynamicAPInt &operator++();
+  LLVM_ABI SlowDynamicAPInt &operator--();
+
+  LLVM_ABI_FRIEND friend SlowDynamicAPInt abs(const SlowDynamicAPInt &X);
+  LLVM_ABI_FRIEND friend SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS,
+                                                  const SlowDynamicAPInt &RHS);
+  LLVM_ABI_FRIEND friend SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS,
+                                                   const SlowDynamicAPInt &RHS);
   /// The operands must be non-negative for gcd.
-  friend SlowDynamicAPInt gcd(const SlowDynamicAPInt &A,
-                              const SlowDynamicAPInt &B);
+  LLVM_ABI_FRIEND friend SlowDynamicAPInt gcd(const SlowDynamicAPInt &A,
+                                              const SlowDynamicAPInt &B);
 
   /// Overload to compute a hash_code for a SlowDynamicAPInt value.
-  friend hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT
+  LLVM_ABI_FRIEND friend hash_code
+  hash_value(const SlowDynamicAPInt &X); // NOLINT
 
   // Make DynamicAPInt a friend so it can access Val directly.
   friend DynamicAPInt;
 
   unsigned getBitWidth() const { return Val.getBitWidth(); }
 
-  void print(raw_ostream &OS) const;
+  LLVM_ABI void print(raw_ostream &OS) const;
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
   LLVM_DUMP_METHOD void dump() const;
@@ -94,53 +96,56 @@ inline raw_ostream &operator<<(raw_ostream &OS, const SlowDynamicAPInt &X) {
 ///
 /// The RHS is always expected to be positive, and the result
 /// is always non-negative.
-SlowDynamicAPInt mod(const SlowDynamicAPInt &LHS, const SlowDynamicAPInt &RHS);
+LLVM_ABI SlowDynamicAPInt mod(const SlowDynamicAPInt &LHS,
+                              const SlowDynamicAPInt &RHS);
 
 /// Returns the least common multiple of A and B.
-SlowDynamicAPInt lcm(const SlowDynamicAPInt &A, const SlowDynamicAPInt &B);
+LLVM_ABI SlowDynamicAPInt lcm(const SlowDynamicAPInt &A,
+                              const SlowDynamicAPInt &B);
 
 /// Redeclarations of friend declarations above to
 /// make it discoverable by lookups.
-SlowDynamicAPInt abs(const SlowDynamicAPInt &X);
-SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS,
-                         const SlowDynamicAPInt &RHS);
-SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS,
-                          const SlowDynamicAPInt &RHS);
-SlowDynamicAPInt gcd(const SlowDynamicAPInt &A, const SlowDynamicAPInt &B);
-hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT
+LLVM_ABI SlowDynamicAPInt abs(const SlowDynamicAPInt &X);
+LLVM_ABI SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS,
+                                  const SlowDynamicAPInt &RHS);
+LLVM_ABI SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS,
+                                   const SlowDynamicAPInt &RHS);
+LLVM_ABI SlowDynamicAPInt gcd(const SlowDynamicAPInt &A,
+                              const SlowDynamicAPInt &B);
+LLVM_ABI hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT
 
 /// ---------------------------------------------------------------------------
 /// Convenience operator overloads for int64_t.
 /// ---------------------------------------------------------------------------
-SlowDynamicAPInt &operator+=(SlowDynamicAPInt &A, int64_t B);
-SlowDynamicAPInt &operator-=(SlowDynamicAPInt &A, int64_t B);
-SlowDynamicAPInt &operator*=(SlowDynamicAPInt &A, int64_t B);
-SlowDynamicAPInt &operator/=(SlowDynamicAPInt &A, int64_t B);
-SlowDynamicAPInt &operator%=(SlowDynamicAPInt &A, int64_t B);
-
-bool operator==(const SlowDynamicAPInt &A, int64_t B);
-bool operator!=(const SlowDynamicAPInt &A, int64_t B);
-bool operator>(const SlowDynamicAPInt &A, int64_t B);
-bool operator<(const SlowDynamicAPInt &A, int64_t B);
-bool operator<=(const SlowDynamicAPInt &A, int64_t B);
-bool operator>=(const SlowDynamicAPInt &A, int64_t B);
-SlowDynamicAPInt operator+(const SlowDynamicAPInt &A, int64_t B);
-SlowDynamicAPInt operator-(const SlowDynamicAPInt &A, int64_t B);
-SlowDynamicAPInt operator*(const SlowDynamicAPInt &A, int64_t B);
-SlowDynamicAPInt operator/(const SlowDynamicAPInt &A, int64_t B);
-SlowDynamicAPInt operator%(const SlowDynamicAPInt &A, int64_t B);
-
-bool operator==(int64_t A, const SlowDynamicAPInt &B);
-bool operator!=(int64_t A, const SlowDynamicAPInt &B);
-bool operator>(int64_t A, const SlowDynamicAPInt &B);
-bool operator<(int64_t A, const SlowDynamicAPInt &B);
-bool operator<=(int64_t A, const SlowDynamicAPInt &B);
-bool operator>=(int64_t A, const SlowDynamicAPInt &B);
-SlowDynamicAPInt operator+(int64_t A, const SlowDynamicAPInt &B);
-SlowDynamicAPInt operator-(int64_t A, const SlowDynamicAPInt &B);
-SlowDynamicAPInt operator*(int64_t A, const SlowDynamicAPInt &B);
-SlowDynamicAPInt operator/(int64_t A, const SlowDynamicAPInt &B);
-SlowDynamicAPInt operator%(int64_t A, const SlowDynamicAPInt &B);
+LLVM_ABI SlowDynamicAPInt &operator+=(SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI SlowDynamicAPInt &operator-=(SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI SlowDynamicAPInt &operator*=(SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI SlowDynamicAPInt &operator/=(SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI SlowDynamicAPInt &operator%=(SlowDynamicAPInt &A, int64_t B);
+
+LLVM_ABI bool operator==(const SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI bool operator!=(const SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI bool operator>(const SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI bool operator<(const SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI bool operator<=(const SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI bool operator>=(const SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI SlowDynamicAPInt operator+(const SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI SlowDynamicAPInt operator-(const SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI SlowDynamicAPInt operator*(const SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI SlowDynamicAPInt operator/(const SlowDynamicAPInt &A, int64_t B);
+LLVM_ABI SlowDynamicAPInt operator%(const SlowDynamicAPInt &A, int64_t B);
+
+LLVM_ABI bool operator==(int64_t A, const SlowDynamicAPInt &B);
+LLVM_ABI bool operator!=(int64_t A, const SlowDynamicAPInt &B);
+LLVM_ABI bool operator>(int64_t A, const SlowDynamicAPInt &B);
+LLVM_ABI bool operator<(int64_t A, const SlowDynamicAPInt &B);
+LLVM_ABI bool operator<=(int64_t A, const SlowDynamicAPInt &B);
+LLVM_ABI bool operator>=(int64_t A, const SlowDynamicAPInt &B);
+LLVM_ABI SlowDynamicAPInt operator+(int64_t A, const SlowDynamicAPInt &B);
+LLVM_ABI SlowDynamicAPInt operator-(int64_t A, const SlowDynamicAPInt &B);
+LLVM_ABI SlowDynamicAPInt operator*(int64_t A, const SlowDynamicAPInt &B);
+LLVM_ABI SlowDynamicAPInt operator/(int64_t A, const SlowDynamicAPInt &B);
+LLVM_ABI SlowDynamicAPInt operator%(int64_t A, const SlowDynamicAPInt &B);
 } // namespace llvm::detail
 
 #endif // LLVM_ADT_SLOWDYNAMICAPINT_H
diff --git a/llvm/include/llvm/ADT/SmallPtrSet.h b/llvm/include/llvm/ADT/SmallPtrSet.h
index e47d5c0c7cdc0..2ce934321c456 100644
--- a/llvm/include/llvm/ADT/SmallPtrSet.h
+++ b/llvm/include/llvm/ADT/SmallPtrSet.h
@@ -18,6 +18,7 @@
 #include "llvm/ADT/ADL.h"
 #include "llvm/ADT/EpochTracker.h"
 #include "llvm/ADT/STLForwardCompat.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/MathExtras.h"
 #include "llvm/Support/ReverseIteration.h"
 #include "llvm/Support/type_traits.h"
@@ -70,10 +71,11 @@ class SmallPtrSetImplBase : public DebugEpochBase {
   bool IsSmall;
 
   // Helpers to copy and move construct a SmallPtrSet.
-  SmallPtrSetImplBase(const void **SmallStorage,
-                      const SmallPtrSetImplBase &that);
-  SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize,
-                      const void **RHSSmallStorage, SmallPtrSetImplBase &&that);
+  LLVM_ABI SmallPtrSetImplBase(const void **SmallStorage,
+                               const SmallPtrSetImplBase &that);
+  LLVM_ABI SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize,
+                               const void **RHSSmallStorage,
+                               SmallPtrSetImplBase &&that);
 
   explicit SmallPtrSetImplBase(const void **SmallStorage, unsigned SmallSize)
       : CurArray(SmallStorage), CurArraySize(SmallSize), NumNonEmpty(0),
@@ -235,24 +237,26 @@ class SmallPtrSetImplBase : public DebugEpochBase {
   bool isSmall() const { return IsSmall; }
 
 private:
-  std::pair<const void *const *, bool> insert_imp_big(const void *Ptr);
+  LLVM_ABI std::pair<const void *const *, bool> insert_imp_big(const void *Ptr);
 
-  const void *const *doFind(const void *Ptr) const;
+  LLVM_ABI const void *const *doFind(const void *Ptr) const;
   const void * const *FindBucketFor(const void *Ptr) const;
-  void shrink_and_clear();
+  LLVM_ABI void shrink_and_clear();
 
   /// Grow - Allocate a larger backing store for the buckets and move it over.
-  void Grow(unsigned NewSize);
+  LLVM_ABI void Grow(unsigned NewSize);
 
 protected:
   /// swap - Swaps the elements of two sets.
   /// Note: This method assumes that both sets have the same small size.
-  void swap(const void **SmallStorage, const void **RHSSmallStorage,
-            SmallPtrSetImplBase &RHS);
-
-  void copyFrom(const void **SmallStorage, const SmallPtrSetImplBase &RHS);
-  void moveFrom(const void **SmallStorage, unsigned SmallSize,
-                const void **RHSSmallStorage, SmallPtrSetImplBase &&RHS);
+  LLVM_ABI void swap(const void **SmallStorage, const void **RHSSmallStorage,
+                     SmallPtrSetImplBase &RHS);
+
+  LLVM_ABI void copyFrom(const void **SmallStorage,
+                         const SmallPtrSetImplBase &RHS);
+  LLVM_ABI void moveFrom(const void **SmallStorage, unsigned SmallSize,
+                         const void **RHSSmallStorage,
+                         SmallPtrSetImplBase &&RHS);
 
 private:
   /// Code shared by moveFrom() and move constructor.
diff --git a/llvm/include/llvm/ADT/SmallVector.h b/llvm/include/llvm/ADT/SmallVector.h
index fb9ec9abf111b..0b8bb48b8fe5e 100644
--- a/llvm/include/llvm/ADT/SmallVector.h
+++ b/llvm/include/llvm/ADT/SmallVector.h
@@ -67,13 +67,13 @@ template <class Size_T> class SmallVectorBase {
   /// This is a helper for \a grow() that's out of line to reduce code
   /// duplication.  This function will report a fatal error if it can't grow at
   /// least to \p MinSize.
-  void *mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize,
-                      size_t &NewCapacity);
+  LLVM_ABI void *mallocForGrow(void *FirstEl, size_t MinSize, size_t TSize,
+                               size_t &NewCapacity);
 
   /// This is an implementation of the grow() method which only works
   /// on POD-like data types and is out of line to reduce code duplication.
   /// This function will report a fatal error if it cannot increase capacity.
-  void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
+  LLVM_ABI void grow_pod(void *FirstEl, size_t MinSize, size_t TSize);
 
 public:
   size_t size() const { return Size; }
diff --git a/llvm/include/llvm/ADT/Statistic.h b/llvm/include/llvm/ADT/Statistic.h
index aa7197cc6caef..082e6d50577fa 100644
--- a/llvm/include/llvm/ADT/Statistic.h
+++ b/llvm/include/llvm/ADT/Statistic.h
@@ -27,6 +27,7 @@
 #define LLVM_ADT_STATISTIC_H
 
 #include "llvm/Config/llvm-config.h"
+#include "llvm/Support/Compiler.h"
 #include <atomic>
 #include <memory>
 #include <vector>
@@ -125,7 +126,7 @@ class TrackingStatistic {
     return *this;
   }
 
-  void RegisterStatistic();
+  LLVM_ABI void RegisterStatistic();
 };
 
 class NoopStatistic {
@@ -172,25 +173,25 @@ using Statistic = NoopStatistic;
   static llvm::TrackingStatistic VARNAME = {DEBUG_TYPE, #VARNAME, DESC}
 
 /// Enable the collection and printing of statistics.
-void EnableStatistics(bool DoPrintOnExit = true);
+LLVM_ABI void EnableStatistics(bool DoPrintOnExit = true);
 
 /// Check if statistics are enabled.
-bool AreStatisticsEnabled();
+LLVM_ABI bool AreStatisticsEnabled();
 
 /// Return a stream to print our output on.
-std::unique_ptr<raw_ostream> CreateInfoOutputFile();
+LLVM_ABI std::unique_ptr<raw_ostream> CreateInfoOutputFile();
 
 /// Print statistics to the file returned by CreateInfoOutputFile().
-void PrintStatistics();
+LLVM_ABI void PrintStatistics();
 
 /// Print statistics to the given output stream.
-void PrintStatistics(raw_ostream &OS);
+LLVM_ABI void PrintStatistics(raw_ostream &OS);
 
 /// Print statistics in JSON format. This does include all global timers (\see
 /// Timer, TimerGroup). Note that the timers are cleared after printing and will
 /// not be printed in human readable form or in a second call of
 /// PrintStatisticsJSON().
-void PrintStatisticsJSON(raw_ostream &OS);
+LLVM_ABI void PrintStatisticsJSON(raw_ostream &OS);
 
 /// Get the statistics. This can be used to look up the value of
 /// statistics without needing to parse JSON.
@@ -199,7 +200,7 @@ void PrintStatisticsJSON(raw_ostream &OS);
 /// during it's execution. It will return the value at the point that it is
 /// read. However, it will prevent new statistics from registering until it
 /// completes.
-std::vector<std::pair<StringRef, uint64_t>> GetStatistics();
+LLVM_ABI std::vector<std::pair<StringRef, uint64_t>> GetStatistics();
 
 /// Reset the statistics. This can be used to zero and de-register the
 /// statistics in order to measure a compilation.
@@ -214,7 +215,7 @@ std::vector<std::pair<StringRef, uint64_t>> GetStatistics();
 /// compilation should ensure that no compilations are in progress at the point
 /// this function is called and that only one compilation executes until calling
 /// GetStatistics().
-void ResetStatistics();
+LLVM_ABI void ResetStatistics();
 
 } // end namespace llvm
 
diff --git a/llvm/include/llvm/ADT/StringExtras.h b/llvm/include/llvm/ADT/StringExtras.h
index 1317d521d4c19..a2cc36dd8caad 100644
--- a/llvm/include/llvm/ADT/StringExtras.h
+++ b/llvm/include/llvm/ADT/StringExtras.h
@@ -19,6 +19,7 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
+#include "llvm/Support/Compiler.h"
 #include <cassert>
 #include <cstddef>
 #include <cstdint>
@@ -355,7 +356,7 @@ inline std::string toString(const APSInt &I, unsigned Radix) {
 /// StrInStrNoCase - Portable version of strcasestr.  Locates the first
 /// occurrence of string 's1' in string 's2', ignoring case.  Returns
 /// the offset of s2 in s1 or npos if s2 cannot be found.
-StringRef::size_type StrInStrNoCase(StringRef s1, StringRef s2);
+LLVM_ABI StringRef::size_type StrInStrNoCase(StringRef s1, StringRef s2);
 
 /// getToken - This function extracts one token from source, ignoring any
 /// leading characters that appear in the Delimiters string, and ending the
@@ -363,14 +364,14 @@ StringRef::size_type StrInStrNoCase(StringRef s1, StringRef s2);
 /// there are no tokens in the source string, an empty string is returned.
 /// The function returns a pair containing the extracted token and the
 /// remaining tail string.
-std::pair<StringRef, StringRef> getToken(StringRef Source,
-                                         StringRef Delimiters = " \t\n\v\f\r");
+LLVM_ABI std::pair<StringRef, StringRef>
+getToken(StringRef Source, StringRef Delimiters = " \t\n\v\f\r");
 
 /// SplitString - Split up the specified string according to the specified
 /// delimiters, appending the result fragments to the output list.
-void SplitString(StringRef Source,
-                 SmallVectorImpl<StringRef> &OutFragments,
-                 StringRef Delimiters = " \t\n\v\f\r");
+LLVM_ABI void SplitString(StringRef Source,
+                          SmallVectorImpl<StringRef> &OutFragments,
+                          StringRef Delimiters = " \t\n\v\f\r");
 
 /// Returns the English suffix for an ordinal integer (-st, -nd, -rd, -th).
 inline StringRef getOrdinalSuffix(unsigned Val) {
@@ -393,26 +394,26 @@ inline StringRef getOrdinalSuffix(unsigned Val) {
 
 /// Print each character of the specified string, escaping it if it is not
 /// printable or if it is an escape char.
-void printEscapedString(StringRef Name, raw_ostream &Out);
+LLVM_ABI void printEscapedString(StringRef Name, raw_ostream &Out);
 
 /// Print each character of the specified string, escaping HTML special
 /// characters.
-void printHTMLEscaped(StringRef String, raw_ostream &Out);
+LLVM_ABI void printHTMLEscaped(StringRef String, raw_ostream &Out);
 
 /// printLowerCase - Print each character as lowercase if it is uppercase.
-void printLowerCase(StringRef String, raw_ostream &Out);
+LLVM_ABI void printLowerCase(StringRef String, raw_ostream &Out);
 
 /// Converts a string from camel-case to snake-case by replacing all uppercase
 /// letters with '_' followed by the letter in lowercase, except if the
 /// uppercase letter is the first character of the string.
-std::string convertToSnakeFromCamelCase(StringRef input);
+LLVM_ABI std::string convertToSnakeFromCamelCase(StringRef input);
 
 /// Converts a string from snake-case to camel-case by replacing all occurrences
 /// of '_' followed by a lowercase letter with the letter in uppercase.
 /// Optionally allow capitalization of the first letter (if it is a lowercase
 /// letter)
-std::string convertToCamelFromSnakeCase(StringRef input,
-                                        bool capitalizeFirst = false);
+LLVM_ABI std::string convertToCamelFromSnakeCase(StringRef input,
+                                                 bool capitalizeFirst = false);
 
 namespace detail {
 
diff --git a/llvm/include/llvm/ADT/StringMap.h b/llvm/include/llvm/ADT/StringMap.h
index 9b58af7327391..f839edf031006 100644
--- a/llvm/include/llvm/ADT/StringMap.h
+++ b/llvm/include/llvm/ADT/StringMap.h
@@ -17,6 +17,7 @@
 #include "llvm/ADT/StringMapEntry.h"
 #include "llvm/ADT/iterator.h"
 #include "llvm/Support/AllocatorBase.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/PointerLikeTypeTraits.h"
 #include <initializer_list>
 #include <iterator>
@@ -52,9 +53,9 @@ class StringMapImpl {
     RHS.NumTombstones = 0;
   }
 
-  StringMapImpl(unsigned InitSize, unsigned ItemSize);
+  LLVM_ABI StringMapImpl(unsigned InitSize, unsigned ItemSize);
   ~StringMapImpl() { free(TheTable); }
-  unsigned RehashTable(unsigned BucketNo = 0);
+  LLVM_ABI unsigned RehashTable(unsigned BucketNo = 0);
 
   /// LookupBucketFor - Look up the bucket that the specified string should end
   /// up in.  If it already exists as a key in the map, the Item pointer for the
@@ -66,7 +67,7 @@ class StringMapImpl {
   }
 
   /// Overload that explicitly takes precomputed hash(Key).
-  unsigned LookupBucketFor(StringRef Key, uint32_t FullHashValue);
+  LLVM_ABI unsigned LookupBucketFor(StringRef Key, uint32_t FullHashValue);
 
   /// FindKey - Look up the bucket that contains the specified key. If it exists
   /// in the map, return the bucket number of the key.  Otherwise return -1.
@@ -74,19 +75,19 @@ class StringMapImpl {
   int FindKey(StringRef Key) const { return FindKey(Key, hash(Key)); }
 
   /// Overload that explicitly takes precomputed hash(Key).
-  int FindKey(StringRef Key, uint32_t FullHashValue) const;
+  LLVM_ABI int FindKey(StringRef Key, uint32_t FullHashValue) const;
 
   /// RemoveKey - Remove the specified StringMapEntry from the table, but do not
   /// delete it.  This aborts if the value isn't in the table.
-  void RemoveKey(StringMapEntryBase *V);
+  LLVM_ABI void RemoveKey(StringMapEntryBase *V);
 
   /// RemoveKey - Remove the StringMapEntry for the specified key from the
   /// table, returning it.  If the key is not in the table, this returns null.
-  StringMapEntryBase *RemoveKey(StringRef Key);
+  LLVM_ABI StringMapEntryBase *RemoveKey(StringRef Key);
 
   /// Allocate the table with the specified number of buckets and otherwise
   /// setup the map as empty.
-  void init(unsigned Size);
+  LLVM_ABI void init(unsigned Size);
 
 public:
   static constexpr uintptr_t TombstoneIntVal =
@@ -108,7 +109,7 @@ class StringMapImpl {
   /// to some of the functions.
   /// The implementation of this function is not guaranteed to be stable
   /// and may change.
-  static uint32_t hash(StringRef Key);
+  LLVM_ABI static uint32_t hash(StringRef Key);
 
   void swap(StringMapImpl &Other) {
     std::swap(TheTable, Other.TheTable);
diff --git a/llvm/include/llvm/ADT/StringRef.h b/llvm/include/llvm/ADT/StringRef.h
index 5b525c8e56ecc..0ced1c0379a3b 100644
--- a/llvm/include/llvm/ADT/StringRef.h
+++ b/llvm/include/llvm/ADT/StringRef.h
@@ -32,14 +32,16 @@ namespace llvm {
   class StringRef;
 
   /// Helper functions for StringRef::getAsInteger.
-  bool getAsUnsignedInteger(StringRef Str, unsigned Radix,
-                            unsigned long long &Result);
+  LLVM_ABI bool getAsUnsignedInteger(StringRef Str, unsigned Radix,
+                                     unsigned long long &Result);
 
-  bool getAsSignedInteger(StringRef Str, unsigned Radix, long long &Result);
+  LLVM_ABI bool getAsSignedInteger(StringRef Str, unsigned Radix,
+                                   long long &Result);
 
-  bool consumeUnsignedInteger(StringRef &Str, unsigned Radix,
-                              unsigned long long &Result);
-  bool consumeSignedInteger(StringRef &Str, unsigned Radix, long long &Result);
+  LLVM_ABI bool consumeUnsignedInteger(StringRef &Str, unsigned Radix,
+                                       unsigned long long &Result);
+  LLVM_ABI bool consumeSignedInteger(StringRef &Str, unsigned Radix,
+                                     long long &Result);
 
   /// StringRef - Represent a constant reference to a string, i.e. a character
   /// array and a length, which need not be null terminated.
@@ -193,11 +195,11 @@ namespace llvm {
     }
 
     /// Compare two strings, ignoring case.
-    [[nodiscard]] int compare_insensitive(StringRef RHS) const;
+    [[nodiscard]] LLVM_ABI int compare_insensitive(StringRef RHS) const;
 
     /// compare_numeric - Compare two strings, treating sequences of digits as
     /// numbers.
-    [[nodiscard]] int compare_numeric(StringRef RHS) const;
+    [[nodiscard]] LLVM_ABI int compare_numeric(StringRef RHS) const;
 
     /// Determine the edit distance between this string and another
     /// string.
@@ -217,11 +219,11 @@ namespace llvm {
     /// or (if \p AllowReplacements is \c true) replacements needed to
     /// transform one of the given strings into the other. If zero,
     /// the strings are identical.
-    [[nodiscard]] unsigned edit_distance(StringRef Other,
-                                         bool AllowReplacements = true,
-                                         unsigned MaxEditDistance = 0) const;
+    [[nodiscard]] LLVM_ABI unsigned
+    edit_distance(StringRef Other, bool AllowReplacements = true,
+                  unsigned MaxEditDistance = 0) const;
 
-    [[nodiscard]] unsigned
+    [[nodiscard]] LLVM_ABI unsigned
     edit_distance_insensitive(StringRef Other, bool AllowReplacements = true,
                               unsigned MaxEditDistance = 0) const;
 
@@ -271,7 +273,7 @@ namespace llvm {
     }
 
     /// Check if this string starts with the given \p Prefix, ignoring case.
-    [[nodiscard]] bool starts_with_insensitive(StringRef Prefix) const;
+    [[nodiscard]] LLVM_ABI bool starts_with_insensitive(StringRef Prefix) const;
 
     /// Check if this string ends with the given \p Suffix.
     [[nodiscard]] bool ends_with(StringRef Suffix) const {
@@ -284,7 +286,7 @@ namespace llvm {
     }
 
     /// Check if this string ends with the given \p Suffix, ignoring case.
-    [[nodiscard]] bool ends_with_insensitive(StringRef Suffix) const;
+    [[nodiscard]] LLVM_ABI bool ends_with_insensitive(StringRef Suffix) const;
 
     /// @}
     /// @name String Searching
@@ -302,7 +304,8 @@ namespace llvm {
     ///
     /// \returns The index of the first occurrence of \p C, or npos if not
     /// found.
-    [[nodiscard]] size_t find_insensitive(char C, size_t From = 0) const;
+    [[nodiscard]] LLVM_ABI size_t find_insensitive(char C,
+                                                   size_t From = 0) const;
 
     /// Search for the first character satisfying the predicate \p F
     ///
@@ -332,13 +335,14 @@ namespace llvm {
     ///
     /// \returns The index of the first occurrence of \p Str, or npos if not
     /// found.
-    [[nodiscard]] size_t find(StringRef Str, size_t From = 0) const;
+    [[nodiscard]] LLVM_ABI size_t find(StringRef Str, size_t From = 0) const;
 
     /// Search for the first string \p Str in the string, ignoring case.
     ///
     /// \returns The index of the first occurrence of \p Str, or npos if not
     /// found.
-    [[nodiscard]] size_t find_insensitive(StringRef Str, size_t From = 0) const;
+    [[nodiscard]] LLVM_ABI size_t find_insensitive(StringRef Str,
+                                                   size_t From = 0) const;
 
     /// Search for the last character \p C in the string.
     ///
@@ -358,19 +362,20 @@ namespace llvm {
     ///
     /// \returns The index of the last occurrence of \p C, or npos if not
     /// found.
-    [[nodiscard]] size_t rfind_insensitive(char C, size_t From = npos) const;
+    [[nodiscard]] LLVM_ABI size_t rfind_insensitive(char C,
+                                                    size_t From = npos) const;
 
     /// Search for the last string \p Str in the string.
     ///
     /// \returns The index of the last occurrence of \p Str, or npos if not
     /// found.
-    [[nodiscard]] size_t rfind(StringRef Str) const;
+    [[nodiscard]] LLVM_ABI size_t rfind(StringRef Str) const;
 
     /// Search for the last string \p Str in the string, ignoring case.
     ///
     /// \returns The index of the last occurrence of \p Str, or npos if not
     /// found.
-    [[nodiscard]] size_t rfind_insensitive(StringRef Str) const;
+    [[nodiscard]] LLVM_ABI size_t rfind_insensitive(StringRef Str) const;
 
     /// Find the first character in the string that is \p C, or npos if not
     /// found. Same as find.
@@ -382,18 +387,20 @@ namespace llvm {
     /// not found.
     ///
     /// Complexity: O(size() + Chars.size())
-    [[nodiscard]] size_t find_first_of(StringRef Chars, size_t From = 0) const;
+    [[nodiscard]] LLVM_ABI size_t find_first_of(StringRef Chars,
+                                                size_t From = 0) const;
 
     /// Find the first character in the string that is not \p C or npos if not
     /// found.
-    [[nodiscard]] size_t find_first_not_of(char C, size_t From = 0) const;
+    [[nodiscard]] LLVM_ABI size_t find_first_not_of(char C,
+                                                    size_t From = 0) const;
 
     /// Find the first character in the string that is not in the string
     /// \p Chars, or npos if not found.
     ///
     /// Complexity: O(size() + Chars.size())
-    [[nodiscard]] size_t find_first_not_of(StringRef Chars,
-                                           size_t From = 0) const;
+    [[nodiscard]] LLVM_ABI size_t find_first_not_of(StringRef Chars,
+                                                    size_t From = 0) const;
 
     /// Find the last character in the string that is \p C, or npos if not
     /// found.
@@ -405,19 +412,20 @@ namespace llvm {
     /// found.
     ///
     /// Complexity: O(size() + Chars.size())
-    [[nodiscard]] size_t find_last_of(StringRef Chars,
-                                      size_t From = npos) const;
+    [[nodiscard]] LLVM_ABI size_t find_last_of(StringRef Chars,
+                                               size_t From = npos) const;
 
     /// Find the last character in the string that is not \p C, or npos if not
     /// found.
-    [[nodiscard]] size_t find_last_not_of(char C, size_t From = npos) const;
+    [[nodiscard]] LLVM_ABI size_t find_last_not_of(char C,
+                                                   size_t From = npos) const;
 
     /// Find the last character in the string that is not in \p Chars, or
     /// npos if not found.
     ///
     /// Complexity: O(size() + Chars.size())
-    [[nodiscard]] size_t find_last_not_of(StringRef Chars,
-                                          size_t From = npos) const;
+    [[nodiscard]] LLVM_ABI size_t find_last_not_of(StringRef Chars,
+                                                   size_t From = npos) const;
 
     /// Return true if the given string is a substring of *this, and false
     /// otherwise.
@@ -458,7 +466,7 @@ namespace llvm {
 
     /// Return the number of non-overlapped occurrences of \p Str in
     /// the string.
-    size_t count(StringRef Str) const;
+    LLVM_ABI size_t count(StringRef Str) const;
 
     /// Parse the current string as an integer of the specified radix.  If
     /// \p Radix is specified as zero, this does radix autosensing using
@@ -523,7 +531,7 @@ namespace llvm {
     ///
     /// APInt::fromString is superficially similar but assumes the
     /// string is well-formed in the given radix.
-    bool getAsInteger(unsigned Radix, APInt &Result) const;
+    LLVM_ABI bool getAsInteger(unsigned Radix, APInt &Result) const;
 
     /// Parse the current string as an integer of the specified \p Radix.  If
     /// \p Radix is specified as zero, this does radix autosensing using
@@ -534,7 +542,7 @@ namespace llvm {
     /// erroneous if empty.
     /// The portion of the string representing the discovered numeric value
     /// is removed from the beginning of the string.
-    bool consumeInteger(unsigned Radix, APInt &Result);
+    LLVM_ABI bool consumeInteger(unsigned Radix, APInt &Result);
 
     /// Parse the current string as an IEEE double-precision floating
     /// point value.  The string must be a well-formed double.
@@ -543,17 +551,17 @@ namespace llvm {
     /// cannot be represented exactly.  Otherwise, the function only fails
     /// in case of an overflow or underflow, or an invalid floating point
     /// representation.
-    bool getAsDouble(double &Result, bool AllowInexact = true) const;
+    LLVM_ABI bool getAsDouble(double &Result, bool AllowInexact = true) const;
 
     /// @}
     /// @name String Operations
     /// @{
 
     // Convert the given ASCII string to lowercase.
-    [[nodiscard]] std::string lower() const;
+    [[nodiscard]] LLVM_ABI std::string lower() const;
 
     /// Convert the given ASCII string to uppercase.
-    [[nodiscard]] std::string upper() const;
+    [[nodiscard]] LLVM_ABI std::string upper() const;
 
     /// @}
     /// @name Substring Operations
@@ -751,9 +759,8 @@ namespace llvm {
     /// \param Separator - The string to split on.
     /// \param MaxSplit - The maximum number of times the string is split.
     /// \param KeepEmpty - True if empty substring should be added.
-    void split(SmallVectorImpl<StringRef> &A,
-               StringRef Separator, int MaxSplit = -1,
-               bool KeepEmpty = true) const;
+    LLVM_ABI void split(SmallVectorImpl<StringRef> &A, StringRef Separator,
+                        int MaxSplit = -1, bool KeepEmpty = true) const;
 
     /// Split into substrings around the occurrences of a separator character.
     ///
@@ -769,8 +776,8 @@ namespace llvm {
     /// \param Separator - The string to split on.
     /// \param MaxSplit - The maximum number of times the string is split.
     /// \param KeepEmpty - True if empty substring should be added.
-    void split(SmallVectorImpl<StringRef> &A, char Separator, int MaxSplit = -1,
-               bool KeepEmpty = true) const;
+    LLVM_ABI void split(SmallVectorImpl<StringRef> &A, char Separator,
+                        int MaxSplit = -1, bool KeepEmpty = true) const;
 
     /// Split into two substrings around the last occurrence of a separator
     /// character.
@@ -911,7 +918,7 @@ namespace llvm {
   /// @}
 
   /// Compute a hash_code for a StringRef.
-  [[nodiscard]] hash_code hash_value(StringRef S);
+  [[nodiscard]] LLVM_ABI hash_code hash_value(StringRef S);
 
   // Provide DenseMapInfo for StringRefs.
   template <> struct DenseMapInfo<StringRef, void> {
@@ -925,7 +932,7 @@ namespace llvm {
           reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)), 0);
     }
 
-    static unsigned getHashValue(StringRef Val);
+    LLVM_ABI static unsigned getHashValue(StringRef Val);
 
     static bool isEqual(StringRef LHS, StringRef RHS) {
       if (RHS.data() == getEmptyKey().data())
diff --git a/llvm/include/llvm/ADT/TrieRawHashMap.h b/llvm/include/llvm/ADT/TrieRawHashMap.h
index 1382eac1c768f..a980638166765 100644
--- a/llvm/include/llvm/ADT/TrieRawHashMap.h
+++ b/llvm/include/llvm/ADT/TrieRawHashMap.h
@@ -10,6 +10,7 @@
 #define LLVM_ADT_TRIERAWHASHMAP_H
 
 #include "llvm/ADT/ArrayRef.h"
+#include "llvm/Support/Compiler.h"
 #include <atomic>
 #include <optional>
 
@@ -94,7 +95,7 @@ class ThreadSafeTrieRawHashMapBase {
   LLVM_DUMP_METHOD void dump() const;
 #endif
 
-  void print(raw_ostream &OS) const;
+  LLVM_ABI void print(raw_ostream &OS) const;
 
 protected:
   /// Result of a lookup. Suitable for an insertion hint. Maybe could be
@@ -121,17 +122,17 @@ class ThreadSafeTrieRawHashMapBase {
   };
 
   /// Find the stored content with hash.
-  PointerBase find(ArrayRef<uint8_t> Hash) const;
+  LLVM_ABI PointerBase find(ArrayRef<uint8_t> Hash) const;
 
   /// Insert and return the stored content.
-  PointerBase
+  LLVM_ABI PointerBase
   insert(PointerBase Hint, ArrayRef<uint8_t> Hash,
          function_ref<const uint8_t *(void *Mem, ArrayRef<uint8_t> Hash)>
              Constructor);
 
   ThreadSafeTrieRawHashMapBase() = delete;
 
-  ThreadSafeTrieRawHashMapBase(
+  LLVM_ABI ThreadSafeTrieRawHashMapBase(
       size_t ContentAllocSize, size_t ContentAllocAlign, size_t ContentOffset,
       std::optional<size_t> NumRootBits = std::nullopt,
       std::optional<size_t> NumSubtrieBits = std::nullopt);
@@ -140,10 +141,10 @@ class ThreadSafeTrieRawHashMapBase {
   /// call \a destroyImpl().
   ///
   /// \pre \a destroyImpl() was already called.
-  ~ThreadSafeTrieRawHashMapBase();
-  void destroyImpl(function_ref<void(void *ValueMem)> Destructor);
+  LLVM_ABI ~ThreadSafeTrieRawHashMapBase();
+  LLVM_ABI void destroyImpl(function_ref<void(void *ValueMem)> Destructor);
 
-  ThreadSafeTrieRawHashMapBase(ThreadSafeTrieRawHashMapBase &&RHS);
+  LLVM_ABI ThreadSafeTrieRawHashMapBase(ThreadSafeTrieRawHashMapBase &&RHS);
 
   // Move assignment is not supported as it is not thread-safe.
   ThreadSafeTrieRawHashMapBase &
@@ -156,14 +157,14 @@ class ThreadSafeTrieRawHashMapBase {
 
   // Debug functions. Implementation details and not guaranteed to be
   // thread-safe.
-  PointerBase getRoot() const;
-  unsigned getStartBit(PointerBase P) const;
-  unsigned getNumBits(PointerBase P) const;
-  unsigned getNumSlotUsed(PointerBase P) const;
-  std::string getTriePrefixAsString(PointerBase P) const;
-  unsigned getNumTries() const;
+  LLVM_ABI PointerBase getRoot() const;
+  LLVM_ABI unsigned getStartBit(PointerBase P) const;
+  LLVM_ABI unsigned getNumBits(PointerBase P) const;
+  LLVM_ABI unsigned getNumSlotUsed(PointerBase P) const;
+  LLVM_ABI std::string getTriePrefixAsString(PointerBase P) const;
+  LLVM_ABI unsigned getNumTries() const;
   // Visit next trie in the allocation chain.
-  PointerBase getNextTrie(PointerBase P) const;
+  LLVM_ABI PointerBase getNextTrie(PointerBase P) const;
 
 private:
   friend class TrieRawHashMapTestHelper;
diff --git a/llvm/include/llvm/ADT/Twine.h b/llvm/include/llvm/ADT/Twine.h
index d9e553a8a8c77..7718150780e3a 100644
--- a/llvm/include/llvm/ADT/Twine.h
+++ b/llvm/include/llvm/ADT/Twine.h
@@ -11,6 +11,7 @@
 
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <cassert>
 #include <cstdint>
@@ -463,10 +464,10 @@ namespace llvm {
     /// @{
 
     /// Return the twine contents as a std::string.
-    std::string str() const;
+    LLVM_ABI std::string str() const;
 
     /// Append the concatenated string into the given SmallString or SmallVector.
-    void toVector(SmallVectorImpl<char> &Out) const;
+    LLVM_ABI void toVector(SmallVectorImpl<char> &Out) const;
 
     /// This returns the twine as a single StringRef.  This method is only valid
     /// if isSingleStringRef() is true.
@@ -501,14 +502,15 @@ namespace llvm {
     /// given SmallVector and a StringRef to the SmallVector's data is returned.
     ///
     /// The returned StringRef's size does not include the null terminator.
-    StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
+    LLVM_ABI StringRef
+    toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
 
     /// Write the concatenated string represented by this twine to the
     /// stream \p OS.
-    void print(raw_ostream &OS) const;
+    LLVM_ABI void print(raw_ostream &OS) const;
 
     /// Write the representation of this twine to the stream \p OS.
-    void printRepr(raw_ostream &OS) const;
+    LLVM_ABI void printRepr(raw_ostream &OS) const;
 
 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
     /// Dump the concatenated string represented by this twine to stderr.


Reviews:
user: login: compnerd
body: This seems reasonable to me with minor quibbles about `dump` being introduced into the ABI.
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-13T00:42:58Z
user: login: vgvassilev
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T04:44:42Z
user: login: vgvassilev
body: Lgtm. 
state: APPROVED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T04:48:29Z
user: login: andrurogerz
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-14T05:26:47Z
user: login: compnerd
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-14T22:27:55Z

Review comments:
diff_hunk: @@ -35,51 +36,52 @@ class SlowDynamicAPInt {
   APInt Val;
 
 public:
-  explicit SlowDynamicAPInt(int64_t Val);
-  SlowDynamicAPInt();
-  explicit SlowDynamicAPInt(const APInt &Val);
-  SlowDynamicAPInt &operator=(int64_t Val);
-  explicit operator int64_t() const;
-  SlowDynamicAPInt operator-() const;
-  bool operator==(const SlowDynamicAPInt &O) const;
-  bool operator!=(const SlowDynamicAPInt &O) const;
-  bool operator>(const SlowDynamicAPInt &O) const;
-  bool operator<(const SlowDynamicAPInt &O) const;
-  bool operator<=(const SlowDynamicAPInt &O) const;
-  bool operator>=(const SlowDynamicAPInt &O) const;
-  SlowDynamicAPInt operator+(const SlowDynamicAPInt &O) const;
-  SlowDynamicAPInt operator-(const SlowDynamicAPInt &O) const;
-  SlowDynamicAPInt operator*(const SlowDynamicAPInt &O) const;
-  SlowDynamicAPInt operator/(const SlowDynamicAPInt &O) const;
-  SlowDynamicAPInt operator%(const SlowDynamicAPInt &O) const;
-  SlowDynamicAPInt &operator+=(const SlowDynamicAPInt &O);
-  SlowDynamicAPInt &operator-=(const SlowDynamicAPInt &O);
-  SlowDynamicAPInt &operator*=(const SlowDynamicAPInt &O);
-  SlowDynamicAPInt &operator/=(const SlowDynamicAPInt &O);
-  SlowDynamicAPInt &operator%=(const SlowDynamicAPInt &O);
-
-  SlowDynamicAPInt &operator++();
-  SlowDynamicAPInt &operator--();
-
-  friend SlowDynamicAPInt abs(const SlowDynamicAPInt &X);
-  friend SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS,
-                                  const SlowDynamicAPInt &RHS);
-  friend SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS,
-                                   const SlowDynamicAPInt &RHS);
+  LLVM_ABI explicit SlowDynamicAPInt(int64_t Val);
+  LLVM_ABI SlowDynamicAPInt();
+  LLVM_ABI explicit SlowDynamicAPInt(const APInt &Val);
+  LLVM_ABI SlowDynamicAPInt &operator=(int64_t Val);
+  LLVM_ABI explicit operator int64_t() const;
+  LLVM_ABI SlowDynamicAPInt operator-() const;
+  LLVM_ABI bool operator==(const SlowDynamicAPInt &O) const;
+  LLVM_ABI bool operator!=(const SlowDynamicAPInt &O) const;
+  LLVM_ABI bool operator>(const SlowDynamicAPInt &O) const;
+  LLVM_ABI bool operator<(const SlowDynamicAPInt &O) const;
+  LLVM_ABI bool operator<=(const SlowDynamicAPInt &O) const;
+  LLVM_ABI bool operator>=(const SlowDynamicAPInt &O) const;
+  LLVM_ABI SlowDynamicAPInt operator+(const SlowDynamicAPInt &O) const;
+  LLVM_ABI SlowDynamicAPInt operator-(const SlowDynamicAPInt &O) const;
+  LLVM_ABI SlowDynamicAPInt operator*(const SlowDynamicAPInt &O) const;
+  LLVM_ABI SlowDynamicAPInt operator/(const SlowDynamicAPInt &O) const;
+  LLVM_ABI SlowDynamicAPInt operator%(const SlowDynamicAPInt &O) const;
+  LLVM_ABI SlowDynamicAPInt &operator+=(const SlowDynamicAPInt &O);
+  LLVM_ABI SlowDynamicAPInt &operator-=(const SlowDynamicAPInt &O);
+  LLVM_ABI SlowDynamicAPInt &operator*=(const SlowDynamicAPInt &O);
+  LLVM_ABI SlowDynamicAPInt &operator/=(const SlowDynamicAPInt &O);
+  LLVM_ABI SlowDynamicAPInt &operator%=(const SlowDynamicAPInt &O);
+
+  LLVM_ABI SlowDynamicAPInt &operator++();
+  LLVM_ABI SlowDynamicAPInt &operator--();
+
+  LLVM_ABI_FRIEND friend SlowDynamicAPInt abs(const SlowDynamicAPInt &X);
+  LLVM_ABI_FRIEND friend SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS,
+                                                  const SlowDynamicAPInt &RHS);
+  LLVM_ABI_FRIEND friend SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS,
+                                                   const SlowDynamicAPInt &RHS);
   /// The operands must be non-negative for gcd.
-  friend SlowDynamicAPInt gcd(const SlowDynamicAPInt &A,
-                              const SlowDynamicAPInt &B);
+  LLVM_ABI_FRIEND friend SlowDynamicAPInt gcd(const SlowDynamicAPInt &A,
+                                              const SlowDynamicAPInt &B);
 
   /// Overload to compute a hash_code for a SlowDynamicAPInt value.
-  friend hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT
+  LLVM_ABI_FRIEND friend hash_code
+  hash_value(const SlowDynamicAPInt &X); // NOLINT
 
   // Make DynamicAPInt a friend so it can access Val directly.
   friend DynamicAPInt;
 
   unsigned getBitWidth() const { return Val.getBitWidth(); }
 
-  void print(raw_ostream &OS) const;
-  LLVM_DUMP_METHOD void dump() const;
+  LLVM_ABI void print(raw_ostream &OS) const;
+  LLVM_ABI LLVM_DUMP_METHOD void dump() const;
path: llvm/include/llvm/ADT/SlowDynamicAPInt.h
user: login: compnerd
body: Ideally, this should be protected with the `LLVM_ENABLE_DUMP` check.
created_at: 2025-05-13T00:40:18Z
author_association: MEMBER
diff_hunk: @@ -90,8 +91,8 @@ class ThreadSafeTrieRawHashMapBase {
   static void *operator new(size_t Size) { return ::operator new(Size); }
   void operator delete(void *Ptr) { ::operator delete(Ptr); }
 
-  LLVM_DUMP_METHOD void dump() const;
-  void print(raw_ostream &OS) const;
+  LLVM_ABI LLVM_DUMP_METHOD void dump() const;
path: llvm/include/llvm/ADT/TrieRawHashMap.h
user: login: compnerd
body: Likewise
created_at: 2025-05-13T00:41:07Z
author_association: MEMBER
diff_hunk: @@ -501,20 +502,21 @@ namespace llvm {
     /// given SmallVector and a StringRef to the SmallVector's data is returned.
     ///
     /// The returned StringRef's size does not include the null terminator.
-    StringRef toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
+    LLVM_ABI StringRef
+    toNullTerminatedStringRef(SmallVectorImpl<char> &Out) const;
 
     /// Write the concatenated string represented by this twine to the
     /// stream \p OS.
-    void print(raw_ostream &OS) const;
+    LLVM_ABI void print(raw_ostream &OS) const;
 
     /// Dump the concatenated string represented by this twine to stderr.
-    void dump() const;
+    LLVM_ABI void dump() const;
path: llvm/include/llvm/ADT/Twine.h
user: login: compnerd
body: And here
created_at: 2025-05-13T00:41:17Z
author_association: MEMBER
diff_hunk: @@ -1482,8 +1498,8 @@ class APFloat : public APFloatBase {
         toString(Str, FormatPrecision, FormatMaxPadding, TruncateZero));
   }
 
-  void print(raw_ostream &) const;
-  void dump() const;
+  LLVM_ABI void print(raw_ostream &) const;
+  LLVM_ABI void dump() const;
path: llvm/include/llvm/ADT/APFloat.h
user: login: compnerd
body: This should be guarded by `LLVM_ENABLE_DUMP`.
created_at: 2025-05-13T00:42:36Z
author_association: MEMBER
diff_hunk: @@ -190,22 +191,26 @@ class APFixedPoint {
   // Convert this number to match the semantics provided. If the overflow
   // parameter is provided, set this value to true or false to indicate if this
   // operation results in an overflow.
-  APFixedPoint convert(const FixedPointSemantics &DstSema,
-                       bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint convert(const FixedPointSemantics &DstSema,
+                                bool *Overflow = nullptr) const;
path: llvm/include/llvm/ADT/APFixedPoint.h
user: login: vgvassilev
body: Is that whitespace necessary - can’t tell from the diff. 
created_at: 2025-05-14T04:44:41Z
author_association: CONTRIBUTOR
diff_hunk: @@ -190,22 +191,26 @@ class APFixedPoint {
   // Convert this number to match the semantics provided. If the overflow
   // parameter is provided, set this value to true or false to indicate if this
   // operation results in an overflow.
-  APFixedPoint convert(const FixedPointSemantics &DstSema,
-                       bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint convert(const FixedPointSemantics &DstSema,
+                                bool *Overflow = nullptr) const;
path: llvm/include/llvm/ADT/APFixedPoint.h
user: login: andrurogerz
body: Yes, clang-format added that to align the argument indentation
created_at: 2025-05-14T05:26:47Z
author_association: CONTRIBUTOR

PR comments:
user: login: github-actions[bot]
created_at: 2025-04-21T22:50:56Z
body: <!--LLVM CODE FORMAT COMMENT: {clang-format}-->

:white_check_mark: With the latest revision this PR passed the C/C++ code formatter.
author_association: NONE
user: login: vgvassilev
created_at: 2025-04-23T18:55:08Z
body: Can we mention the mega issue https://github.com/llvm/llvm-project/issues/109483 in the pr description of such PRs?
author_association: CONTRIBUTOR
user: login: llvmbot
created_at: 2025-05-13T00:29:54Z
body: 
<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-adt

Author: Andrew Rogers (andrurogerz)

<details>
<summary>Changes</summary>

## Purpose

This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the `llvm/ADT` library. These annotations currently have no meaningful impact on the LLVM build; however, they are a prerequisite to support an LLVM Windows DLL (shared library) build.

## Background

This effort is tracked in #<!-- -->109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307), and documentation for `LLVM_ABI` and related annotations is found in the LLVM repo [here](https://github.com/llvm/llvm-project/blob/main/llvm/docs/InterfaceExportAnnotations.rst).  

The bulk of these changes were generated automatically using the [Interface Definition Scanner (IDS)](https://github.com/compnerd/ids) tool, followed formatting with `git clang-format`.

The following manual adjustments were also applied after running IDS:

- Add `#include "llvm/Support/Compiler.h"` to files where it was not auto-added by IDS due to no pre-existing block of include statements.
- Add `LLVM_ABI_FRIEND` to a small number of `friend` function declarations
- Add `LLVM_ABI` to a subset of private class methods and fields that require export

## Validation

Local builds and tests to validate cross-platform compatibility. This included llvm, clang, and lldb on the following configurations:

- Windows with MSVC
- Windows with Clang
- Linux with GCC
- Linux with Clang
- Darwin with Clang

---

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


23 Files Affected:

- (modified) llvm/include/llvm/ADT/APFixedPoint.h (+36-30) 
- (modified) llvm/include/llvm/ADT/APFloat.h (+210-194) 
- (modified) llvm/include/llvm/ADT/APInt.h (+169-159) 
- (modified) llvm/include/llvm/ADT/APSInt.h (+3-2) 
- (modified) llvm/include/llvm/ADT/DAGDeltaAlgorithm.h (+2-1) 
- (modified) llvm/include/llvm/ADT/DeltaAlgorithm.h (+2-1) 
- (modified) llvm/include/llvm/ADT/DeltaTree.h (+7-5) 
- (modified) llvm/include/llvm/ADT/DynamicAPInt.h (+5-4) 
- (modified) llvm/include/llvm/ADT/FloatingPointMode.h (+5-4) 
- (modified) llvm/include/llvm/ADT/FoldingSet.h (+26-23) 
- (modified) llvm/include/llvm/ADT/IntEqClasses.h (+6-5) 
- (modified) llvm/include/llvm/ADT/IntervalMap.h (+9-8) 
- (modified) llvm/include/llvm/ADT/RewriteBuffer.h (+8-5) 
- (modified) llvm/include/llvm/ADT/RewriteRope.h (+11-10) 
- (modified) llvm/include/llvm/ADT/SlowDynamicAPInt.h (+79-74) 
- (modified) llvm/include/llvm/ADT/SmallPtrSet.h (+18-14) 
- (modified) llvm/include/llvm/ADT/SmallVector.h (+3-3) 
- (modified) llvm/include/llvm/ADT/Statistic.h (+10-9) 
- (modified) llvm/include/llvm/ADT/StringExtras.h (+13-12) 
- (modified) llvm/include/llvm/ADT/StringMap.h (+9-8) 
- (modified) llvm/include/llvm/ADT/StringRef.h (+49-42) 
- (modified) llvm/include/llvm/ADT/TrieRawHashMap.h (+16-15) 
- (modified) llvm/include/llvm/ADT/Twine.h (+9-7) 


``````````diff
diff --git a/llvm/include/llvm/ADT/APFixedPoint.h b/llvm/include/llvm/ADT/APFixedPoint.h
index 70d7f325702cf..658e7ff9caec8 100644
--- a/llvm/include/llvm/ADT/APFixedPoint.h
+++ b/llvm/include/llvm/ADT/APFixedPoint.h
@@ -19,6 +19,7 @@
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/Hashing.h"
 #include "llvm/ADT/SmallString.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/raw_ostream.h"
 
 namespace llvm {
@@ -84,11 +85,11 @@ class FixedPointSemantics {
   /// precision semantic that can precisely represent the precision and ranges
   /// of both input values. This does not compute the resulting semantics for a
   /// given binary operation.
-  FixedPointSemantics
+  LLVM_ABI FixedPointSemantics
   getCommonSemantics(const FixedPointSemantics &Other) const;
 
   /// Print semantics for debug purposes
-  void print(llvm::raw_ostream& OS) const;
+  LLVM_ABI void print(llvm::raw_ostream &OS) const;
 
   /// Returns true if this fixed-point semantic with its value bits interpreted
   /// as an integer can fit in the given floating point semantic without
@@ -97,7 +98,7 @@ class FixedPointSemantics {
   /// minimum integer representation of 127 and -128, respectively. If both of
   /// these values can be represented (possibly inexactly) in the floating
   /// point semantic without overflowing, this returns true.
-  bool fitsInFloatSemantics(const fltSemantics &FloatSema) const;
+  LLVM_ABI bool fitsInFloatSemantics(const fltSemantics &FloatSema) const;
 
   /// Return the FixedPointSemantics for an integer type.
   static FixedPointSemantics GetIntegerSemantics(unsigned Width,
@@ -118,10 +119,10 @@ class FixedPointSemantics {
   /// The result is dependent on the host endianness and not stable across LLVM
   /// versions. See getFromOpaqueInt() to convert it back to a
   /// FixedPointSemantics object.
-  uint32_t toOpaqueInt() const;
+  LLVM_ABI uint32_t toOpaqueInt() const;
   /// Create a FixedPointSemantics object from an integer created via
   /// toOpaqueInt().
-  static FixedPointSemantics getFromOpaqueInt(uint32_t);
+  LLVM_ABI static FixedPointSemantics getFromOpaqueInt(uint32_t);
 
 private:
   unsigned Width          : WidthBitWidth;
@@ -190,22 +191,26 @@ class APFixedPoint {
   // Convert this number to match the semantics provided. If the overflow
   // parameter is provided, set this value to true or false to indicate if this
   // operation results in an overflow.
-  APFixedPoint convert(const FixedPointSemantics &DstSema,
-                       bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint convert(const FixedPointSemantics &DstSema,
+                                bool *Overflow = nullptr) const;
 
   // Perform binary operations on a fixed point type. The resulting fixed point
   // value will be in the common, full precision semantics that can represent
   // the precision and ranges of both input values. See convert() for an
   // explanation of the Overflow parameter.
-  APFixedPoint add(const APFixedPoint &Other, bool *Overflow = nullptr) const;
-  APFixedPoint sub(const APFixedPoint &Other, bool *Overflow = nullptr) const;
-  APFixedPoint mul(const APFixedPoint &Other, bool *Overflow = nullptr) const;
-  APFixedPoint div(const APFixedPoint &Other, bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint add(const APFixedPoint &Other,
+                            bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint sub(const APFixedPoint &Other,
+                            bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint mul(const APFixedPoint &Other,
+                            bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint div(const APFixedPoint &Other,
+                            bool *Overflow = nullptr) const;
 
   // Perform shift operations on a fixed point type. Unlike the other binary
   // operations, the resulting fixed point value will be in the original
   // semantic.
-  APFixedPoint shl(unsigned Amt, bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint shl(unsigned Amt, bool *Overflow = nullptr) const;
   APFixedPoint shr(unsigned Amt, bool *Overflow = nullptr) const {
     // Right shift cannot overflow.
     if (Overflow)
@@ -215,7 +220,7 @@ class APFixedPoint {
 
   /// Perform a unary negation (-X) on this fixed point type, taking into
   /// account saturation if applicable.
-  APFixedPoint negate(bool *Overflow = nullptr) const;
+  LLVM_ABI APFixedPoint negate(bool *Overflow = nullptr) const;
 
   /// Return the integral part of this fixed point number, rounded towards
   /// zero. (-2.5k -> -2)
@@ -234,25 +239,25 @@ class APFixedPoint {
   /// If the overflow parameter is provided, and the integral value is not able
   /// to be fully stored in the provided width and sign, the overflow parameter
   /// is set to true.
-  APSInt convertToInt(unsigned DstWidth, bool DstSign,
-                      bool *Overflow = nullptr) const;
+  LLVM_ABI APSInt convertToInt(unsigned DstWidth, bool DstSign,
+                               bool *Overflow = nullptr) const;
 
   /// Convert this fixed point number to a floating point value with the
   /// provided semantics.
-  APFloat convertToFloat(const fltSemantics &FloatSema) const;
+  LLVM_ABI APFloat convertToFloat(const fltSemantics &FloatSema) const;
 
-  void toString(SmallVectorImpl<char> &Str) const;
+  LLVM_ABI void toString(SmallVectorImpl<char> &Str) const;
   std::string toString() const {
     SmallString<40> S;
     toString(S);
     return std::string(S);
   }
 
-  void print(raw_ostream &) const;
-  void dump() const;
+  LLVM_ABI void print(raw_ostream &) const;
+  LLVM_ABI void dump() const;
 
   // If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1.
-  int compare(const APFixedPoint &Other) const;
+  LLVM_ABI int compare(const APFixedPoint &Other) const;
   bool operator==(const APFixedPoint &Other) const {
     return compare(Other) == 0;
   }
@@ -268,21 +273,22 @@ class APFixedPoint {
     return compare(Other) <= 0;
   }
 
-  static APFixedPoint getMax(const FixedPointSemantics &Sema);
-  static APFixedPoint getMin(const FixedPointSemantics &Sema);
-  static APFixedPoint getEpsilon(const FixedPointSemantics &Sema);
+  LLVM_ABI static APFixedPoint getMax(const FixedPointSemantics &Sema);
+  LLVM_ABI static APFixedPoint getMin(const FixedPointSemantics &Sema);
+  LLVM_ABI static APFixedPoint getEpsilon(const FixedPointSemantics &Sema);
 
   /// Given a floating point semantic, return the next floating point semantic
   /// with a larger exponent and larger or equal mantissa.
-  static const fltSemantics *promoteFloatSemantics(const fltSemantics *S);
+  LLVM_ABI static const fltSemantics *
+  promoteFloatSemantics(const fltSemantics *S);
 
   /// Create an APFixedPoint with a value equal to that of the provided integer,
   /// and in the same semantics as the provided target semantics. If the value
   /// is not able to fit in the specified fixed point semantics, and the
   /// overflow parameter is provided, it is set to true.
-  static APFixedPoint getFromIntValue(const APSInt &Value,
-                                      const FixedPointSemantics &DstFXSema,
-                                      bool *Overflow = nullptr);
+  LLVM_ABI static APFixedPoint
+  getFromIntValue(const APSInt &Value, const FixedPointSemantics &DstFXSema,
+                  bool *Overflow = nullptr);
 
   /// Create an APFixedPoint with a value equal to that of the provided
   /// floating point value, in the provided target semantics. If the value is
@@ -291,9 +297,9 @@ class APFixedPoint {
   /// For NaN, the Overflow flag is always set. For +inf and -inf, if the
   /// semantic is saturating, the value saturates. Otherwise, the Overflow flag
   /// is set.
-  static APFixedPoint getFromFloatValue(const APFloat &Value,
-                                        const FixedPointSemantics &DstFXSema,
-                                        bool *Overflow = nullptr);
+  LLVM_ABI static APFixedPoint
+  getFromFloatValue(const APFloat &Value, const FixedPointSemantics &DstFXSema,
+                    bool *Overflow = nullptr);
 
 private:
   APSInt Val;
diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index ed49380cfc05f..c671830185737 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -18,6 +18,7 @@
 #include "llvm/ADT/APInt.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/FloatingPointMode.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/float128.h"
 #include <memory>
@@ -253,38 +254,39 @@ struct APFloatBase {
     S_MaxSemantics = S_x87DoubleExtended,
   };
 
-  static const llvm::fltSemantics &EnumToSemantics(Semantics S);
-  static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem);
-
-  static const fltSemantics &IEEEhalf() LLVM_READNONE;
-  static const fltSemantics &BFloat() LLVM_READNONE;
-  static const fltSemantics &IEEEsingle() LLVM_READNONE;
-  static const fltSemantics &IEEEdouble() LLVM_READNONE;
-  static const fltSemantics &IEEEquad() LLVM_READNONE;
-  static const fltSemantics &PPCDoubleDouble() LLVM_READNONE;
-  static const fltSemantics &PPCDoubleDoubleLegacy() LLVM_READNONE;
-  static const fltSemantics &Float8E5M2() LLVM_READNONE;
-  static const fltSemantics &Float8E5M2FNUZ() LLVM_READNONE;
-  static const fltSemantics &Float8E4M3() LLVM_READNONE;
-  static const fltSemantics &Float8E4M3FN() LLVM_READNONE;
-  static const fltSemantics &Float8E4M3FNUZ() LLVM_READNONE;
-  static const fltSemantics &Float8E4M3B11FNUZ() LLVM_READNONE;
-  static const fltSemantics &Float8E3M4() LLVM_READNONE;
-  static const fltSemantics &FloatTF32() LLVM_READNONE;
-  static const fltSemantics &Float8E8M0FNU() LLVM_READNONE;
-  static const fltSemantics &Float6E3M2FN() LLVM_READNONE;
-  static const fltSemantics &Float6E2M3FN() LLVM_READNONE;
-  static const fltSemantics &Float4E2M1FN() LLVM_READNONE;
-  static const fltSemantics &x87DoubleExtended() LLVM_READNONE;
+  LLVM_ABI static const llvm::fltSemantics &EnumToSemantics(Semantics S);
+  LLVM_ABI static Semantics SemanticsToEnum(const llvm::fltSemantics &Sem);
+
+  LLVM_ABI static const fltSemantics &IEEEhalf() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &BFloat() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &IEEEsingle() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &IEEEdouble() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &IEEEquad() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &PPCDoubleDouble() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &PPCDoubleDoubleLegacy() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E5M2() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E5M2FNUZ() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E4M3() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E4M3FN() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E4M3FNUZ() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E4M3B11FNUZ() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E3M4() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &FloatTF32() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float8E8M0FNU() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float6E3M2FN() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float6E2M3FN() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Float4E2M1FN() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &x87DoubleExtended() LLVM_READNONE;
 
   /// A Pseudo fltsemantic used to construct APFloats that cannot conflict with
   /// anything real.
-  static const fltSemantics &Bogus() LLVM_READNONE;
+  LLVM_ABI static const fltSemantics &Bogus() LLVM_READNONE;
 
   // Returns true if any number described by this semantics can be precisely
   // represented by the specified semantics. Does not take into account
   // the value of fltNonfiniteBehavior, hasZero, hasSignedRepr.
-  static bool isRepresentableBy(const fltSemantics &A, const fltSemantics &B);
+  LLVM_ABI static bool isRepresentableBy(const fltSemantics &A,
+                                         const fltSemantics &B);
 
   /// @}
 
@@ -344,26 +346,27 @@ struct APFloatBase {
     IEK_Inf = INT_MAX
   };
 
-  static unsigned int semanticsPrecision(const fltSemantics &);
-  static ExponentType semanticsMinExponent(const fltSemantics &);
-  static ExponentType semanticsMaxExponent(const fltSemantics &);
-  static unsigned int semanticsSizeInBits(const fltSemantics &);
-  static unsigned int semanticsIntSizeInBits(const fltSemantics&, bool);
-  static bool semanticsHasZero(const fltSemantics &);
-  static bool semanticsHasSignedRepr(const fltSemantics &);
-  static bool semanticsHasInf(const fltSemantics &);
-  static bool semanticsHasNaN(const fltSemantics &);
-  static bool isIEEELikeFP(const fltSemantics &);
-  static bool hasSignBitInMSB(const fltSemantics &);
+  LLVM_ABI static unsigned int semanticsPrecision(const fltSemantics &);
+  LLVM_ABI static ExponentType semanticsMinExponent(const fltSemantics &);
+  LLVM_ABI static ExponentType semanticsMaxExponent(const fltSemantics &);
+  LLVM_ABI static unsigned int semanticsSizeInBits(const fltSemantics &);
+  LLVM_ABI static unsigned int semanticsIntSizeInBits(const fltSemantics &,
+                                                      bool);
+  LLVM_ABI static bool semanticsHasZero(const fltSemantics &);
+  LLVM_ABI static bool semanticsHasSignedRepr(const fltSemantics &);
+  LLVM_ABI static bool semanticsHasInf(const fltSemantics &);
+  LLVM_ABI static bool semanticsHasNaN(const fltSemantics &);
+  LLVM_ABI static bool isIEEELikeFP(const fltSemantics &);
+  LLVM_ABI static bool hasSignBitInMSB(const fltSemantics &);
 
   // Returns true if any number described by \p Src can be precisely represented
   // by a normal (not subnormal) value in \p Dst.
-  static bool isRepresentableAsNormalIn(const fltSemantics &Src,
-                                        const fltSemantics &Dst);
+  LLVM_ABI static bool isRepresentableAsNormalIn(const fltSemantics &Src,
+                                                 const fltSemantics &Dst);
 
   /// Returns the size of the floating point number (in bits) in the given
   /// semantics.
-  static unsigned getSizeInBits(const fltSemantics &Sem);
+  LLVM_ABI static unsigned getSizeInBits(const fltSemantics &Sem);
 };
 
 namespace detail {
@@ -404,15 +407,15 @@ class IEEEFloat final {
   /// \name Constructors
   /// @{
 
-  IEEEFloat(const fltSemantics &); // Default construct to +0.0
-  IEEEFloat(const fltSemantics &, integerPart);
-  IEEEFloat(const fltSemantics &, uninitializedTag);
-  IEEEFloat(const fltSemantics &, const APInt &);
-  explicit IEEEFloat(double d);
-  explicit IEEEFloat(float f);
-  IEEEFloat(const IEEEFloat &);
-  IEEEFloat(IEEEFloat &&);
-  ~IEEEFloat();
+  LLVM_ABI IEEEFloat(const fltSemantics &); // Default construct to +0.0
+  LLVM_ABI IEEEFloat(const fltSemantics &, integerPart);
+  LLVM_ABI IEEEFloat(const fltSemantics &, uninitializedTag);
+  LLVM_ABI IEEEFloat(const fltSemantics &, const APInt &);
+  LLVM_ABI explicit IEEEFloat(double d);
+  LLVM_ABI explicit IEEEFloat(float f);
+  LLVM_ABI IEEEFloat(const IEEEFloat &);
+  LLVM_ABI IEEEFloat(IEEEFloat &&);
+  LLVM_ABI ~IEEEFloat();
 
   /// @}
 
@@ -427,46 +430,49 @@ class IEEEFloat final {
   /// \name Arithmetic
   /// @{
 
-  opStatus add(const IEEEFloat &, roundingMode);
-  opStatus subtract(const IEEEFloat &, roundingMode);
-  opStatus multiply(const IEEEFloat &, roundingMode);
-  opStatus divide(const IEEEFloat &, roundingMode);
+  LLVM_ABI opStatus add(const IEEEFloat &, roundingMode);
+  LLVM_ABI opStatus subtract(const IEEEFloat &, roundingMode);
+  LLVM_ABI opStatus multiply(const IEEEFloat &, roundingMode);
+  LLVM_ABI opStatus divide(const IEEEFloat &, roundingMode);
   /// IEEE remainder.
-  opStatus remainder(const IEEEFloat &);
+  LLVM_ABI opStatus remainder(const IEEEFloat &);
   /// C fmod, or llvm frem.
-  opStatus mod(const IEEEFloat &);
-  opStatus fusedMultiplyAdd(const IEEEFloat &, const IEEEFloat &, roundingMode);
-  opStatus roundToIntegral(roundingMode);
+  LLVM_ABI opStatus mod(const IEEEFloat &);
+  LLVM_ABI opStatus fusedMultiplyAdd(const IEEEFloat &, const IEEEFloat &,
+                                     roundingMode);
+  LLVM_ABI opStatus roundToIntegral(roundingMode);
   /// IEEE-754R 5.3.1: nextUp/nextDown.
-  opStatus next(bool nextDown);
+  LLVM_ABI opStatus next(bool nextDown);
 
   /// @}
 
   /// \name Sign operations.
   /// @{
 
-  void changeSign();
+  LLVM_ABI void changeSign();
 
   /// @}
 
   /// \name Conversions
   /// @{
 
-  opStatus convert(const fltSemantics &, roundingMode, bool *);
-  opStatus convertToInteger(MutableArrayRef<integerPart>, unsigned int, bool,
-                            roundingMode, bool *) const;
-  opStatus convertFromAPInt(const APInt &, bool, roundingMode);
-  opStatus convertFromSignExtendedInteger(const integerPart *, unsigned int,
-                                          bool, roundingMode);
-  opStatus convertFromZeroExtendedInteger(const integerPart *, unsigned int,
-                                          bool, roundingMode);
-  Expected<opStatus> convertFromString(StringRef, roundingMode);
-  APInt bitcastToAPInt() const;
-  double convertToDouble() const;
+  LLVM_ABI opStatus convert(const fltSemantics &, roundingMode, bool *);
+  LLVM_ABI opStatus convertToInteger(MutableArrayRef<integerPart>, unsigned int,
+                                     bool, roundingMode, bool *) const;
+  LLVM_ABI opStatus convertFromAPInt(const APInt &, bool, roundingMode);
+  LLVM_ABI opStatus convertFromSignExtendedInteger(const integerPart *,
+                                                   unsigned int, bool,
+                                                   roundingMode);
+  LLVM_ABI opStatus convertFromZeroExtendedInteger(const integerPart *,
+                                                   unsigned int, bool,
+                                                   roundingMode);
+  LLVM_ABI Expected<opStatus> convertFromString(StringRef, roundingMode);
+  LLVM_ABI APInt bitcastToAPInt() const;
+  LLVM_ABI double convertToDouble() const;
 #ifdef HAS_IEE754_FLOAT128
-  float128 convertToQuad() const;
+  LLVM_ABI float128 convertToQuad() const;
 #endif
-  float convertToFloat() const;
+  LLVM_ABI float convertToFloat() const;
 
   /// @}
 
@@ -477,16 +483,16 @@ class IEEEFloat final {
 
   /// IEEE comparison with another floating point number (NaNs compare
   /// unordered, 0==-0).
-  cmpResult compare(const IEEEFloat &) const;
+  LLVM_ABI cmpResult compare(const IEEEFloat &) const;
 
   /// Bitwise comparison for equality (QNaNs compare equal, 0!=-0).
-  bool bitwiseIsEqual(const IEEEFloat &) const;
+  LLVM_ABI bool bitwiseIsEqual(const IEEEFloat &) const;
 
   /// Write out a hexadecimal representation of the floating point value to DST,
   /// which must be of sufficient size, in the C99 form [-]0xh.hhhhp[+-]d.
   /// Return the number of characters written, excluding the terminating NUL.
-  unsigned int convertToHexString(char *dst, unsigned int hexDigits,
-                                  bool upperCase, roundingMode) const;
+  LLVM_ABI unsigned int convertToHexString(char *dst, unsigned int hexDigits,
+                                           bool upperCase, roundingMode) const;
 
   /// \name IEEE-754R 5.7.2 General operations.
   /// @{
@@ -514,7 +520,7 @@ class IEEEFloat final {
 
   /// IEEE-754R isSubnormal(): Returns true if and only if the float is a
   /// denormal.
-  bool isDenormal() const;
+  LLVM_ABI bool isDenormal() const;
 
   /// IEEE-754R isInfinite(): Returns true if and only if the float is infinity.
   bool isInfinity() const { return category == fcInfinity; }
@@ -523,7 +529,7 @@ class IEEEFloat final {
   bool isNaN() const { return category == fcNaN; }
 
   /// Returns true if and only if the float is a signaling NaN.
-  bool isSignaling() const;
+  LLVM_ABI bool isSignaling() const;
 
   /// @}
 
@@ -539,23 +545,23 @@ class IEEEFloat final {
 
   /// Returns true if and only if the number has the smallest possible non-zero
   /// magnitude in the current semantics.
-  bool isSmallest() const;
+  LLVM_ABI bool isSmallest() const;
 
   /// Returns true if this is the smallest (by magnitude) normalized finite
   /// number in the given semantics.
-  ...
[truncated]

``````````

</details>

author_association: MEMBER
user: login: andrurogerz
created_at: 2025-05-13T00:34:24Z
body: @compnerd mind having a look?
author_association: CONTRIBUTOR
user: login: andrurogerz
created_at: 2025-05-14T00:34:25Z
body: #139804 addresses the `dump` method feedback; I will rebase + update this PR once that is accepted and merged
author_association: CONTRIBUTOR
user: login: andrurogerz
created_at: 2025-05-14T17:55:23Z
body: PR #139938 will add proper gating for the `dump()` methods, so I just removed the `LLVM_ABI` annotations from them in this PR.
author_association: CONTRIBUTOR
user: login: andrurogerz
created_at: 2025-05-14T22:26:27Z
body: Rebased on #139938.
author_association: CONTRIBUTOR