1 //===-- TapiUniversal.h - Text-based Dynamic Library Stub -------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file declares the TapiUniversal interface.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #ifndef LLVM_OBJECT_TAPI_UNIVERSAL_H
14 #define LLVM_OBJECT_TAPI_UNIVERSAL_H
15 
16 #include "llvm/Object/Binary.h"
17 #include "llvm/Object/TapiFile.h"
18 #include "llvm/Support/Error.h"
19 #include "llvm/Support/MemoryBuffer.h"
20 #include "llvm/TextAPI/MachO/Architecture.h"
21 #include "llvm/TextAPI/MachO/InterfaceFile.h"
22 
23 namespace llvm {
24 namespace object {
25 
26 class TapiUniversal : public Binary {
27 public:
28   class ObjectForArch {
29     const TapiUniversal *Parent;
30     int Index;
31 
32   public:
33     ObjectForArch(const TapiUniversal *Parent, int Index)
34         : Parent(Parent), Index(Index) {}
35 
36     ObjectForArch getNext() const { return ObjectForArch(Parent, Index + 1); }
37 
38     bool operator==(const ObjectForArch &Other) const {
39       return (Parent == Other.Parent) && (Index == Other.Index);
40     }
41 
42     uint32_t getCPUType() const {
43       auto Result =
44           MachO::getCPUTypeFromArchitecture(Parent->Architectures[Index]);
45       return Result.first;
46     }
47 
48     uint32_t getCPUSubType() const {
49       auto Result =
50           MachO::getCPUTypeFromArchitecture(Parent->Architectures[Index]);
51       return Result.second;
52     }
53 
54     std::string getArchFlagName() const {
55       return MachO::getArchitectureName(Parent->Architectures[Index]);
56     }
57 
58     Expected<std::unique_ptr<TapiFile>> getAsObjectFile() const;
59   };
60 
61   class object_iterator {
62     ObjectForArch Obj;
63 
64   public:
65     object_iterator(const ObjectForArch &Obj) : Obj(Obj) {}
66     const ObjectForArch *operator->() const { return &Obj; }
67     const ObjectForArch &operator*() const { return Obj; }
68 
69     bool operator==(const object_iterator &Other) const {
70       return Obj == Other.Obj;
71     }
72     bool operator!=(const object_iterator &Other) const {
73       return !(*this == Other);
74     }
75 
76     object_iterator &operator++() { // Preincrement
77       Obj = Obj.getNext();
78       return *this;
79     }
80   };
81 
82   TapiUniversal(MemoryBufferRef Source, Error &Err);
83   static Expected<std::unique_ptr<TapiUniversal>>
84   create(MemoryBufferRef Source);
85   ~TapiUniversal() override;
86 
87   object_iterator begin_objects() const { return ObjectForArch(this, 0); }
88   object_iterator end_objects() const {
89     return ObjectForArch(this, Architectures.size());
90   }
91 
92   iterator_range<object_iterator> objects() const {
93     return make_range(begin_objects(), end_objects());
94   }
95 
96   uint32_t getNumberOfObjects() const { return Architectures.size(); }
97 
98   // Cast methods.
99   static bool classof(const Binary *v) { return v->isTapiUniversal(); }
100 
101 private:
102   std::unique_ptr<MachO::InterfaceFile> ParsedFile;
103   std::vector<MachO::Architecture> Architectures;
104 };
105 
106 } // end namespace object.
107 } // end namespace llvm.
108 
109 #endif // LLVM_OBJECT_TAPI_UNIVERSAL_H
110