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