diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index aa888d26b..4c9ef4776 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -207,26 +207,31 @@ void MemberList::combine(MemberList const & _other) pair const* MemberList::memberStorageOffset(string const& _name) const { - if (!m_storageOffsets) - { - TypePointers memberTypes; - memberTypes.reserve(m_memberTypes.size()); - for (auto const& member: m_memberTypes) - memberTypes.push_back(member.type); - m_storageOffsets = std::make_unique(); - m_storageOffsets->computeOffsets(memberTypes); - } + StorageOffsets const& offsets = storageOffsets(); + for (size_t index = 0; index < m_memberTypes.size(); ++index) if (m_memberTypes[index].name == _name) - return m_storageOffsets->offset(index); + return offsets.offset(index); return nullptr; } u256 const& MemberList::storageSize() const { - // trigger lazy computation - memberStorageOffset(""); - return m_storageOffsets->storageSize(); + return storageOffsets().storageSize(); +} + +StorageOffsets const& MemberList::storageOffsets() const { + return m_storageOffsets.init([&]{ + TypePointers memberTypes; + memberTypes.reserve(m_memberTypes.size()); + for (auto const& member: m_memberTypes) + memberTypes.push_back(member.type); + + StorageOffsets storageOffsets; + storageOffsets.computeOffsets(memberTypes); + + return storageOffsets; + }); } /// Helper functions for type identifier diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index d549d4f24..cdccbc69b 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -139,8 +140,10 @@ public: MemberMap::const_iterator end() const { return m_memberTypes.end(); } private: + StorageOffsets const& storageOffsets() const; + MemberMap m_memberTypes; - mutable std::unique_ptr m_storageOffsets; + util::LazyInit m_storageOffsets; }; static_assert(std::is_nothrow_move_constructible::value, "MemberList should be noexcept move constructible");