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