Skip to content

[llvm] annotate interfaces in llvm/ObjCopy and llvm/Object for DLL export #142668

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 4, 2025

Conversation

andrurogerz
Copy link
Contributor

Purpose

This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the llvm/ObjCopy and llvm/Object libraries. 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, and documentation for LLVM_ABI and related annotations is found in the LLVM repo here.

The bulk of these changes were generated automatically using the Interface Definition Scanner (IDS) tool, followed formatting with git clang-format.

The following manual adjustments were also applied after running IDS on Linux:

  • 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.
  • Manually annotate template class CommonArchiveMemberHeader with LLVM_ABI since IDS ignores templates and this is the simplest solution for DLL-exporting its child classes because it has methods defined out-of-line. Seems to be an uncommon situation.
  • Explicitly make Archive class non-copyable due to the class-level LLVM_ABI annotation.
  • Add default constructor to ELFFile so it can be instantiated for DLL-export as a base class.
  • Add LLVM_TEMPLATE_ABI and LLVM_EXPORT_TEMPLATE to exported instantiated templates.

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

@llvmbot
Copy link
Member

llvmbot commented Jun 4, 2025

@llvm/pr-subscribers-backend-webassembly
@llvm/pr-subscribers-backend-directx

@llvm/pr-subscribers-llvm-binary-utilities

Author: Andrew Rogers (andrurogerz)

Changes

Purpose

This patch is one in a series of code-mods that annotate LLVM’s public interface for export. This patch annotates the llvm/ObjCopy and llvm/Object libraries. 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, and documentation for LLVM_ABI and related annotations is found in the LLVM repo here.

The bulk of these changes were generated automatically using the Interface Definition Scanner (IDS) tool, followed formatting with git clang-format.

The following manual adjustments were also applied after running IDS on Linux:

  • 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.
  • Manually annotate template class CommonArchiveMemberHeader with LLVM_ABI since IDS ignores templates and this is the simplest solution for DLL-exporting its child classes because it has methods defined out-of-line. Seems to be an uncommon situation.
  • Explicitly make Archive class non-copyable due to the class-level LLVM_ABI annotation.
  • Add default constructor to ELFFile so it can be instantiated for DLL-export as a base class.
  • Add LLVM_TEMPLATE_ABI and LLVM_EXPORT_TEMPLATE to exported instantiated templates.

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 87.78 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/142668.diff

41 Files Affected:

  • (modified) llvm/include/llvm/ObjCopy/COFF/COFFObjcopy.h (+6-2)
  • (modified) llvm/include/llvm/ObjCopy/CommonConfig.h (+2-1)
  • (modified) llvm/include/llvm/ObjCopy/ConfigManager.h (+3-2)
  • (modified) llvm/include/llvm/ObjCopy/ELF/ELFObjcopy.h (+12-9)
  • (modified) llvm/include/llvm/ObjCopy/MachO/MachOObjcopy.h (+7-4)
  • (modified) llvm/include/llvm/ObjCopy/ObjCopy.h (+5-4)
  • (modified) llvm/include/llvm/ObjCopy/wasm/WasmObjcopy.h (+6-2)
  • (modified) llvm/include/llvm/Object/Archive.h (+31-24)
  • (modified) llvm/include/llvm/Object/ArchiveWriter.h (+22-20)
  • (modified) llvm/include/llvm/Object/Binary.h (+8-7)
  • (modified) llvm/include/llvm/Object/BuildID.h (+4-3)
  • (modified) llvm/include/llvm/Object/COFF.h (+63-60)
  • (modified) llvm/include/llvm/Object/COFFImportFile.h (+6-5)
  • (modified) llvm/include/llvm/Object/COFFModuleDefinition.h (+2-1)
  • (modified) llvm/include/llvm/Object/DXContainer.h (+9-8)
  • (modified) llvm/include/llvm/Object/Decompressor.h (+4-3)
  • (modified) llvm/include/llvm/Object/ELF.h (+6-3)
  • (modified) llvm/include/llvm/Object/ELFObjectFile.h (+4-2)
  • (modified) llvm/include/llvm/Object/Error.h (+6-4)
  • (modified) llvm/include/llvm/Object/FaultMapParser.h (+6-5)
  • (modified) llvm/include/llvm/Object/GOFFObjectFile.h (+2-1)
  • (modified) llvm/include/llvm/Object/IRObjectFile.h (+3-3)
  • (modified) llvm/include/llvm/Object/IRSymtab.h (+5-3)
  • (modified) llvm/include/llvm/Object/MachO.h (+68-63)
  • (modified) llvm/include/llvm/Object/MachOUniversal.h (+6-6)
  • (modified) llvm/include/llvm/Object/MachOUniversalWriter.h (+13-10)
  • (modified) llvm/include/llvm/Object/Minidump.h (+11-7)
  • (modified) llvm/include/llvm/Object/ModuleSymbolTable.h (+6-5)
  • (modified) llvm/include/llvm/Object/ObjectFile.h (+4-3)
  • (modified) llvm/include/llvm/Object/OffloadBinary.h (+12-10)
  • (modified) llvm/include/llvm/Object/OffloadBundle.h (+11-10)
  • (modified) llvm/include/llvm/Object/RelocationResolver.h (+5-3)
  • (modified) llvm/include/llvm/Object/SymbolSize.h (+3-3)
  • (modified) llvm/include/llvm/Object/SymbolicFile.h (+2-1)
  • (modified) llvm/include/llvm/Object/TapiFile.h (+2-1)
  • (modified) llvm/include/llvm/Object/TapiUniversal.h (+3-2)
  • (modified) llvm/include/llvm/Object/Wasm.h (+7-4)
  • (modified) llvm/include/llvm/Object/WindowsMachineFlag.h (+3-2)
  • (modified) llvm/include/llvm/Object/WindowsResource.h (+15-13)
  • (modified) llvm/include/llvm/Object/XCOFFObjectFile.h (+58-52)
  • (modified) llvm/lib/Object/XCOFFObjectFile.cpp (+6-6)
diff --git a/llvm/include/llvm/ObjCopy/COFF/COFFObjcopy.h b/llvm/include/llvm/ObjCopy/COFF/COFFObjcopy.h
index d9043d6c5d019..2ec1ca9614113 100644
--- a/llvm/include/llvm/ObjCopy/COFF/COFFObjcopy.h
+++ b/llvm/include/llvm/ObjCopy/COFF/COFFObjcopy.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_OBJCOPY_COFF_COFFOBJCOPY_H
 #define LLVM_OBJCOPY_COFF_COFFOBJCOPY_H
 
+#include "llvm/Support/Compiler.h"
+
 namespace llvm {
 class Error;
 class raw_ostream;
@@ -26,8 +28,10 @@ namespace coff {
 /// Apply the transformations described by \p Config and \p COFFConfig
 /// to \p In and writes the result into \p Out.
 /// \returns any Error encountered whilst performing the operation.
-Error executeObjcopyOnBinary(const CommonConfig &Config, const COFFConfig &,
-                             object::COFFObjectFile &In, raw_ostream &Out);
+LLVM_ABI Error executeObjcopyOnBinary(const CommonConfig &Config,
+                                      const COFFConfig &,
+                                      object::COFFObjectFile &In,
+                                      raw_ostream &Out);
 
 } // end namespace coff
 } // end namespace objcopy
diff --git a/llvm/include/llvm/ObjCopy/CommonConfig.h b/llvm/include/llvm/ObjCopy/CommonConfig.h
index aea9cd6f9a9c7..faa7b0db757a3 100644
--- a/llvm/include/llvm/ObjCopy/CommonConfig.h
+++ b/llvm/include/llvm/ObjCopy/CommonConfig.h
@@ -16,6 +16,7 @@
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Object/ELFTypes.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/Compression.h"
 #include "llvm/Support/GlobPattern.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -104,7 +105,7 @@ class NameOrPattern {
 public:
   // ErrorCallback is used to handle recoverable errors. An Error returned
   // by the callback aborts the parsing and is then returned by this function.
-  static Expected<NameOrPattern>
+  LLVM_ABI static Expected<NameOrPattern>
   create(StringRef Pattern, MatchStyle MS,
          llvm::function_ref<Error(Error)> ErrorCallback);
 
diff --git a/llvm/include/llvm/ObjCopy/ConfigManager.h b/llvm/include/llvm/ObjCopy/ConfigManager.h
index 2962cf99b270d..e7b3775f0e9f1 100644
--- a/llvm/include/llvm/ObjCopy/ConfigManager.h
+++ b/llvm/include/llvm/ObjCopy/ConfigManager.h
@@ -14,13 +14,14 @@
 #include "llvm/ObjCopy/ELF/ELFConfig.h"
 #include "llvm/ObjCopy/MachO/MachOConfig.h"
 #include "llvm/ObjCopy/MultiFormatConfig.h"
-#include "llvm/ObjCopy/wasm/WasmConfig.h"
 #include "llvm/ObjCopy/XCOFF/XCOFFConfig.h"
+#include "llvm/ObjCopy/wasm/WasmConfig.h"
+#include "llvm/Support/Compiler.h"
 
 namespace llvm {
 namespace objcopy {
 
-struct ConfigManager : public MultiFormatConfig {
+struct LLVM_ABI ConfigManager : public MultiFormatConfig {
   virtual ~ConfigManager() {}
 
   const CommonConfig &getCommonConfig() const override { return Common; }
diff --git a/llvm/include/llvm/ObjCopy/ELF/ELFObjcopy.h b/llvm/include/llvm/ObjCopy/ELF/ELFObjcopy.h
index 552b6fb655f18..05fe2828a86f0 100644
--- a/llvm/include/llvm/ObjCopy/ELF/ELFObjcopy.h
+++ b/llvm/include/llvm/ObjCopy/ELF/ELFObjcopy.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_OBJCOPY_ELF_ELFOBJCOPY_H
 #define LLVM_OBJCOPY_ELF_ELFOBJCOPY_H
 
+#include "llvm/Support/Compiler.h"
+
 namespace llvm {
 class Error;
 class MemoryBuffer;
@@ -27,24 +29,25 @@ namespace elf {
 /// \p In, which must represent an IHex file, and writes the result
 /// into \p Out.
 /// \returns any Error encountered whilst performing the operation.
-Error executeObjcopyOnIHex(const CommonConfig &Config,
-                           const ELFConfig &ELFConfig, MemoryBuffer &In,
-                           raw_ostream &Out);
+LLVM_ABI Error executeObjcopyOnIHex(const CommonConfig &Config,
+                                    const ELFConfig &ELFConfig,
+                                    MemoryBuffer &In, raw_ostream &Out);
 
 /// Apply the transformations described by \p Config and \p ELFConfig to
 /// \p In, which is treated as a raw binary input, and writes the result
 /// into \p Out.
 /// \returns any Error encountered whilst performing the operation.
-Error executeObjcopyOnRawBinary(const CommonConfig &Config,
-                                const ELFConfig &ELFConfig, MemoryBuffer &In,
-                                raw_ostream &Out);
+LLVM_ABI Error executeObjcopyOnRawBinary(const CommonConfig &Config,
+                                         const ELFConfig &ELFConfig,
+                                         MemoryBuffer &In, raw_ostream &Out);
 
 /// Apply the transformations described by \p Config and \p ELFConfig to
 /// \p In and writes the result into \p Out.
 /// \returns any Error encountered whilst performing the operation.
-Error executeObjcopyOnBinary(const CommonConfig &Config,
-                             const ELFConfig &ELFConfig,
-                             object::ELFObjectFileBase &In, raw_ostream &Out);
+LLVM_ABI Error executeObjcopyOnBinary(const CommonConfig &Config,
+                                      const ELFConfig &ELFConfig,
+                                      object::ELFObjectFileBase &In,
+                                      raw_ostream &Out);
 
 } // end namespace elf
 } // end namespace objcopy
diff --git a/llvm/include/llvm/ObjCopy/MachO/MachOObjcopy.h b/llvm/include/llvm/ObjCopy/MachO/MachOObjcopy.h
index 73690d7ace8a5..1efe61a819fd6 100644
--- a/llvm/include/llvm/ObjCopy/MachO/MachOObjcopy.h
+++ b/llvm/include/llvm/ObjCopy/MachO/MachOObjcopy.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_OBJCOPY_MACHO_MACHOOBJCOPY_H
 #define LLVM_OBJCOPY_MACHO_MACHOOBJCOPY_H
 
+#include "llvm/Support/Compiler.h"
+
 namespace llvm {
 class Error;
 class raw_ostream;
@@ -27,14 +29,15 @@ namespace macho {
 /// Apply the transformations described by \p Config and \p MachOConfig to
 /// \p In and writes the result into \p Out.
 /// \returns any Error encountered whilst performing the operation.
-Error executeObjcopyOnBinary(const CommonConfig &Config,
-                             const MachOConfig &MachOConfig,
-                             object::MachOObjectFile &In, raw_ostream &Out);
+LLVM_ABI Error executeObjcopyOnBinary(const CommonConfig &Config,
+                                      const MachOConfig &MachOConfig,
+                                      object::MachOObjectFile &In,
+                                      raw_ostream &Out);
 
 /// Apply the transformations described by \p Config and \p MachOConfig to
 /// \p In and writes the result into \p Out.
 /// \returns any Error encountered whilst performing the operation.
-Error executeObjcopyOnMachOUniversalBinary(
+LLVM_ABI Error executeObjcopyOnMachOUniversalBinary(
     const MultiFormatConfig &Config, const object::MachOUniversalBinary &In,
     raw_ostream &Out);
 
diff --git a/llvm/include/llvm/ObjCopy/ObjCopy.h b/llvm/include/llvm/ObjCopy/ObjCopy.h
index 023814002c727..9554930e20970 100644
--- a/llvm/include/llvm/ObjCopy/ObjCopy.h
+++ b/llvm/include/llvm/ObjCopy/ObjCopy.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_OBJCOPY_OBJCOPY_H
 #define LLVM_OBJCOPY_OBJCOPY_H
 
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/Error.h"
 
 namespace llvm {
@@ -26,15 +27,15 @@ class MultiFormatConfig;
 /// each member in archive \p Ar.
 /// Writes a result in a file specified by \p Config.OutputFilename.
 /// \returns any Error encountered whilst performing the operation.
-Error executeObjcopyOnArchive(const MultiFormatConfig &Config,
-                              const object::Archive &Ar);
+LLVM_ABI Error executeObjcopyOnArchive(const MultiFormatConfig &Config,
+                                       const object::Archive &Ar);
 
 /// Applies the transformations described by \p Config to \p In and writes
 /// the result into \p Out. This function does the dispatch based on the
 /// format of the input binary (COFF, ELF, MachO or wasm).
 /// \returns any Error encountered whilst performing the operation.
-Error executeObjcopyOnBinary(const MultiFormatConfig &Config,
-                             object::Binary &In, raw_ostream &Out);
+LLVM_ABI Error executeObjcopyOnBinary(const MultiFormatConfig &Config,
+                                      object::Binary &In, raw_ostream &Out);
 
 } // end namespace objcopy
 } // end namespace llvm
diff --git a/llvm/include/llvm/ObjCopy/wasm/WasmObjcopy.h b/llvm/include/llvm/ObjCopy/wasm/WasmObjcopy.h
index 5b4181c22b979..da8ce374dc406 100644
--- a/llvm/include/llvm/ObjCopy/wasm/WasmObjcopy.h
+++ b/llvm/include/llvm/ObjCopy/wasm/WasmObjcopy.h
@@ -9,6 +9,8 @@
 #ifndef LLVM_OBJCOPY_WASM_WASMOBJCOPY_H
 #define LLVM_OBJCOPY_WASM_WASMOBJCOPY_H
 
+#include "llvm/Support/Compiler.h"
+
 namespace llvm {
 class Error;
 class raw_ostream;
@@ -25,8 +27,10 @@ namespace wasm {
 /// Apply the transformations described by \p Config and \p WasmConfig
 /// to \p In and writes the result into \p Out.
 /// \returns any Error encountered whilst performing the operation.
-Error executeObjcopyOnBinary(const CommonConfig &Config, const WasmConfig &,
-                             object::WasmObjectFile &In, raw_ostream &Out);
+LLVM_ABI Error executeObjcopyOnBinary(const CommonConfig &Config,
+                                      const WasmConfig &,
+                                      object::WasmObjectFile &In,
+                                      raw_ostream &Out);
 
 } // end namespace wasm
 } // end namespace objcopy
diff --git a/llvm/include/llvm/Object/Archive.h b/llvm/include/llvm/Object/Archive.h
index b2dd970b00c05..9a4311993acd2 100644
--- a/llvm/include/llvm/Object/Archive.h
+++ b/llvm/include/llvm/Object/Archive.h
@@ -18,6 +18,7 @@
 #include "llvm/ADT/iterator_range.h"
 #include "llvm/Object/Binary.h"
 #include "llvm/Support/Chrono.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/FileSystem.h"
 #include "llvm/Support/MemoryBuffer.h"
@@ -61,10 +62,11 @@ class AbstractArchiveMemberHeader {
   virtual Expected<const char *> getNextChildLoc() const = 0;
   virtual Expected<bool> isThin() const = 0;
 
-  Expected<sys::fs::perms> getAccessMode() const;
-  Expected<sys::TimePoint<std::chrono::seconds>> getLastModified() const;
-  Expected<unsigned> getUID() const;
-  Expected<unsigned> getGID() const;
+  LLVM_ABI Expected<sys::fs::perms> getAccessMode() const;
+  LLVM_ABI Expected<sys::TimePoint<std::chrono::seconds>>
+  getLastModified() const;
+  LLVM_ABI Expected<unsigned> getUID() const;
+  LLVM_ABI Expected<unsigned> getGID() const;
 
   /// Returns the size in bytes of the format-defined member header of the
   /// concrete archive type.
@@ -74,7 +76,7 @@ class AbstractArchiveMemberHeader {
 };
 
 template <typename T>
-class CommonArchiveMemberHeader : public AbstractArchiveMemberHeader {
+class LLVM_ABI CommonArchiveMemberHeader : public AbstractArchiveMemberHeader {
 public:
   CommonArchiveMemberHeader(const Archive *Parent, const T *RawHeaderPtr)
       : AbstractArchiveMemberHeader(Parent), ArMemHdr(RawHeaderPtr){};
@@ -99,7 +101,8 @@ struct UnixArMemHdrType {
   char Terminator[2];
 };
 
-class ArchiveMemberHeader : public CommonArchiveMemberHeader<UnixArMemHdrType> {
+class LLVM_ABI ArchiveMemberHeader
+    : public CommonArchiveMemberHeader<UnixArMemHdrType> {
 public:
   ArchiveMemberHeader(const Archive *Parent, const char *RawHeaderPtr,
                       uint64_t Size, Error *Err);
@@ -133,7 +136,7 @@ struct BigArMemHdrType {
 };
 
 // Define file member header of AIX big archive.
-class BigArchiveMemberHeader
+class LLVM_ABI BigArchiveMemberHeader
     : public CommonArchiveMemberHeader<BigArMemHdrType> {
 
 public:
@@ -153,7 +156,7 @@ class BigArchiveMemberHeader
   Expected<bool> isThin() const override { return false; }
 };
 
-class Archive : public Binary {
+class LLVM_ABI Archive : public Binary {
   virtual void anchor();
 
 public:
@@ -171,8 +174,8 @@ class Archive : public Binary {
     Expected<bool> isThinMember() const;
 
   public:
-    Child(const Archive *Parent, const char *Start, Error *Err);
-    Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile);
+    LLVM_ABI Child(const Archive *Parent, const char *Start, Error *Err);
+    LLVM_ABI Child(const Archive *Parent, StringRef Data, uint16_t StartOfFile);
 
     Child(const Child &C)
         : Parent(C.Parent), Data(C.Data), StartOfFile(C.StartOfFile) {
@@ -218,10 +221,10 @@ class Archive : public Binary {
     }
 
     const Archive *getParent() const { return Parent; }
-    Expected<Child> getNext() const;
+    LLVM_ABI Expected<Child> getNext() const;
 
-    Expected<StringRef> getName() const;
-    Expected<std::string> getFullName() const;
+    LLVM_ABI Expected<StringRef> getName() const;
+    LLVM_ABI Expected<std::string> getFullName() const;
     Expected<StringRef> getRawName() const { return Header->getRawName(); }
 
     Expected<sys::TimePoint<std::chrono::seconds>> getLastModified() const {
@@ -240,17 +243,17 @@ class Archive : public Binary {
     }
 
     /// \return the size of the archive member without the header or padding.
-    Expected<uint64_t> getSize() const;
+    LLVM_ABI Expected<uint64_t> getSize() const;
     /// \return the size in the archive header for this member.
-    Expected<uint64_t> getRawSize() const;
+    LLVM_ABI Expected<uint64_t> getRawSize() const;
 
-    Expected<StringRef> getBuffer() const;
-    uint64_t getChildOffset() const;
+    LLVM_ABI Expected<StringRef> getBuffer() const;
+    LLVM_ABI uint64_t getChildOffset() const;
     uint64_t getDataOffset() const { return getChildOffset() + StartOfFile; }
 
-    Expected<MemoryBufferRef> getMemoryBufferRef() const;
+    LLVM_ABI Expected<MemoryBufferRef> getMemoryBufferRef() const;
 
-    Expected<std::unique_ptr<Binary>>
+    LLVM_ABI Expected<std::unique_ptr<Binary>>
     getAsBinary(LLVMContext *Context = nullptr) const;
   };
 
@@ -299,10 +302,10 @@ class Archive : public Binary {
       return (Parent == other.Parent) && (SymbolIndex == other.SymbolIndex);
     }
 
-    StringRef getName() const;
-    Expected<Child> getMember() const;
-    Symbol getNext() const;
-    bool isECSymbol() const;
+    LLVM_ABI StringRef getName() const;
+    LLVM_ABI Expected<Child> getMember() const;
+    LLVM_ABI Symbol getNext() const;
+    LLVM_ABI bool isECSymbol() const;
   };
 
   class symbol_iterator {
@@ -331,6 +334,10 @@ class Archive : public Binary {
   Archive(MemoryBufferRef Source, Error &Err);
   static Expected<std::unique_ptr<Archive>> create(MemoryBufferRef Source);
 
+  // Explicitly non-copyable.
+  Archive(Archive const &) = delete;
+  Archive &operator=(Archive const &) = delete;
+
   /// Size field is 10 decimal digits long
   static const uint64_t MaxMemberSize = 9999999999;
 
@@ -416,7 +423,7 @@ class BigArchive : public Archive {
   bool Has64BitGlobalSymtab = false;
 
 public:
-  BigArchive(MemoryBufferRef Source, Error &Err);
+  LLVM_ABI BigArchive(MemoryBufferRef Source, Error &Err);
   uint64_t getFirstChildOffset() const override { return FirstChildOffset; }
   uint64_t getLastChildOffset() const { return LastChildOffset; }
   bool isEmpty() const override { return getFirstChildOffset() == 0; }
diff --git a/llvm/include/llvm/Object/ArchiveWriter.h b/llvm/include/llvm/Object/ArchiveWriter.h
index 95b81f5f64c8f..dad150ce1d847 100644
--- a/llvm/include/llvm/Object/ArchiveWriter.h
+++ b/llvm/include/llvm/Object/ArchiveWriter.h
@@ -14,6 +14,7 @@
 #define LLVM_OBJECT_ARCHIVEWRITER_H
 
 #include "llvm/Object/Archive.h"
+#include "llvm/Support/Compiler.h"
 
 namespace llvm {
 
@@ -24,21 +25,22 @@ struct NewArchiveMember {
   unsigned UID = 0, GID = 0, Perms = 0644;
 
   NewArchiveMember() = default;
-  NewArchiveMember(MemoryBufferRef BufRef);
+  LLVM_ABI NewArchiveMember(MemoryBufferRef BufRef);
 
   // Detect the archive format from the object or bitcode file. This helps
   // assume the archive format when creating or editing archives in the case
   // one isn't explicitly set.
-  object::Archive::Kind detectKindFromObject() const;
+  LLVM_ABI object::Archive::Kind detectKindFromObject() const;
 
-  static Expected<NewArchiveMember>
+  LLVM_ABI static Expected<NewArchiveMember>
   getOldMember(const object::Archive::Child &OldMember, bool Deterministic);
 
-  static Expected<NewArchiveMember> getFile(StringRef FileName,
-                                            bool Deterministic);
+  LLVM_ABI static Expected<NewArchiveMember> getFile(StringRef FileName,
+                                                     bool Deterministic);
 };
 
-Expected<std::string> computeArchiveRelativePath(StringRef From, StringRef To);
+LLVM_ABI Expected<std::string> computeArchiveRelativePath(StringRef From,
+                                                          StringRef To);
 
 enum class SymtabWritingMode {
   NoSymtab,     // Do not write symbol table.
@@ -48,26 +50,26 @@ enum class SymtabWritingMode {
   BigArchive64  // Only write the 64-bit symbol table.
 };
 
-void warnToStderr(Error Err);
+LLVM_ABI void warnToStderr(Error Err);
 
 // Write an archive directly to an output stream.
-Error writeArchiveToStream(raw_ostream &Out,
-                           ArrayRef<NewArchiveMember> NewMembers,
-                           SymtabWritingMode WriteSymtab,
-                           object::Archive::Kind Kind, bool Deterministic,
-                           bool Thin, std::optional<bool> IsEC = std::nullopt,
-                           function_ref<void(Error)> Warn = warnToStderr);
+LLVM_ABI Error writeArchiveToStream(
+    raw_ostream &Out, ArrayRef<NewArchiveMember> NewMembers,
+    SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
+    bool Deterministic, bool Thin, std::optional<bool> IsEC = std::nullopt,
+    function_ref<void(Error)> Warn = warnToStderr);
 
-Error writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
-                   SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
-                   bool Deterministic, bool Thin,
-                   std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr,
-                   std::optional<bool> IsEC = std::nullopt,
-                   function_ref<void(Error)> Warn = warnToStderr);
+LLVM_ABI Error
+writeArchive(StringRef ArcName, ArrayRef<NewArchiveMember> NewMembers,
+             SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
+             bool Deterministic, bool Thin,
+             std::unique_ptr<MemoryBuffer> OldArchiveBuf = nullptr,
+             std::optional<bool> IsEC = std::nullopt,
+             function_ref<void(Error)> Warn = warnToStderr);
 
 // writeArchiveToBuffer is similar to writeArchive but returns the Archive in a
 // buffer instead of writing it out to a file.
-Expected<std::unique_ptr<MemoryBuffer>>
+LLVM_ABI Expected<std::unique_ptr<MemoryBuffer>>
 writeArchiveToBuffer(ArrayRef<NewArchiveMember> NewMembers,
                      SymtabWritingMode WriteSymtab, object::Archive::Kind Kind,
                      bool Deterministic, bool Thin,
diff --git a/llvm/include/llvm/Object/Binary.h b/llvm/include/llvm/Object/Binary.h
index ce870e25acafe..bd98f40dbc706 100644
--- a/llvm/include/llvm/Object/Binary.h
+++ b/llvm/include/llvm/Object/Binary.h
@@ -16,6 +16,7 @@
 #include "llvm-c/Types.h"
 #include "llvm/Object/Error.h"
 #include "llvm/Support/CBindingWrapping.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/Error.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/TargetParser/Triple.h"
@@ -29,7 +30,7 @@ class StringRef;
 
 namespace object {
 
-class Binary {
+class LLVM_ABI Binary {
 private:
   unsigned int TypeID;
 
@@ -189,9 +190,9 @@ DEFINE_ISA_CONVERSION_FUNCTIONS(Binary, LLVMBinaryRef)
 /// Create a Binary from Source, autodetecting the file type.
 ///
 /// @param Source The data to create the Binary from.
-Expected<std::unique_ptr<Binary>> createBinary(MemoryBufferRef Source,
-                                               LLVMContext *Context = nullptr,
-                                               bool InitContent = true);
+LLVM_ABI Expected<std::unique_ptr<Binary>>
+createBinary(MemoryBufferRef Source, LLVMContext *Context = nullptr,
+             bool InitContent = true);
 
 template <typename T> class OwningBinary {
   std::unique_ptr<T> Bin;
@@ -241,9 +242,9 @@ template <typename T> const T* OwningBinary<T>::getBinary() const {
   return Bin.get();
 }
 
-Expected<OwningBinary<Binary>> createBinary(StringRef Path,
-                                            LLVMContext *Context = nullptr,
-                                          ...
[truncated]

@andrurogerz
Copy link
Contributor Author

@compnerd, @vgvassilev here's another one that's ready for review

@compnerd compnerd merged commit ecbe2e8 into llvm:main Jun 4, 2025
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants