diff --git a/kernel/rtlil.cc b/kernel/rtlil.cc index 4175a008d..9863fc4e9 100644 --- a/kernel/rtlil.cc +++ b/kernel/rtlil.cc @@ -204,12 +204,22 @@ const pool &RTLIL::builtin_ff_cell_types() { #define check(condition) log_assert(condition && "malformed Const union") -Const::bitvectype& Const::get_bits() const { +const Const::bitvectype& Const::get_bits() const { check(is_bits()); return *get_if_bits(); } -std::string& Const::get_str() const { +const std::string& Const::get_str() const { + check(is_str()); + return *get_if_str(); +} + +Const::bitvectype& Const::get_bits() { + check(is_bits()); + return *get_if_bits(); +} + +std::string& Const::get_str() { check(is_str()); return *get_if_str(); } @@ -395,7 +405,7 @@ bool RTLIL::Const::as_bool() const return false; } - bitvectype& bv = get_bits(); + const bitvectype& bv = get_bits(); for (size_t i = 0; i < bv.size(); i++) if (bv[i] == State::S1) return true; @@ -542,7 +552,7 @@ std::string RTLIL::Const::decode_string() const if (auto str = get_if_str()) return *str; - bitvectype& bv = get_bits(); + const bitvectype& bv = get_bits(); const int n = GetSize(bv); const int n_over_8 = n / 8; std::string s; @@ -590,7 +600,7 @@ bool RTLIL::Const::empty() const { } } -void RTLIL::Const::bitvectorize_internal() const { +void RTLIL::Const::bitvectorize_internal() { if (tag == backing_tag::bits) return; @@ -641,7 +651,7 @@ bool RTLIL::Const::is_fully_zero() const return true; } - bitvectype& bv = get_bits(); + const bitvectype& bv = get_bits(); for (const auto &bit : bv) if (bit != RTLIL::State::S0) @@ -661,7 +671,7 @@ bool RTLIL::Const::is_fully_ones() const return true; } - bitvectype& bv = get_bits(); + const bitvectype& bv = get_bits(); for (const auto &bit : bv) if (bit != RTLIL::State::S1) return false; @@ -676,7 +686,7 @@ bool RTLIL::Const::is_fully_def() const if (is_str()) return true; - bitvectype& bv = get_bits(); + const bitvectype& bv = get_bits(); for (const auto &bit : bv) if (bit != RTLIL::State::S0 && bit != RTLIL::State::S1) return false; @@ -691,7 +701,7 @@ bool RTLIL::Const::is_fully_undef() const if (auto str = get_if_str()) return str->empty(); - bitvectype& bv = get_bits(); + const bitvectype& bv = get_bits(); for (const auto &bit : bv) if (bit != RTLIL::State::Sx && bit != RTLIL::State::Sz) return false; @@ -706,7 +716,7 @@ bool RTLIL::Const::is_fully_undef_x_only() const if (auto str = get_if_str()) return str->empty(); - bitvectype& bv = get_bits(); + const bitvectype& bv = get_bits(); for (const auto &bit : bv) if (bit != RTLIL::State::Sx) return false; @@ -742,7 +752,7 @@ Hasher RTLIL::Const::hash_into(Hasher h) const // If the bits are all 0/1, hash packed bits using the string hash. // Otherwise hash the leading packed bits with the rest of the bits individually. - bitvectype &bv = get_bits(); + const bitvectype &bv = get_bits(); int size = GetSize(bv); std::string packed; int packed_size = (size + 7) >> 3; diff --git a/kernel/rtlil.h b/kernel/rtlil.h index d2caf81f7..62a62021e 100644 --- a/kernel/rtlil.h +++ b/kernel/rtlil.h @@ -723,23 +723,27 @@ private: using bitvectype = std::vector; enum class backing_tag: bool { bits, string }; // Do not access the union or tag even in Const methods unless necessary - mutable backing_tag tag; + backing_tag tag; union { - mutable bitvectype bits_; - mutable std::string str_; + bitvectype bits_; + std::string str_; }; // Use these private utilities instead bool is_bits() const { return tag == backing_tag::bits; } bool is_str() const { return tag == backing_tag::string; } - bitvectype* get_if_bits() const { return is_bits() ? &bits_ : NULL; } - std::string* get_if_str() const { return is_str() ? &str_ : NULL; } + bitvectype* get_if_bits() { return is_bits() ? &bits_ : NULL; } + std::string* get_if_str() { return is_str() ? &str_ : NULL; } + const bitvectype* get_if_bits() const { return is_bits() ? &bits_ : NULL; } + const std::string* get_if_str() const { return is_str() ? &str_ : NULL; } - bitvectype& get_bits() const; - std::string& get_str() const; + bitvectype& get_bits(); + std::string& get_str(); + const bitvectype& get_bits() const; + const std::string& get_str() const; std::vector& bits_internal(); - void bitvectorize_internal() const; + void bitvectorize_internal(); public: Const() : flags(RTLIL::CONST_FLAG_NONE), tag(backing_tag::bits), bits_(std::vector()) {} @@ -772,7 +776,7 @@ public: [[deprecated("Don't use direct access to the internal std::vector, that's an implementation detail.")]] std::vector& bits() { return bits_internal(); } [[deprecated("Don't call bitvectorize() directly, it's an implementation detail.")]] - void bitvectorize() const { bitvectorize_internal(); } + void bitvectorize() const { const_cast(this)->bitvectorize_internal(); } bool as_bool() const;