[llvm] Llvm abi gnu attribute (PR #144418)

Andrew Rogers via llvm-commits llvm-commits at lists.llvm.org
Mon Jun 16 12:35:27 PDT 2025


https://github.com/andrurogerz created https://github.com/llvm/llvm-project/pull/144418

## Purpose

Update the `LLVM_ABI` macro to always resolve to `__attribute__((visibility("default")))` when building LLVM as a shared library for ELF or Mach-O targets.

## Background

Previously, `LLVM_ABI` was defined to the C++ style attribute `[[gnu::visibility("default")]]` when compiling with gcc, which has more restrictions on its placement. Of note, the C++ style attributes cannot decorate `friend` functions and must not appear after `extern` on variable declarations.

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).  

## Overview
- Directly define `LLVM_ABI` to  `__attribute__((visibility("default")))` instead of `LLVM_ATTRIBUTE_VISIBILITY_DEFAULT`, which resolves to C++ style `[[gnu::visibility("default")]]` when compiling with gcc.
- Remove the `LLVM_ABI_FRIEND` macro and replace all usages of it with `LLVM_ABI`.
- Update the documentation for exporting friend functions to no longer reference `LLVM_ABI_FRIEND`.

## Validation
Built with clang and gcc on Linux.

>From 90321952528ebb7a2a98edd2b657e4d8bc955de4 Mon Sep 17 00:00:00 2001
From: Andrew Rogers <andrurogerz at gmail.com>
Date: Wed, 11 Jun 2025 07:42:15 -0700
Subject: [PATCH 1/3] [llvm] always define LLVM_ABI using __attribute__

---
 llvm/include/llvm/Support/Compiler.h | 21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index 0de789ec68c49..67d5577091405 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -208,19 +208,25 @@
 #endif
 #define LLVM_ABI_FRIEND LLVM_ABI
 #define LLVM_ABI_EXPORT __declspec(dllexport)
-#elif defined(__ELF__) || defined(__MINGW32__) || defined(_AIX) ||             \
-    defined(__MVS__) || defined(__CYGWIN__)
-#define LLVM_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
+#elif __has_attribute(visibility)
+#define LLVM_ABI __attribute__((visibility("default")))
+#if defined(__ELF__) || defined(__MINGW32__) || defined(_AIX) ||               \
+    defined(__MVS__)
 #define LLVM_ABI_FRIEND
-#define LLVM_TEMPLATE_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
+#define LLVM_TEMPLATE_ABI LLVM_ABI
 #define LLVM_EXPORT_TEMPLATE
-#define LLVM_ABI_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
+#define LLVM_ABI_EXPORT LLVM_ABI
 #elif defined(__MACH__) || defined(__WASM__) || defined(__EMSCRIPTEN__)
-#define LLVM_ABI LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
 #define LLVM_ABI_FRIEND
 #define LLVM_TEMPLATE_ABI
 #define LLVM_EXPORT_TEMPLATE
-#define LLVM_ABI_EXPORT LLVM_ATTRIBUTE_VISIBILITY_DEFAULT
+#define LLVM_ABI_EXPORT LLVM_ABI
+#else
+#define LLVM_ABI
+#define LLVM_ABI_FRIEND
+#define LLVM_TEMPLATE_ABI
+#define LLVM_EXPORT_TEMPLATE
+#define LLVM_ABI_EXPORT
 #endif
 #else
 #define LLVM_ABI
@@ -229,6 +235,7 @@
 #define LLVM_EXPORT_TEMPLATE
 #define LLVM_ABI_EXPORT
 #endif
+#endif
 #define LLVM_C_ABI LLVM_ABI
 #endif
 

>From cd46964be650562ea30a7df8b671988e7d707ed6 Mon Sep 17 00:00:00 2001
From: Andrew Rogers <andrurogerz at gmail.com>
Date: Mon, 16 Jun 2025 11:06:53 -0700
Subject: [PATCH 2/3] [llvm] remove LLVM_ABI_FRIEND in favor of LLVM_ABI

---
 llvm/include/llvm/ADT/APFloat.h               | 21 +++++++++----------
 llvm/include/llvm/ADT/SlowDynamicAPInt.h      | 17 +++++++--------
 llvm/include/llvm/Bitcode/BitcodeReader.h     |  2 +-
 llvm/include/llvm/CodeGen/MachineOperand.h    |  2 +-
 llvm/include/llvm/CodeGen/PseudoSourceValue.h |  4 ++--
 llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h |  3 +--
 .../ExecutionEngine/Orc/SymbolStringPool.h    |  8 +++----
 .../llvm/ExecutionEngine/RuntimeDyld.h        |  2 +-
 llvm/include/llvm/IR/Function.h               |  5 ++---
 .../llvm/ProfileData/SampleProfWriter.h       |  4 ++--
 llvm/include/llvm/Support/Compiler.h          | 11 ----------
 llvm/include/llvm/Support/Error.h             |  2 +-
 llvm/include/llvm/Support/FileSystem.h        |  2 +-
 llvm/include/llvm/Support/JSON.h              |  4 ++--
 llvm/include/llvm/Support/Path.h              |  8 +++----
 llvm/include/llvm/Support/PrettyStackTrace.h  |  2 +-
 16 files changed, 41 insertions(+), 56 deletions(-)

diff --git a/llvm/include/llvm/ADT/APFloat.h b/llvm/include/llvm/ADT/APFloat.h
index 13df838da3dad..300f83dcf9ef6 100644
--- a/llvm/include/llvm/ADT/APFloat.h
+++ b/llvm/include/llvm/ADT/APFloat.h
@@ -572,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.
-  LLVM_ABI_FRIEND friend hash_code hash_value(const IEEEFloat &Arg);
+  LLVM_ABI friend hash_code hash_value(const IEEEFloat &Arg);
 
   /// Converts this value into a decimal string.
   ///
@@ -629,13 +629,12 @@ class IEEEFloat final {
   ///   0   -> \c IEK_Zero
   ///   Inf -> \c IEK_Inf
   ///
-  LLVM_ABI_FRIEND friend int ilogb(const IEEEFloat &Arg);
+  LLVM_ABI friend int ilogb(const IEEEFloat &Arg);
 
   /// Returns: X * 2^Exp for integral exponents.
-  LLVM_ABI_FRIEND friend IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode);
+  LLVM_ABI friend IEEEFloat scalbn(IEEEFloat X, int Exp, roundingMode);
 
-  LLVM_ABI_FRIEND friend IEEEFloat frexp(const IEEEFloat &X, int &Exp,
-                                         roundingMode);
+  LLVM_ABI friend IEEEFloat frexp(const IEEEFloat &X, int &Exp, roundingMode);
 
   /// \name Special value setters.
   /// @{
@@ -906,11 +905,11 @@ class DoubleAPFloat final {
   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);
+  LLVM_ABI friend DoubleAPFloat scalbn(const DoubleAPFloat &X, int Exp,
+                                       roundingMode);
+  LLVM_ABI friend DoubleAPFloat frexp(const DoubleAPFloat &X, int &Exp,
+                                      roundingMode);
+  LLVM_ABI friend hash_code hash_value(const DoubleAPFloat &Arg);
 };
 
 LLVM_ABI hash_code hash_value(const DoubleAPFloat &Arg);
@@ -1518,7 +1517,7 @@ class APFloat : public APFloatBase {
     APFLOAT_DISPATCH_ON_SEMANTICS(getExactLog2());
   }
 
-  LLVM_ABI_FRIEND friend hash_code hash_value(const APFloat &Arg);
+  LLVM_ABI 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);
diff --git a/llvm/include/llvm/ADT/SlowDynamicAPInt.h b/llvm/include/llvm/ADT/SlowDynamicAPInt.h
index 702e0398e40fc..a9db8a3ae00c0 100644
--- a/llvm/include/llvm/ADT/SlowDynamicAPInt.h
+++ b/llvm/include/llvm/ADT/SlowDynamicAPInt.h
@@ -62,18 +62,17 @@ class SlowDynamicAPInt {
   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);
+  LLVM_ABI friend SlowDynamicAPInt abs(const SlowDynamicAPInt &X);
+  LLVM_ABI friend SlowDynamicAPInt ceilDiv(const SlowDynamicAPInt &LHS,
+                                           const SlowDynamicAPInt &RHS);
+  LLVM_ABI friend SlowDynamicAPInt floorDiv(const SlowDynamicAPInt &LHS,
+                                            const SlowDynamicAPInt &RHS);
   /// The operands must be non-negative for gcd.
-  LLVM_ABI_FRIEND friend SlowDynamicAPInt gcd(const SlowDynamicAPInt &A,
-                                              const SlowDynamicAPInt &B);
+  LLVM_ABI friend SlowDynamicAPInt gcd(const SlowDynamicAPInt &A,
+                                       const SlowDynamicAPInt &B);
 
   /// Overload to compute a hash_code for a SlowDynamicAPInt value.
-  LLVM_ABI_FRIEND friend hash_code
-  hash_value(const SlowDynamicAPInt &X); // NOLINT
+  LLVM_ABI friend hash_code hash_value(const SlowDynamicAPInt &X); // NOLINT
 
   // Make DynamicAPInt a friend so it can access Val directly.
   friend DynamicAPInt;
diff --git a/llvm/include/llvm/Bitcode/BitcodeReader.h b/llvm/include/llvm/Bitcode/BitcodeReader.h
index e7451a3f1bac9..4f839d4cd1575 100644
--- a/llvm/include/llvm/Bitcode/BitcodeReader.h
+++ b/llvm/include/llvm/Bitcode/BitcodeReader.h
@@ -120,7 +120,7 @@ struct ParserCallbacks {
           IdentificationBit(IdentificationBit), ModuleBit(ModuleBit) {}
 
     // Calls the ctor.
-    LLVM_ABI_FRIEND friend Expected<BitcodeFileContents>
+    LLVM_ABI friend Expected<BitcodeFileContents>
     getBitcodeFileContents(MemoryBufferRef Buffer);
 
     Expected<std::unique_ptr<Module>>
diff --git a/llvm/include/llvm/CodeGen/MachineOperand.h b/llvm/include/llvm/CodeGen/MachineOperand.h
index 161a1cdbff98e..646588a2a92a5 100644
--- a/llvm/include/llvm/CodeGen/MachineOperand.h
+++ b/llvm/include/llvm/CodeGen/MachineOperand.h
@@ -764,7 +764,7 @@ class MachineOperand {
   /// isIdenticalTo uses for comparison. It is thus suited for use in hash
   /// tables which use that function for equality comparisons only. This must
   /// stay exactly in sync with isIdenticalTo above.
-  LLVM_ABI_FRIEND friend hash_code hash_value(const MachineOperand &MO);
+  LLVM_ABI friend hash_code hash_value(const MachineOperand &MO);
 
   /// ChangeToImmediate - Replace this operand with a new immediate operand of
   /// the specified value.  If an operand is known to be an immediate already,
diff --git a/llvm/include/llvm/CodeGen/PseudoSourceValue.h b/llvm/include/llvm/CodeGen/PseudoSourceValue.h
index 01402c31a1e30..aec19005278a4 100644
--- a/llvm/include/llvm/CodeGen/PseudoSourceValue.h
+++ b/llvm/include/llvm/CodeGen/PseudoSourceValue.h
@@ -46,8 +46,8 @@ class LLVM_ABI PseudoSourceValue {
 private:
   unsigned Kind;
   unsigned AddressSpace;
-  LLVM_ABI_FRIEND friend raw_ostream &
-  llvm::operator<<(raw_ostream &OS, const PseudoSourceValue *PSV);
+  LLVM_ABI friend raw_ostream &llvm::operator<<(raw_ostream &OS,
+                                                const PseudoSourceValue *PSV);
 
   friend class MachineMemOperand; // For printCustom().
   friend class MIRFormatter;      // For printCustom().
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
index cb8fdd650a2aa..9c0d6e86d279f 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/LLJIT.h
@@ -42,8 +42,7 @@ class ExecutorProcessControl;
 class LLVM_ABI LLJIT {
   template <typename, typename, typename> friend class LLJITBuilderSetters;
 
-  LLVM_ABI_FRIEND friend Expected<JITDylibSP>
-  setUpGenericLLVMIRPlatform(LLJIT &J);
+  LLVM_ABI friend Expected<JITDylibSP> setUpGenericLLVMIRPlatform(LLJIT &J);
 
 public:
   /// Initializer support for LLJIT.
diff --git a/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h b/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
index d92c029ff84dc..ed6ea961bccfe 100644
--- a/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
+++ b/llvm/include/llvm/ExecutionEngine/Orc/SymbolStringPool.h
@@ -36,8 +36,8 @@ class SymbolStringPool {
   friend class SymbolStringPoolEntryUnsafe;
 
   // Implemented in DebugUtils.h.
-  LLVM_ABI_FRIEND friend raw_ostream &operator<<(raw_ostream &OS,
-                                                 const SymbolStringPool &SSP);
+  LLVM_ABI friend raw_ostream &operator<<(raw_ostream &OS,
+                                          const SymbolStringPool &SSP);
 
 public:
   /// Destroy a SymbolStringPool.
@@ -94,8 +94,8 @@ class SymbolStringPtrBase {
     return LHS.S < RHS.S;
   }
 
-  LLVM_ABI_FRIEND friend raw_ostream &
-  operator<<(raw_ostream &OS, const SymbolStringPtrBase &Sym);
+  LLVM_ABI friend raw_ostream &operator<<(raw_ostream &OS,
+                                          const SymbolStringPtrBase &Sym);
 
 #ifndef NDEBUG
   // Returns true if the pool entry's ref count is above zero (or if the entry
diff --git a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
index c1fab1199f512..57387f029b6cf 100644
--- a/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
+++ b/llvm/include/llvm/ExecutionEngine/RuntimeDyld.h
@@ -287,7 +287,7 @@ class RuntimeDyld {
   LLVM_ABI void finalizeWithMemoryManagerLocking();
 
 private:
-  LLVM_ABI_FRIEND friend void jitLinkForORC(
+  LLVM_ABI friend void jitLinkForORC(
       object::OwningBinary<object::ObjectFile> O,
       RuntimeDyld::MemoryManager &MemMgr, JITSymbolResolver &Resolver,
       bool ProcessAllSections,
diff --git a/llvm/include/llvm/IR/Function.h b/llvm/include/llvm/IR/Function.h
index c361be3e752a9..d3497716ca844 100644
--- a/llvm/include/llvm/IR/Function.h
+++ b/llvm/include/llvm/IR/Function.h
@@ -783,9 +783,8 @@ class LLVM_ABI Function : public GlobalObject, public ilist_node<Function> {
 
 private:
   // These need access to the underlying BB list.
-  LLVM_ABI_FRIEND friend void BasicBlock::removeFromParent();
-  LLVM_ABI_FRIEND friend iplist<BasicBlock>::iterator
-  BasicBlock::eraseFromParent();
+  LLVM_ABI friend void BasicBlock::removeFromParent();
+  LLVM_ABI friend iplist<BasicBlock>::iterator BasicBlock::eraseFromParent();
   template <class BB_t, class BB_i_t, class BI_t, class II_t>
   friend class InstIterator;
   friend class llvm::SymbolTableListTraits<llvm::BasicBlock>;
diff --git a/llvm/include/llvm/ProfileData/SampleProfWriter.h b/llvm/include/llvm/ProfileData/SampleProfWriter.h
index 146d051f770a3..e84b2095efd7b 100644
--- a/llvm/include/llvm/ProfileData/SampleProfWriter.h
+++ b/llvm/include/llvm/ProfileData/SampleProfWriter.h
@@ -193,7 +193,7 @@ class LLVM_ABI SampleProfileWriterText : public SampleProfileWriter {
   /// cannot be skipped.
   bool MarkFlatProfiles = false;
 
-  LLVM_ABI_FRIEND friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
+  LLVM_ABI friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
   SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
                               SampleProfileFormat Format);
 };
@@ -225,7 +225,7 @@ class LLVM_ABI SampleProfileWriterBinary : public SampleProfileWriter {
   void addNames(const FunctionSamples &S);
 
 private:
-  LLVM_ABI_FRIEND friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
+  LLVM_ABI friend ErrorOr<std::unique_ptr<SampleProfileWriter>>
   SampleProfileWriter::create(std::unique_ptr<raw_ostream> &OS,
                               SampleProfileFormat Format);
 };
diff --git a/llvm/include/llvm/Support/Compiler.h b/llvm/include/llvm/Support/Compiler.h
index 67d5577091405..dfd3b04efced1 100644
--- a/llvm/include/llvm/Support/Compiler.h
+++ b/llvm/include/llvm/Support/Compiler.h
@@ -171,11 +171,6 @@
 /// for both functions and classes. On windows its turned in to dllimport for
 /// library consumers, for other platforms its a default visibility attribute.
 ///
-/// LLVM_ABI_FRIEND is for annotating friend function declarations when the
-/// target function's original declaration is annotated with LLVM_ABI. This
-/// macro matches the LLVM_ABI macro on Windows, on other platforms it does
-/// nothing.
-///
 /// LLVM_C_ABI is used to annotated functions and data that need to be exported
 /// for the libllvm-c API. This used both for the llvm-c headers and for the
 /// functions declared in the different Target's c++ source files that don't
@@ -192,7 +187,6 @@
 // missing symbol linker errors on windows.
 #if defined(LLVM_BUILD_STATIC)
 #define LLVM_ABI
-#define LLVM_ABI_FRIEND
 #define LLVM_TEMPLATE_ABI
 #define LLVM_EXPORT_TEMPLATE
 #define LLVM_ABI_EXPORT
@@ -206,31 +200,26 @@
 #define LLVM_TEMPLATE_ABI __declspec(dllimport)
 #define LLVM_EXPORT_TEMPLATE
 #endif
-#define LLVM_ABI_FRIEND LLVM_ABI
 #define LLVM_ABI_EXPORT __declspec(dllexport)
 #elif __has_attribute(visibility)
 #define LLVM_ABI __attribute__((visibility("default")))
 #if defined(__ELF__) || defined(__MINGW32__) || defined(_AIX) ||               \
     defined(__MVS__)
-#define LLVM_ABI_FRIEND
 #define LLVM_TEMPLATE_ABI LLVM_ABI
 #define LLVM_EXPORT_TEMPLATE
 #define LLVM_ABI_EXPORT LLVM_ABI
 #elif defined(__MACH__) || defined(__WASM__) || defined(__EMSCRIPTEN__)
-#define LLVM_ABI_FRIEND
 #define LLVM_TEMPLATE_ABI
 #define LLVM_EXPORT_TEMPLATE
 #define LLVM_ABI_EXPORT LLVM_ABI
 #else
 #define LLVM_ABI
-#define LLVM_ABI_FRIEND
 #define LLVM_TEMPLATE_ABI
 #define LLVM_EXPORT_TEMPLATE
 #define LLVM_ABI_EXPORT
 #endif
 #else
 #define LLVM_ABI
-#define LLVM_ABI_FRIEND
 #define LLVM_TEMPLATE_ABI
 #define LLVM_EXPORT_TEMPLATE
 #define LLVM_ABI_EXPORT
diff --git a/llvm/include/llvm/Support/Error.h b/llvm/include/llvm/Support/Error.h
index 9bb952ceb0dc2..ed83e6e3a40ed 100644
--- a/llvm/include/llvm/Support/Error.h
+++ b/llvm/include/llvm/Support/Error.h
@@ -1191,7 +1191,7 @@ class ExpectedAsOutParameter {
 /// (or Expected) and you want to call code that still returns
 /// std::error_codes.
 class LLVM_ABI ECError : public ErrorInfo<ECError> {
-  LLVM_ABI_FRIEND friend Error errorCodeToError(std::error_code);
+  LLVM_ABI friend Error errorCodeToError(std::error_code);
 
   void anchor() override;
 
diff --git a/llvm/include/llvm/Support/FileSystem.h b/llvm/include/llvm/Support/FileSystem.h
index ae4a212b553c8..31fedc37bf776 100644
--- a/llvm/include/llvm/Support/FileSystem.h
+++ b/llvm/include/llvm/Support/FileSystem.h
@@ -220,7 +220,7 @@ class basic_file_status {
 
 /// Represents the result of a call to sys::fs::status().
 class file_status : public basic_file_status {
-  LLVM_ABI_FRIEND friend bool equivalent(file_status A, file_status B);
+  LLVM_ABI friend bool equivalent(file_status A, file_status B);
 
 #if defined(LLVM_ON_UNIX)
   dev_t fs_st_dev = 0;
diff --git a/llvm/include/llvm/Support/JSON.h b/llvm/include/llvm/Support/JSON.h
index 962d79de8dd1d..74858ec559932 100644
--- a/llvm/include/llvm/Support/JSON.h
+++ b/llvm/include/llvm/Support/JSON.h
@@ -531,7 +531,7 @@ class Value {
                                       llvm::StringRef, std::string, json::Array,
                                       json::Object>
       Union;
-  LLVM_ABI_FRIEND friend bool operator==(const Value &, const Value &);
+  LLVM_ABI friend bool operator==(const Value &, const Value &);
 };
 
 LLVM_ABI bool operator==(const Value &, const Value &);
@@ -713,7 +713,7 @@ class Path::Root {
   llvm::StringLiteral ErrorMessage;
   std::vector<Path::Segment> ErrorPath; // Only valid in error state. Reversed.
 
-  LLVM_ABI_FRIEND friend void Path::report(llvm::StringLiteral Message);
+  LLVM_ABI friend void Path::report(llvm::StringLiteral Message);
 
 public:
   Root(llvm::StringRef Name = "") : Name(Name), ErrorMessage("") {}
diff --git a/llvm/include/llvm/Support/Path.h b/llvm/include/llvm/Support/Path.h
index 32144a0d53488..0d8881359b806 100644
--- a/llvm/include/llvm/Support/Path.h
+++ b/llvm/include/llvm/Support/Path.h
@@ -80,8 +80,8 @@ class const_iterator
   Style S = Style::native; ///< The path style to use.
 
   // An end iterator has Position = Path.size() + 1.
-  LLVM_ABI_FRIEND friend const_iterator begin(StringRef path, Style style);
-  LLVM_ABI_FRIEND friend const_iterator end(StringRef path);
+  LLVM_ABI friend const_iterator begin(StringRef path, Style style);
+  LLVM_ABI friend const_iterator end(StringRef path);
 
 public:
   reference operator*() const { return Component; }
@@ -105,8 +105,8 @@ class reverse_iterator
   size_t    Position = 0;  ///< The iterators current position within Path.
   Style S = Style::native; ///< The path style to use.
 
-  LLVM_ABI_FRIEND friend reverse_iterator rbegin(StringRef path, Style style);
-  LLVM_ABI_FRIEND friend reverse_iterator rend(StringRef path);
+  LLVM_ABI friend reverse_iterator rbegin(StringRef path, Style style);
+  LLVM_ABI friend reverse_iterator rend(StringRef path);
 
 public:
   reference operator*() const { return Component; }
diff --git a/llvm/include/llvm/Support/PrettyStackTrace.h b/llvm/include/llvm/Support/PrettyStackTrace.h
index 33d95f1c5ec74..cf695089b44e7 100644
--- a/llvm/include/llvm/Support/PrettyStackTrace.h
+++ b/llvm/include/llvm/Support/PrettyStackTrace.h
@@ -51,7 +51,7 @@ namespace llvm {
   /// constructed and destructed, they will add their symbolic frames to a
   /// virtual stack trace.  This gets dumped out if the program crashes.
   class LLVM_ABI PrettyStackTraceEntry {
-    LLVM_ABI_FRIEND friend PrettyStackTraceEntry *
+    LLVM_ABI friend PrettyStackTraceEntry *
     ReverseStackTrace(PrettyStackTraceEntry *);
 
     PrettyStackTraceEntry *NextEntry;

>From 1e234c0f475bed4c4657f55eddda7a5a9f485a43 Mon Sep 17 00:00:00 2001
From: Andrew Rogers <andrurogerz at gmail.com>
Date: Mon, 16 Jun 2025 11:10:04 -0700
Subject: [PATCH 3/3] [llvm] remove LLVM_ABI_FRIEND documentation

---
 llvm/docs/InterfaceExportAnnotations.rst | 7 +++----
 1 file changed, 3 insertions(+), 4 deletions(-)

diff --git a/llvm/docs/InterfaceExportAnnotations.rst b/llvm/docs/InterfaceExportAnnotations.rst
index afea5b461d16c..ec1f907b5f645 100644
--- a/llvm/docs/InterfaceExportAnnotations.rst
+++ b/llvm/docs/InterfaceExportAnnotations.rst
@@ -222,7 +222,7 @@ method in a C++ class, it may be annotated for export.
 Friend Functions
 ~~~~~~~~~~~~~~~~
 Friend functions declared in a class, struct or union must be annotated with
-``LLVM_ABI_FRIEND`` if the corresponding function declaration is annotated with
+``LLVM_ABI`` if the corresponding function declaration is annotated with
 ``LLVM_ABI``. This requirement applies even when the class containing the friend
 declaration is annotated with ``LLVM_ABI``.
 
@@ -236,14 +236,13 @@ declaration is annotated with ``LLVM_ABI``.
    class ExampleClass {
      // Friend declaration of a function must be annotated the same as the actual
      // function declaration.
-     LLVM_ABI_FRIEND friend int friend_function(ExampleClass &obj);
+     LLVM_ABI friend int friend_function(ExampleClass &obj);
    };
 
 .. note::
 
    Annotating the friend declaration avoids an “inconsistent dll linkage”
-   compiler error when building a DLL for Windows. The ``LLVM_ABI_FRIEND``
-   annotation is a no-op when building ELF or Mach-O shared libraries.
+   compiler error when building a DLL for Windows.
 
 Virtual Table and Type Info
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~



More information about the llvm-commits mailing list