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 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 65 bool hasX86() const { 66 return has(AK_i386) || has(AK_x86_64) || has(AK_x86_64h); 67 } 68 69 template <typename Ty> class arch_iterator { 70 public: 71 using iterator_category = std::forward_iterator_tag; 72 using value_type = Architecture; 73 using difference_type = std::size_t; 74 using pointer = value_type *; 75 using reference = value_type &; 76 77 private: 78 ArchSetType Index; 79 Ty *ArchSet; 80 81 void findNextSetBit() { 82 if (Index == EndIndexVal) 83 return; 84 while (++Index < sizeof(Ty) * 8) { 85 if (*ArchSet & (1UL << Index)) 86 return; 87 } 88 89 Index = EndIndexVal; 90 } 91 92 public: 93 arch_iterator(Ty *ArchSet, ArchSetType Index = 0) 94 : Index(Index), ArchSet(ArchSet) { 95 if (Index != EndIndexVal && !(*ArchSet & (1UL << Index))) 96 findNextSetBit(); 97 } 98 99 Architecture operator*() const { return static_cast<Architecture>(Index); } 100 101 arch_iterator &operator++() { 102 findNextSetBit(); 103 return *this; 104 } 105 106 arch_iterator operator++(int) { 107 auto tmp = *this; 108 findNextSetBit(); 109 return tmp; 110 } 111 112 bool operator==(const arch_iterator &o) const { 113 return std::tie(Index, ArchSet) == std::tie(o.Index, o.ArchSet); 114 } 115 116 bool operator!=(const arch_iterator &o) const { return !(*this == o); } 117 }; 118 119 ArchitectureSet operator&(const ArchitectureSet &o) { 120 return {ArchSet & o.ArchSet}; 121 } 122 123 ArchitectureSet operator|(const ArchitectureSet &o) { 124 return {ArchSet | o.ArchSet}; 125 } 126 127 ArchitectureSet &operator|=(const ArchitectureSet &o) { 128 ArchSet |= o.ArchSet; 129 return *this; 130 } 131 132 ArchitectureSet &operator|=(const Architecture &Arch) { 133 set(Arch); 134 return *this; 135 } 136 137 bool operator==(const ArchitectureSet &o) const { 138 return ArchSet == o.ArchSet; 139 } 140 141 bool operator!=(const ArchitectureSet &o) const { 142 return ArchSet != o.ArchSet; 143 } 144 145 bool operator<(const ArchitectureSet &o) const { return ArchSet < o.ArchSet; } 146 147 using iterator = arch_iterator<ArchSetType>; 148 using const_iterator = arch_iterator<const ArchSetType>; 149 150 iterator begin() { return {&ArchSet}; } 151 iterator end() { return {&ArchSet, EndIndexVal}; } 152 153 const_iterator begin() const { return {&ArchSet}; } 154 const_iterator end() const { return {&ArchSet, EndIndexVal}; } 155 156 operator std::string() const; 157 operator std::vector<Architecture>() const; 158 void print(raw_ostream &OS) const; 159 }; 160 161 inline ArchitectureSet operator|(const Architecture &lhs, 162 const Architecture &rhs) { 163 return ArchitectureSet(lhs) | ArchitectureSet(rhs); 164 } 165 166 raw_ostream &operator<<(raw_ostream &OS, ArchitectureSet Set); 167 168 } // end namespace MachO. 169 } // end namespace llvm. 170 171 #endif // LLVM_TEXTAPI_ARCHITECTURESET_H 172