blob: c48a4a7023631cf30b45064c4d18c2d985860d60 [file] [log] [blame]
Andrew Walbran3d2c1972020-04-07 12:24:26 +01001//===- llvm/TextAPI/MachO/ArchitectureSet.h - ArchitectureSet ---*- 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// Defines the architecture set.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_TEXTAPI_MACHO_ARCHITECTURE_SET_H
14#define LLVM_TEXTAPI_MACHO_ARCHITECTURE_SET_H
15
Andrew Walbran3d2c1972020-04-07 12:24:26 +010016#include "llvm/TextAPI/MachO/Architecture.h"
17#include <cstddef>
18#include <iterator>
19#include <limits>
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020020#include <string>
21#include <tuple>
Andrew Walbran3d2c1972020-04-07 12:24:26 +010022#include <vector>
23
24namespace llvm {
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020025class raw_ostream;
26
Andrew Walbran3d2c1972020-04-07 12:24:26 +010027namespace MachO {
28
29class ArchitectureSet {
30private:
31 using ArchSetType = uint32_t;
32
33 const static ArchSetType EndIndexVal =
34 std::numeric_limits<ArchSetType>::max();
35 ArchSetType ArchSet{0};
36
37public:
38 constexpr ArchitectureSet() = default;
39 constexpr ArchitectureSet(ArchSetType Raw) : ArchSet(Raw) {}
40 ArchitectureSet(Architecture Arch) : ArchitectureSet() { set(Arch); }
41 ArchitectureSet(const std::vector<Architecture> &Archs);
42
43 void set(Architecture Arch) {
44 if (Arch == AK_unknown)
45 return;
46 ArchSet |= 1U << static_cast<int>(Arch);
47 }
48
49 void clear(Architecture Arch) { ArchSet &= ~(1U << static_cast<int>(Arch)); }
50
51 bool has(Architecture Arch) const {
52 return ArchSet & (1U << static_cast<int>(Arch));
53 }
54
55 bool contains(ArchitectureSet Archs) const {
56 return (ArchSet & Archs.ArchSet) == Archs.ArchSet;
57 }
58
59 size_t count() const;
60
61 bool empty() const { return ArchSet == 0; }
62
63 ArchSetType rawValue() const { return ArchSet; }
64
Olivier Deprezf4ef2d02021-04-20 13:36:24 +020065 bool hasX86() const {
66 return has(AK_i386) || has(AK_x86_64) || has(AK_x86_64h);
67 }
68
Andrew Walbran3d2c1972020-04-07 12:24:26 +010069 template <typename Ty>
70 class arch_iterator
71 : public std::iterator<std::forward_iterator_tag, Architecture, size_t> {
72 private:
73 ArchSetType Index;
74 Ty *ArchSet;
75
76 void findNextSetBit() {
77 if (Index == EndIndexVal)
78 return;
79 while (++Index < sizeof(Ty) * 8) {
80 if (*ArchSet & (1UL << Index))
81 return;
82 }
83
84 Index = EndIndexVal;
85 }
86
87 public:
88 arch_iterator(Ty *ArchSet, ArchSetType Index = 0)
89 : Index(Index), ArchSet(ArchSet) {
90 if (Index != EndIndexVal && !(*ArchSet & (1UL << Index)))
91 findNextSetBit();
92 }
93
94 Architecture operator*() const { return static_cast<Architecture>(Index); }
95
96 arch_iterator &operator++() {
97 findNextSetBit();
98 return *this;
99 }
100
101 arch_iterator operator++(int) {
102 auto tmp = *this;
103 findNextSetBit();
104 return tmp;
105 }
106
107 bool operator==(const arch_iterator &o) const {
108 return std::tie(Index, ArchSet) == std::tie(o.Index, o.ArchSet);
109 }
110
111 bool operator!=(const arch_iterator &o) const { return !(*this == o); }
112 };
113
114 ArchitectureSet operator&(const ArchitectureSet &o) {
115 return {ArchSet & o.ArchSet};
116 }
117
118 ArchitectureSet operator|(const ArchitectureSet &o) {
119 return {ArchSet | o.ArchSet};
120 }
121
122 ArchitectureSet &operator|=(const ArchitectureSet &o) {
123 ArchSet |= o.ArchSet;
124 return *this;
125 }
126
127 ArchitectureSet &operator|=(const Architecture &Arch) {
128 set(Arch);
129 return *this;
130 }
131
132 bool operator==(const ArchitectureSet &o) const {
133 return ArchSet == o.ArchSet;
134 }
135
136 bool operator!=(const ArchitectureSet &o) const {
137 return ArchSet != o.ArchSet;
138 }
139
140 bool operator<(const ArchitectureSet &o) const { return ArchSet < o.ArchSet; }
141
142 using iterator = arch_iterator<ArchSetType>;
143 using const_iterator = arch_iterator<const ArchSetType>;
144
145 iterator begin() { return {&ArchSet}; }
146 iterator end() { return {&ArchSet, EndIndexVal}; }
147
148 const_iterator begin() const { return {&ArchSet}; }
149 const_iterator end() const { return {&ArchSet, EndIndexVal}; }
150
151 operator std::string() const;
152 operator std::vector<Architecture>() const;
153 void print(raw_ostream &OS) const;
154};
155
156inline ArchitectureSet operator|(const Architecture &lhs,
157 const Architecture &rhs) {
158 return ArchitectureSet(lhs) | ArchitectureSet(rhs);
159}
160
161raw_ostream &operator<<(raw_ostream &OS, ArchitectureSet Set);
162
163} // end namespace MachO.
164} // end namespace llvm.
165
166#endif // LLVM_TEXTAPI_MACHO_ARCHITECTURE_SET_H