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_MACHO_ARCHITECTURESET_H 14 #define LLVM_TEXTAPI_MACHO_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> 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 156 inline ArchitectureSet operator|(const Architecture &lhs, 157 const Architecture &rhs) { 158 return ArchitectureSet(lhs) | ArchitectureSet(rhs); 159 } 160 161 raw_ostream &operator<<(raw_ostream &OS, ArchitectureSet Set); 162 163 } // end namespace MachO. 164 } // end namespace llvm. 165 166 #endif // LLVM_TEXTAPI_MACHO_ARCHITECTURESET_H 167