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