1259698Sdim//===- MachOUniversal.h - Mach-O universal binaries -------------*- C++ -*-===//
2259698Sdim//
3259698Sdim//                     The LLVM Compiler Infrastructure
4259698Sdim//
5259698Sdim// This file is distributed under the University of Illinois Open Source
6259698Sdim// License. See LICENSE.TXT for details.
7259698Sdim//
8259698Sdim//===----------------------------------------------------------------------===//
9259698Sdim//
10259698Sdim// This file declares Mach-O fat/universal binaries.
11259698Sdim//
12259698Sdim//===----------------------------------------------------------------------===//
13259698Sdim
14259698Sdim#ifndef LLVM_OBJECT_MACHOUNIVERSAL_H
15259698Sdim#define LLVM_OBJECT_MACHOUNIVERSAL_H
16259698Sdim
17259698Sdim#include "llvm/ADT/OwningPtr.h"
18259698Sdim#include "llvm/ADT/StringRef.h"
19259698Sdim#include "llvm/ADT/Triple.h"
20259698Sdim#include "llvm/Object/Binary.h"
21259698Sdim#include "llvm/Support/MachO.h"
22259698Sdim
23259698Sdimnamespace llvm {
24259698Sdimnamespace object {
25259698Sdim
26259698Sdimclass ObjectFile;
27259698Sdim
28259698Sdimclass MachOUniversalBinary : public Binary {
29259698Sdim  virtual void anchor();
30259698Sdim
31259698Sdim  uint32_t NumberOfObjects;
32259698Sdimpublic:
33259698Sdim  class ObjectForArch {
34259698Sdim    const MachOUniversalBinary *Parent;
35259698Sdim    /// \brief Index of object in the universal binary.
36259698Sdim    uint32_t Index;
37259698Sdim    /// \brief Descriptor of the object.
38259698Sdim    MachO::fat_arch Header;
39259698Sdim
40259698Sdim  public:
41259698Sdim    ObjectForArch(const MachOUniversalBinary *Parent, uint32_t Index);
42259698Sdim
43259698Sdim    void clear() {
44259698Sdim      Parent = 0;
45259698Sdim      Index = 0;
46259698Sdim    }
47259698Sdim
48259698Sdim    bool operator==(const ObjectForArch &Other) const {
49259698Sdim      return (Parent == Other.Parent) && (Index == Other.Index);
50259698Sdim    }
51259698Sdim
52259698Sdim    ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
53259698Sdim    uint32_t getCPUType() const { return Header.cputype; }
54259698Sdim
55259698Sdim    error_code getAsObjectFile(OwningPtr<ObjectFile> &Result) const;
56259698Sdim  };
57259698Sdim
58259698Sdim  class object_iterator {
59259698Sdim    ObjectForArch Obj;
60259698Sdim  public:
61259698Sdim    object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
62259698Sdim    const ObjectForArch* operator->() const {
63259698Sdim      return &Obj;
64259698Sdim    }
65259698Sdim
66259698Sdim    bool operator==(const object_iterator &Other) const {
67259698Sdim      return Obj == Other.Obj;
68259698Sdim    }
69259698Sdim    bool operator!=(const object_iterator &Other) const {
70259698Sdim      return !(*this == Other);
71259698Sdim    }
72259698Sdim
73259698Sdim    object_iterator& operator++() {  // Preincrement
74259698Sdim      Obj = Obj.getNext();
75259698Sdim      return *this;
76259698Sdim    }
77259698Sdim  };
78259698Sdim
79259698Sdim  MachOUniversalBinary(MemoryBuffer *Source, error_code &ec);
80259698Sdim
81259698Sdim  object_iterator begin_objects() const {
82259698Sdim    return ObjectForArch(this, 0);
83259698Sdim  }
84259698Sdim  object_iterator end_objects() const {
85259698Sdim    return ObjectForArch(0, 0);
86259698Sdim  }
87259698Sdim
88259698Sdim  uint32_t getNumberOfObjects() const { return NumberOfObjects; }
89259698Sdim
90259698Sdim  // Cast methods.
91259698Sdim  static inline bool classof(Binary const *V) {
92259698Sdim    return V->isMachOUniversalBinary();
93259698Sdim  }
94259698Sdim
95259698Sdim  error_code getObjectForArch(Triple::ArchType Arch,
96259698Sdim                              OwningPtr<ObjectFile> &Result) const;
97259698Sdim};
98259698Sdim
99259698Sdim}
100259698Sdim}
101259698Sdim
102259698Sdim#endif
103