- //===- MachOUniversal.h - Mach-O universal binaries -------------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
- // 
- // This file declares Mach-O fat/universal binaries. 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_OBJECT_MACHOUNIVERSAL_H 
- #define LLVM_OBJECT_MACHOUNIVERSAL_H 
-   
- #include "llvm/ADT/Triple.h" 
- #include "llvm/ADT/iterator_range.h" 
- #include "llvm/BinaryFormat/MachO.h" 
- #include "llvm/Object/Binary.h" 
- #include "llvm/Object/MachO.h" 
-   
- namespace llvm { 
- class StringRef; 
- class LLVMContext; 
-   
- namespace object { 
- class Archive; 
- class IRObjectFile; 
-   
- class MachOUniversalBinary : public Binary { 
-   virtual void anchor(); 
-   
-   uint32_t Magic; 
-   uint32_t NumberOfObjects; 
- public: 
-   static constexpr uint32_t MaxSectionAlignment = 15; /* 2**15 or 0x8000 */ 
-   
-   class ObjectForArch { 
-     const MachOUniversalBinary *Parent; 
-     /// Index of object in the universal binary. 
-     uint32_t Index; 
-     /// Descriptor of the object. 
-     MachO::fat_arch Header; 
-     MachO::fat_arch_64 Header64; 
-   
-   public: 
-     ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index); 
-   
-     void clear() { 
-       Parent = nullptr; 
-       Index = 0; 
-     } 
-   
-     bool operator==(const ObjectForArch &Other) const { 
-       return (Parent == Other.Parent) && (Index == Other.Index); 
-     } 
-   
-     ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); } 
-     uint32_t getCPUType() const { 
-       if (Parent->getMagic() == MachO::FAT_MAGIC) 
-         return Header.cputype; 
-       else // Parent->getMagic() == MachO::FAT_MAGIC_64 
-         return Header64.cputype; 
-     } 
-     uint32_t getCPUSubType() const { 
-       if (Parent->getMagic() == MachO::FAT_MAGIC) 
-         return Header.cpusubtype; 
-       else // Parent->getMagic() == MachO::FAT_MAGIC_64 
-         return Header64.cpusubtype; 
-     } 
-     uint64_t getOffset() const { 
-       if (Parent->getMagic() == MachO::FAT_MAGIC) 
-         return Header.offset; 
-       else // Parent->getMagic() == MachO::FAT_MAGIC_64 
-         return Header64.offset; 
-     } 
-     uint64_t getSize() const { 
-       if (Parent->getMagic() == MachO::FAT_MAGIC) 
-         return Header.size; 
-       else // Parent->getMagic() == MachO::FAT_MAGIC_64 
-         return Header64.size; 
-     } 
-     uint32_t getAlign() const { 
-       if (Parent->getMagic() == MachO::FAT_MAGIC) 
-         return Header.align; 
-       else // Parent->getMagic() == MachO::FAT_MAGIC_64 
-         return Header64.align; 
-     } 
-     uint32_t getReserved() const { 
-       if (Parent->getMagic() == MachO::FAT_MAGIC) 
-         return 0; 
-       else // Parent->getMagic() == MachO::FAT_MAGIC_64 
-         return Header64.reserved; 
-     } 
-     Triple getTriple() const { 
-       return MachOObjectFile::getArchTriple(getCPUType(), getCPUSubType()); 
-     } 
-     std::string getArchFlagName() const { 
-       const char *McpuDefault, *ArchFlag; 
-       MachOObjectFile::getArchTriple(getCPUType(), getCPUSubType(), 
-                                      &McpuDefault, &ArchFlag); 
-       return ArchFlag ? ArchFlag : std::string(); 
-     } 
-   
-     Expected<std::unique_ptr<MachOObjectFile>> getAsObjectFile() const; 
-     Expected<std::unique_ptr<IRObjectFile>> 
-     getAsIRObject(LLVMContext &Ctx) const; 
-   
-     Expected<std::unique_ptr<Archive>> getAsArchive() const; 
-   }; 
-   
-   class object_iterator { 
-     ObjectForArch Obj; 
-   public: 
-     object_iterator(const ObjectForArch &Obj) : Obj(Obj) {} 
-     const ObjectForArch *operator->() const { return &Obj; } 
-     const ObjectForArch &operator*() const { return Obj; } 
-   
-     bool operator==(const object_iterator &Other) const { 
-       return Obj == Other.Obj; 
-     } 
-     bool operator!=(const object_iterator &Other) const { 
-       return !(*this == Other); 
-     } 
-   
-     object_iterator& operator++() {  // Preincrement 
-       Obj = Obj.getNext(); 
-       return *this; 
-     } 
-   }; 
-   
-   MachOUniversalBinary(MemoryBufferRef Souce, Error &Err); 
-   static Expected<std::unique_ptr<MachOUniversalBinary>> 
-   create(MemoryBufferRef Source); 
-   
-   object_iterator begin_objects() const { 
-     return ObjectForArch(this, 0); 
-   } 
-   object_iterator end_objects() const { 
-     return ObjectForArch(nullptr, 0); 
-   } 
-   
-   iterator_range<object_iterator> objects() const { 
-     return make_range(begin_objects(), end_objects()); 
-   } 
-   
-   uint32_t getMagic() const { return Magic; } 
-   uint32_t getNumberOfObjects() const { return NumberOfObjects; } 
-   
-   // Cast methods. 
-   static bool classof(Binary const *V) { 
-     return V->isMachOUniversalBinary(); 
-   } 
-   
-   Expected<ObjectForArch> 
-   getObjectForArch(StringRef ArchName) const; 
-   
-   Expected<std::unique_ptr<MachOObjectFile>> 
-   getMachOObjectForArch(StringRef ArchName) const; 
-   
-   Expected<std::unique_ptr<IRObjectFile>> 
-   getIRObjectForArch(StringRef ArchName, LLVMContext &Ctx) const; 
-   
-   Expected<std::unique_ptr<Archive>> 
-   getArchiveForArch(StringRef ArchName) const; 
- }; 
-   
- } 
- } 
-   
- #endif 
-