mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Introduce CompositeType
This commit is contained in:
+23
-61
@@ -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
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user