ArchitectureSet.h 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. #pragma once
  2. #ifdef __GNUC__
  3. #pragma GCC diagnostic push
  4. #pragma GCC diagnostic ignored "-Wunused-parameter"
  5. #endif
  6. //===- llvm/TextAPI/ArchitectureSet.h - ArchitectureSet ---------*- C++ -*-===//
  7. //
  8. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  9. // See https://llvm.org/LICENSE.txt for license information.
  10. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  11. //
  12. //===----------------------------------------------------------------------===//
  13. //
  14. // Defines the architecture set.
  15. //
  16. //===----------------------------------------------------------------------===//
  17. #ifndef LLVM_TEXTAPI_ARCHITECTURESET_H
  18. #define LLVM_TEXTAPI_ARCHITECTURESET_H
  19. #include "llvm/TextAPI/Architecture.h"
  20. #include <cstddef>
  21. #include <iterator>
  22. #include <limits>
  23. #include <string>
  24. #include <tuple>
  25. #include <vector>
  26. namespace llvm {
  27. class raw_ostream;
  28. namespace MachO {
  29. class ArchitectureSet {
  30. private:
  31. using ArchSetType = uint32_t;
  32. const static ArchSetType EndIndexVal =
  33. std::numeric_limits<ArchSetType>::max();
  34. ArchSetType ArchSet{0};
  35. public:
  36. constexpr ArchitectureSet() = default;
  37. constexpr ArchitectureSet(ArchSetType Raw) : ArchSet(Raw) {}
  38. ArchitectureSet(Architecture Arch) : ArchitectureSet() { set(Arch); }
  39. ArchitectureSet(const std::vector<Architecture> &Archs);
  40. void set(Architecture Arch) {
  41. if (Arch == AK_unknown)
  42. return;
  43. ArchSet |= 1U << static_cast<int>(Arch);
  44. }
  45. void clear(Architecture Arch) { ArchSet &= ~(1U << static_cast<int>(Arch)); }
  46. bool has(Architecture Arch) const {
  47. return ArchSet & (1U << static_cast<int>(Arch));
  48. }
  49. bool contains(ArchitectureSet Archs) const {
  50. return (ArchSet & Archs.ArchSet) == Archs.ArchSet;
  51. }
  52. size_t count() const;
  53. bool empty() const { return ArchSet == 0; }
  54. ArchSetType rawValue() const { return ArchSet; }
  55. bool hasX86() const {
  56. return has(AK_i386) || has(AK_x86_64) || has(AK_x86_64h);
  57. }
  58. template <typename Ty> class arch_iterator {
  59. public:
  60. using iterator_category = std::forward_iterator_tag;
  61. using value_type = Architecture;
  62. using difference_type = std::size_t;
  63. using pointer = value_type *;
  64. using reference = value_type &;
  65. private:
  66. ArchSetType Index;
  67. Ty *ArchSet;
  68. void findNextSetBit() {
  69. if (Index == EndIndexVal)
  70. return;
  71. while (++Index < sizeof(Ty) * 8) {
  72. if (*ArchSet & (1UL << Index))
  73. return;
  74. }
  75. Index = EndIndexVal;
  76. }
  77. public:
  78. arch_iterator(Ty *ArchSet, ArchSetType Index = 0)
  79. : Index(Index), ArchSet(ArchSet) {
  80. if (Index != EndIndexVal && !(*ArchSet & (1UL << Index)))
  81. findNextSetBit();
  82. }
  83. Architecture operator*() const { return static_cast<Architecture>(Index); }
  84. arch_iterator &operator++() {
  85. findNextSetBit();
  86. return *this;
  87. }
  88. arch_iterator operator++(int) {
  89. auto tmp = *this;
  90. findNextSetBit();
  91. return tmp;
  92. }
  93. bool operator==(const arch_iterator &o) const {
  94. return std::tie(Index, ArchSet) == std::tie(o.Index, o.ArchSet);
  95. }
  96. bool operator!=(const arch_iterator &o) const { return !(*this == o); }
  97. };
  98. ArchitectureSet operator&(const ArchitectureSet &o) {
  99. return {ArchSet & o.ArchSet};
  100. }
  101. ArchitectureSet operator|(const ArchitectureSet &o) {
  102. return {ArchSet | o.ArchSet};
  103. }
  104. ArchitectureSet &operator|=(const ArchitectureSet &o) {
  105. ArchSet |= o.ArchSet;
  106. return *this;
  107. }
  108. ArchitectureSet &operator|=(const Architecture &Arch) {
  109. set(Arch);
  110. return *this;
  111. }
  112. bool operator==(const ArchitectureSet &o) const {
  113. return ArchSet == o.ArchSet;
  114. }
  115. bool operator!=(const ArchitectureSet &o) const {
  116. return ArchSet != o.ArchSet;
  117. }
  118. bool operator<(const ArchitectureSet &o) const { return ArchSet < o.ArchSet; }
  119. using iterator = arch_iterator<ArchSetType>;
  120. using const_iterator = arch_iterator<const ArchSetType>;
  121. iterator begin() { return {&ArchSet}; }
  122. iterator end() { return {&ArchSet, EndIndexVal}; }
  123. const_iterator begin() const { return {&ArchSet}; }
  124. const_iterator end() const { return {&ArchSet, EndIndexVal}; }
  125. operator std::string() const;
  126. operator std::vector<Architecture>() const;
  127. void print(raw_ostream &OS) const;
  128. };
  129. inline ArchitectureSet operator|(const Architecture &lhs,
  130. const Architecture &rhs) {
  131. return ArchitectureSet(lhs) | ArchitectureSet(rhs);
  132. }
  133. raw_ostream &operator<<(raw_ostream &OS, ArchitectureSet Set);
  134. } // end namespace MachO.
  135. } // end namespace llvm.
  136. #endif // LLVM_TEXTAPI_ARCHITECTURESET_H
  137. #ifdef __GNUC__
  138. #pragma GCC diagnostic pop
  139. #endif