1353940Sdim//===-- TapiUniversal.h - Text-based Dynamic Library Stub -------*- C++ -*-===//
2353940Sdim//
3353940Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353940Sdim// See https://llvm.org/LICENSE.txt for license information.
5353940Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6353940Sdim//
7353940Sdim//===----------------------------------------------------------------------===//
8353940Sdim//
9353940Sdim// This file declares the TapiUniversal interface.
10353940Sdim//
11353940Sdim//===----------------------------------------------------------------------===//
12353940Sdim
13353940Sdim#ifndef LLVM_OBJECT_TAPI_UNIVERSAL_H
14353940Sdim#define LLVM_OBJECT_TAPI_UNIVERSAL_H
15353940Sdim
16353940Sdim#include "llvm/Object/Binary.h"
17353940Sdim#include "llvm/Object/TapiFile.h"
18353940Sdim#include "llvm/Support/Error.h"
19353940Sdim#include "llvm/Support/MemoryBuffer.h"
20353940Sdim#include "llvm/TextAPI/MachO/Architecture.h"
21353940Sdim#include "llvm/TextAPI/MachO/InterfaceFile.h"
22353940Sdim
23353940Sdimnamespace llvm {
24353940Sdimnamespace object {
25353940Sdim
26353940Sdimclass TapiUniversal : public Binary {
27353940Sdimpublic:
28353940Sdim  class ObjectForArch {
29353940Sdim    const TapiUniversal *Parent;
30353940Sdim    int Index;
31353940Sdim
32353940Sdim  public:
33353940Sdim    ObjectForArch(const TapiUniversal *Parent, int Index)
34353940Sdim        : Parent(Parent), Index(Index) {}
35353940Sdim
36353940Sdim    ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
37353940Sdim
38353940Sdim    bool operator==(const ObjectForArch &Other) const {
39353940Sdim      return (Parent == Other.Parent) && (Index == Other.Index);
40353940Sdim    }
41353940Sdim
42353940Sdim    uint32_t getCPUType() const {
43353940Sdim      auto Result =
44353940Sdim          MachO::getCPUTypeFromArchitecture(Parent->Architectures[Index]);
45353940Sdim      return Result.first;
46353940Sdim    }
47353940Sdim
48353940Sdim    uint32_t getCPUSubType() const {
49353940Sdim      auto Result =
50353940Sdim          MachO::getCPUTypeFromArchitecture(Parent->Architectures[Index]);
51353940Sdim      return Result.second;
52353940Sdim    }
53353940Sdim
54353940Sdim    std::string getArchFlagName() const {
55353940Sdim      return MachO::getArchitectureName(Parent->Architectures[Index]);
56353940Sdim    }
57353940Sdim
58353940Sdim    Expected<std::unique_ptr<TapiFile>> getAsObjectFile() const;
59353940Sdim  };
60353940Sdim
61353940Sdim  class object_iterator {
62353940Sdim    ObjectForArch Obj;
63353940Sdim
64353940Sdim  public:
65353940Sdim    object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
66353940Sdim    const ObjectForArch *operator->() const { return &Obj; }
67353940Sdim    const ObjectForArch &operator*() const { return Obj; }
68353940Sdim
69353940Sdim    bool operator==(const object_iterator &Other) const {
70353940Sdim      return Obj == Other.Obj;
71353940Sdim    }
72353940Sdim    bool operator!=(const object_iterator &Other) const {
73353940Sdim      return !(*this == Other);
74353940Sdim    }
75353940Sdim
76353940Sdim    object_iterator &operator++() { // Preincrement
77353940Sdim      Obj = Obj.getNext();
78353940Sdim      return *this;
79353940Sdim    }
80353940Sdim  };
81353940Sdim
82353940Sdim  TapiUniversal(MemoryBufferRef Source, Error &Err);
83353940Sdim  static Expected<std::unique_ptr<TapiUniversal>>
84353940Sdim  create(MemoryBufferRef Source);
85353940Sdim  ~TapiUniversal() override;
86353940Sdim
87353940Sdim  object_iterator begin_objects() const { return ObjectForArch(this, 0); }
88353940Sdim  object_iterator end_objects() const {
89353940Sdim    return ObjectForArch(this, Architectures.size());
90353940Sdim  }
91353940Sdim
92353940Sdim  iterator_range<object_iterator> objects() const {
93353940Sdim    return make_range(begin_objects(), end_objects());
94353940Sdim  }
95353940Sdim
96353940Sdim  uint32_t getNumberOfObjects() const { return Architectures.size(); }
97353940Sdim
98353940Sdim  // Cast methods.
99353940Sdim  static bool classof(const Binary *v) { return v->isTapiUniversal(); }
100353940Sdim
101353940Sdimprivate:
102353940Sdim  std::unique_ptr<MachO::InterfaceFile> ParsedFile;
103353940Sdim  std::vector<MachO::Architecture> Architectures;
104353940Sdim};
105353940Sdim
106353940Sdim} // end namespace object.
107353940Sdim} // end namespace llvm.
108353940Sdim
109353940Sdim#endif // LLVM_OBJECT_TAPI_UNIVERSAL_H
110