Introduce CompositeType

This commit is contained in:
a3d4
2020-09-21 16:18:04 +02:00
parent 306fef334b
commit 6b77a20134
11 changed files with 97 additions and 85 deletions
+23 -61
View File
@@ -44,6 +44,7 @@
#include <boost/range/algorithm/copy.hpp>
#include <limits>
#include <unordered_set>
#include <utility>
using namespace std;
@@ -54,57 +55,6 @@ using namespace solidity::frontend;
namespace
{
struct TypeComp
{
bool operator()(Type const* lhs, Type const* rhs) const
{
solAssert(lhs && rhs, "");
return lhs->richIdentifier() < rhs->richIdentifier();
}
};
using TypeSet = std::set<Type const*, TypeComp>;
void oversizedSubtypesInner(
Type const& _type,
bool _includeType,
set<StructDefinition const*>& _structsSeen,
TypeSet& _oversizedSubtypes
)
{
switch (_type.category())
{
case Type::Category::Array:
{
auto const& t = dynamic_cast<ArrayType const&>(_type);
if (_includeType && t.storageSizeUpperBound() >= bigint(1) << 64)
_oversizedSubtypes.insert(&t);
oversizedSubtypesInner(*t.baseType(), t.isDynamicallySized(), _structsSeen, _oversizedSubtypes);
break;
}
case Type::Category::Struct:
{
auto const& t = dynamic_cast<StructType const&>(_type);
if (_structsSeen.count(&t.structDefinition()))
return;
if (_includeType && t.storageSizeUpperBound() >= bigint(1) << 64)
_oversizedSubtypes.insert(&t);
_structsSeen.insert(&t.structDefinition());
for (auto const& m: t.members(nullptr))
oversizedSubtypesInner(*m.type, false, _structsSeen, _oversizedSubtypes);
_structsSeen.erase(&t.structDefinition());
break;
}
case Type::Category::Mapping:
{
auto const* valueType = dynamic_cast<MappingType const&>(_type).valueType();
oversizedSubtypesInner(*valueType, true, _structsSeen, _oversizedSubtypes);
break;
}
default:
break;
}
}
/// Check whether (_base ** _exp) fits into 4096 bits.
bool fitsPrecisionExp(bigint const& _base, bigint const& _exp)
{
@@ -201,16 +151,6 @@ util::Result<TypePointers> transformParametersToExternal(TypePointers const& _pa
}
vector<frontend::Type const*> solidity::frontend::oversizedSubtypes(frontend::Type const& _type)
{
set<StructDefinition const*> structsSeen;
TypeSet oversized;
oversizedSubtypesInner(_type, true, structsSeen, oversized);
vector<frontend::Type const*> res;
copy(oversized.cbegin(), oversized.cend(), back_inserter(res));
return res;
}
void Type::clearCache() const
{
m_members.clear();
@@ -1612,6 +1552,21 @@ TypeResult ContractType::unaryOperatorResult(Token _operator) const
return nullptr;
}
vector<Type const*> CompositeType::fullDecomposition() const
{
vector<Type const*> res = {this};
unordered_set<string> seen = {richIdentifier()};
for (size_t k = 0; k < res.size(); ++k)
if (auto composite = dynamic_cast<CompositeType const*>(res[k]))
for (Type const* next: composite->decomposition())
if (seen.count(next->richIdentifier()) == 0)
{
seen.insert(next->richIdentifier());
res.push_back(next);
}
return res;
}
Type const* ReferenceType::withLocation(DataLocation _location, bool _isPointer) const
{
return TypeProvider::withLocation(this, _location, _isPointer);
@@ -2649,6 +2604,13 @@ vector<tuple<string, TypePointer>> StructType::makeStackItems() const
solAssert(false, "");
}
vector<Type const*> StructType::decomposition() const
{
vector<Type const*> res;
for (MemberList::Member const& member: members(nullptr))
res.push_back(member.type);
return res;
}
TypePointer EnumType::encodingType() const
{