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; ArchitectureSet(ArchSetType Raw)36 constexpr ArchitectureSet(ArchSetType Raw) : ArchSet(Raw) {} ArchitectureSet(Architecture Arch)37 ArchitectureSet(Architecture Arch) : ArchitectureSet() { set(Arch); } 38 ArchitectureSet(const std::vector<Architecture> &Archs); 39 set(Architecture Arch)40 void set(Architecture Arch) { 41 if (Arch == AK_unknown) 42 return; 43 ArchSet |= 1U << static_cast<int>(Arch); 44 } 45 clear(Architecture Arch)46 void clear(Architecture Arch) { ArchSet &= ~(1U << static_cast<int>(Arch)); } 47 has(Architecture Arch)48 bool has(Architecture Arch) const { 49 return ArchSet & (1U << static_cast<int>(Arch)); 50 } 51 contains(ArchitectureSet Archs)52 bool contains(ArchitectureSet Archs) const { 53 return (ArchSet & Archs.ArchSet) == Archs.ArchSet; 54 } 55 56 size_t count() const; 57 empty()58 bool empty() const { return ArchSet == 0; } 59 rawValue()60 ArchSetType rawValue() const { return ArchSet; } 61 hasX86()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 findNextSetBit()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) Index(Index)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 begin()142 iterator begin() { return {&ArchSet}; } end()143 iterator end() { return {&ArchSet, EndIndexVal}; } 144 begin()145 const_iterator begin() const { return {&ArchSet}; } end()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 164