mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Define stack slot names in types.
This commit is contained in:
parent
e786650bef
commit
6abe0a50b1
@ -151,6 +151,8 @@ util::Result<TypePointers> transformParametersToExternal(TypePointers const& _pa
|
|||||||
void Type::clearCache() const
|
void Type::clearCache() const
|
||||||
{
|
{
|
||||||
m_members.clear();
|
m_members.clear();
|
||||||
|
m_stackSlots.reset();
|
||||||
|
m_stackSize.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StorageOffsets::computeOffsets(TypePointers const& _types)
|
void StorageOffsets::computeOffsets(TypePointers const& _types)
|
||||||
@ -1701,15 +1703,14 @@ u256 ArrayType::storageSize() const
|
|||||||
return max<u256>(1, u256(size));
|
return max<u256>(1, u256(size));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned ArrayType::sizeOnStack() const
|
vector<tuple<string, TypePointer>> ArrayType::makeStackSlots() const
|
||||||
{
|
{
|
||||||
if (m_location == DataLocation::CallData)
|
if (m_location == DataLocation::CallData && isDynamicallySized())
|
||||||
// offset [length] (stack top)
|
return {std::make_tuple("offset", TypeProvider::uint256()), std::make_tuple("length", TypeProvider::uint256())};
|
||||||
return 1 + (isDynamicallySized() ? 1 : 0);
|
|
||||||
else
|
else
|
||||||
// storage slot or memory offset
|
// storage slot or memory offset
|
||||||
// byte offset inside storage value is omitted
|
// byte offset inside storage value is omitted
|
||||||
return 1;
|
return {std::make_tuple(string(), nullptr)};
|
||||||
}
|
}
|
||||||
|
|
||||||
string ArrayType::toString(bool _short) const
|
string ArrayType::toString(bool _short) const
|
||||||
@ -1891,6 +1892,11 @@ string ArraySliceType::toString(bool _short) const
|
|||||||
return m_arrayType.toString(_short) + " slice";
|
return m_arrayType.toString(_short) + " slice";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<std::tuple<std::string, TypePointer>> ArraySliceType::makeStackSlots() const
|
||||||
|
{
|
||||||
|
return {{"offset", TypeProvider::uint256()}, {"length", TypeProvider::uint256()}};
|
||||||
|
}
|
||||||
|
|
||||||
string ContractType::richIdentifier() const
|
string ContractType::richIdentifier() const
|
||||||
{
|
{
|
||||||
return (m_super ? "t_super" : "t_contract") + parenthesizeUserIdentifier(m_contract.name()) + to_string(m_contract.id());
|
return (m_super ? "t_super" : "t_contract") + parenthesizeUserIdentifier(m_contract.name()) + to_string(m_contract.id());
|
||||||
@ -1989,6 +1995,14 @@ vector<tuple<VariableDeclaration const*, u256, unsigned>> ContractType::stateVar
|
|||||||
return variablesAndOffsets;
|
return variablesAndOffsets;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
vector<tuple<string, TypePointer>> ContractType::makeStackSlots() const
|
||||||
|
{
|
||||||
|
if (m_super)
|
||||||
|
return {};
|
||||||
|
else
|
||||||
|
return {make_tuple("address", isPayable() ? TypeProvider::payableAddress() :TypeProvider::address())};
|
||||||
|
}
|
||||||
|
|
||||||
void StructType::clearCache() const
|
void StructType::clearCache() const
|
||||||
{
|
{
|
||||||
Type::clearCache();
|
Type::clearCache();
|
||||||
@ -2422,12 +2436,17 @@ u256 TupleType::storageSize() const
|
|||||||
solAssert(false, "Storage size of non-storable tuple type requested.");
|
solAssert(false, "Storage size of non-storable tuple type requested.");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned TupleType::sizeOnStack() const
|
vector<tuple<string, TypePointer>> TupleType::makeStackSlots() const
|
||||||
{
|
{
|
||||||
unsigned size = 0;
|
vector<tuple<string, TypePointer>> slots;
|
||||||
|
unsigned i = 1;
|
||||||
for (auto const& t: components())
|
for (auto const& t: components())
|
||||||
size += t ? t->sizeOnStack() : 0;
|
{
|
||||||
return size;
|
if (t)
|
||||||
|
slots.emplace_back("component_" + std::to_string(i), t);
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return slots;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer TupleType::mobileType() const
|
TypePointer TupleType::mobileType() const
|
||||||
@ -2883,8 +2902,9 @@ unsigned FunctionType::storageBytes() const
|
|||||||
solAssert(false, "Storage size of non-storable function type requested.");
|
solAssert(false, "Storage size of non-storable function type requested.");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned FunctionType::sizeOnStack() const
|
vector<tuple<string, TypePointer>> FunctionType::makeStackSlots() const
|
||||||
{
|
{
|
||||||
|
vector<tuple<string, TypePointer>> slots;
|
||||||
Kind kind = m_kind;
|
Kind kind = m_kind;
|
||||||
if (m_kind == Kind::SetGas || m_kind == Kind::SetValue)
|
if (m_kind == Kind::SetGas || m_kind == Kind::SetValue)
|
||||||
{
|
{
|
||||||
@ -2892,39 +2912,42 @@ unsigned FunctionType::sizeOnStack() const
|
|||||||
kind = dynamic_cast<FunctionType const&>(*m_returnParameterTypes.front()).m_kind;
|
kind = dynamic_cast<FunctionType const&>(*m_returnParameterTypes.front()).m_kind;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned size = 0;
|
|
||||||
|
|
||||||
switch (kind)
|
switch (kind)
|
||||||
{
|
{
|
||||||
case Kind::External:
|
case Kind::External:
|
||||||
case Kind::DelegateCall:
|
case Kind::DelegateCall:
|
||||||
size = 2;
|
slots = {make_tuple("address", TypeProvider::address()), make_tuple("functionIdentifier", TypeProvider::fixedBytes(4))};
|
||||||
break;
|
break;
|
||||||
case Kind::BareCall:
|
case Kind::BareCall:
|
||||||
case Kind::BareCallCode:
|
case Kind::BareCallCode:
|
||||||
case Kind::BareDelegateCall:
|
case Kind::BareDelegateCall:
|
||||||
case Kind::BareStaticCall:
|
case Kind::BareStaticCall:
|
||||||
|
case Kind::Transfer:
|
||||||
|
case Kind::Send:
|
||||||
|
slots = {make_tuple("address", TypeProvider::address())};
|
||||||
|
break;
|
||||||
case Kind::Internal:
|
case Kind::Internal:
|
||||||
|
slots = {make_tuple(string(), nullptr)};
|
||||||
|
break;
|
||||||
case Kind::ArrayPush:
|
case Kind::ArrayPush:
|
||||||
case Kind::ArrayPop:
|
case Kind::ArrayPop:
|
||||||
case Kind::ByteArrayPush:
|
case Kind::ByteArrayPush:
|
||||||
case Kind::Transfer:
|
slots = {make_tuple(string(), nullptr)};
|
||||||
case Kind::Send:
|
|
||||||
size = 1;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_gasSet)
|
if (m_gasSet)
|
||||||
size++;
|
slots.emplace_back("gas", TypeProvider::uint256());
|
||||||
if (m_valueSet)
|
if (m_valueSet)
|
||||||
size++;
|
slots.emplace_back("value", TypeProvider::uint256());
|
||||||
if (m_saltSet)
|
if (m_saltSet)
|
||||||
size++;
|
slots.emplace_back("salt", TypeProvider::uint256());
|
||||||
if (bound())
|
if (bound())
|
||||||
size += m_parameterTypes.front()->sizeOnStack();
|
for (auto const& [boundName, boundType]: m_parameterTypes.front()->stackSlots())
|
||||||
return size;
|
slots.emplace_back("self_" + boundName, boundType);
|
||||||
|
return slots;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionTypePointer FunctionType::interfaceFunctionType() const
|
FunctionTypePointer FunctionType::interfaceFunctionType() const
|
||||||
@ -3418,12 +3441,12 @@ u256 TypeType::storageSize() const
|
|||||||
solAssert(false, "Storage size of non-storable type type requested.");
|
solAssert(false, "Storage size of non-storable type type requested.");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned TypeType::sizeOnStack() const
|
vector<tuple<string, TypePointer>> TypeType::makeStackSlots() const
|
||||||
{
|
{
|
||||||
if (auto contractType = dynamic_cast<ContractType const*>(m_actualType))
|
if (auto contractType = dynamic_cast<ContractType const*>(m_actualType))
|
||||||
if (contractType->contractDefinition().isLibrary())
|
if (contractType->contractDefinition().isLibrary())
|
||||||
return 1;
|
return {make_tuple("address", TypeProvider::address())};
|
||||||
return 0;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
MemberList::MemberMap TypeType::nativeMembers(ContractDefinition const* _currentScope) const
|
MemberList::MemberMap TypeType::nativeMembers(ContractDefinition const* _currentScope) const
|
||||||
|
@ -259,7 +259,26 @@ public:
|
|||||||
/// Returns true if the type can be stored as a value (as opposed to a reference) on the stack,
|
/// Returns true if the type can be stored as a value (as opposed to a reference) on the stack,
|
||||||
/// i.e. it behaves differently in lvalue context and in value context.
|
/// i.e. it behaves differently in lvalue context and in value context.
|
||||||
virtual bool isValueType() const { return false; }
|
virtual bool isValueType() const { return false; }
|
||||||
virtual unsigned sizeOnStack() const { return 1; }
|
std::vector<std::tuple<std::string, TypePointer>> const& stackSlots() const
|
||||||
|
{
|
||||||
|
if (!m_stackSlots)
|
||||||
|
m_stackSlots = makeStackSlots();
|
||||||
|
return *m_stackSlots;
|
||||||
|
}
|
||||||
|
unsigned sizeOnStack() const
|
||||||
|
{
|
||||||
|
if (!m_stackSize)
|
||||||
|
{
|
||||||
|
size_t sizeOnStack = 0;
|
||||||
|
for (auto const& slot: stackSlots())
|
||||||
|
if (std::get<1>(slot))
|
||||||
|
sizeOnStack += std::get<1>(slot)->sizeOnStack();
|
||||||
|
else
|
||||||
|
++sizeOnStack;
|
||||||
|
m_stackSize = sizeOnStack;
|
||||||
|
}
|
||||||
|
return *m_stackSize;
|
||||||
|
}
|
||||||
/// If it is possible to initialize such a value in memory by just writing zeros
|
/// If it is possible to initialize such a value in memory by just writing zeros
|
||||||
/// of the size memoryHeadSize().
|
/// of the size memoryHeadSize().
|
||||||
virtual bool hasSimpleZeroValueInMemory() const { return true; }
|
virtual bool hasSimpleZeroValueInMemory() const { return true; }
|
||||||
@ -336,9 +355,16 @@ protected:
|
|||||||
{
|
{
|
||||||
return MemberList::MemberMap();
|
return MemberList::MemberMap();
|
||||||
}
|
}
|
||||||
|
virtual std::vector<std::tuple<std::string, TypePointer>> makeStackSlots() const
|
||||||
|
{
|
||||||
|
return {std::make_tuple(std::string(), nullptr)};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// List of member types (parameterised by scape), will be lazy-initialized.
|
/// List of member types (parameterised by scape), will be lazy-initialized.
|
||||||
mutable std::map<ContractDefinition const*, std::unique_ptr<MemberList>> m_members;
|
mutable std::map<ContractDefinition const*, std::unique_ptr<MemberList>> m_members;
|
||||||
|
mutable std::optional<std::vector<std::tuple<std::string, TypePointer>>> m_stackSlots;
|
||||||
|
mutable std::optional<size_t> m_stackSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -562,7 +588,6 @@ public:
|
|||||||
|
|
||||||
bool canBeStored() const override { return false; }
|
bool canBeStored() const override { return false; }
|
||||||
bool canLiveOutsideStorage() const override { return false; }
|
bool canLiveOutsideStorage() const override { return false; }
|
||||||
unsigned sizeOnStack() const override { return 0; }
|
|
||||||
|
|
||||||
std::string toString(bool) const override;
|
std::string toString(bool) const override;
|
||||||
TypePointer mobileType() const override;
|
TypePointer mobileType() const override;
|
||||||
@ -571,6 +596,8 @@ public:
|
|||||||
|
|
||||||
std::string const& value() const { return m_value; }
|
std::string const& value() const { return m_value; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<std::tuple<std::string, TypePointer>> makeStackSlots() const override { return {}; }
|
||||||
private:
|
private:
|
||||||
std::string m_value;
|
std::string m_value;
|
||||||
};
|
};
|
||||||
@ -725,7 +752,6 @@ public:
|
|||||||
bool isDynamicallyEncoded() const override;
|
bool isDynamicallyEncoded() const override;
|
||||||
u256 storageSize() const override;
|
u256 storageSize() const override;
|
||||||
bool canLiveOutsideStorage() const override { return m_baseType->canLiveOutsideStorage(); }
|
bool canLiveOutsideStorage() const override { return m_baseType->canLiveOutsideStorage(); }
|
||||||
unsigned sizeOnStack() const override;
|
|
||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
std::string canonicalName() const override;
|
std::string canonicalName() const override;
|
||||||
std::string signatureInExternalFunction(bool _structsByName) const override;
|
std::string signatureInExternalFunction(bool _structsByName) const override;
|
||||||
@ -756,6 +782,8 @@ public:
|
|||||||
|
|
||||||
void clearCache() const override;
|
void clearCache() const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<std::tuple<std::string, TypePointer>> makeStackSlots() const override;
|
||||||
private:
|
private:
|
||||||
/// String is interpreted as a subtype of Bytes.
|
/// String is interpreted as a subtype of Bytes.
|
||||||
enum class ArrayKind { Ordinary, Bytes, String };
|
enum class ArrayKind { Ordinary, Bytes, String };
|
||||||
@ -785,7 +813,6 @@ public:
|
|||||||
bool isDynamicallySized() const override { return true; }
|
bool isDynamicallySized() const override { return true; }
|
||||||
bool isDynamicallyEncoded() const override { return true; }
|
bool isDynamicallyEncoded() const override { return true; }
|
||||||
bool canLiveOutsideStorage() const override { return m_arrayType.canLiveOutsideStorage(); }
|
bool canLiveOutsideStorage() const override { return m_arrayType.canLiveOutsideStorage(); }
|
||||||
unsigned sizeOnStack() const override { return 2; }
|
|
||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
|
|
||||||
/// @returns true if this is valid to be stored in calldata
|
/// @returns true if this is valid to be stored in calldata
|
||||||
@ -796,6 +823,8 @@ public:
|
|||||||
|
|
||||||
std::unique_ptr<ReferenceType> copyForLocation(DataLocation, bool) const override { solAssert(false, ""); }
|
std::unique_ptr<ReferenceType> copyForLocation(DataLocation, bool) const override { solAssert(false, ""); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<std::tuple<std::string, TypePointer>> makeStackSlots() const override;
|
||||||
private:
|
private:
|
||||||
ArrayType const& m_arrayType;
|
ArrayType const& m_arrayType;
|
||||||
};
|
};
|
||||||
@ -825,7 +854,6 @@ public:
|
|||||||
unsigned storageBytes() const override { solAssert(!isSuper(), ""); return 20; }
|
unsigned storageBytes() const override { solAssert(!isSuper(), ""); return 20; }
|
||||||
bool leftAligned() const override { solAssert(!isSuper(), ""); return false; }
|
bool leftAligned() const override { solAssert(!isSuper(), ""); return false; }
|
||||||
bool canLiveOutsideStorage() const override { return !isSuper(); }
|
bool canLiveOutsideStorage() const override { return !isSuper(); }
|
||||||
unsigned sizeOnStack() const override { return m_super ? 0 : 1; }
|
|
||||||
bool isValueType() const override { return !isSuper(); }
|
bool isValueType() const override { return !isSuper(); }
|
||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
std::string canonicalName() const override;
|
std::string canonicalName() const override;
|
||||||
@ -856,7 +884,8 @@ public:
|
|||||||
/// @returns a list of all state variables (including inherited) of the contract and their
|
/// @returns a list of all state variables (including inherited) of the contract and their
|
||||||
/// offsets in storage.
|
/// offsets in storage.
|
||||||
std::vector<std::tuple<VariableDeclaration const*, u256, unsigned>> stateVariables() const;
|
std::vector<std::tuple<VariableDeclaration const*, u256, unsigned>> stateVariables() const;
|
||||||
|
protected:
|
||||||
|
std::vector<std::tuple<std::string, TypePointer>> makeStackSlots() const override;
|
||||||
private:
|
private:
|
||||||
ContractDefinition const& m_contract;
|
ContractDefinition const& m_contract;
|
||||||
/// If true, this is a special "super" type of m_contract containing only members that m_contract inherited
|
/// If true, this is a special "super" type of m_contract containing only members that m_contract inherited
|
||||||
@ -989,7 +1018,6 @@ public:
|
|||||||
bool canBeStored() const override { return false; }
|
bool canBeStored() const override { return false; }
|
||||||
u256 storageSize() const override;
|
u256 storageSize() const override;
|
||||||
bool canLiveOutsideStorage() const override { return false; }
|
bool canLiveOutsideStorage() const override { return false; }
|
||||||
unsigned sizeOnStack() const override;
|
|
||||||
bool hasSimpleZeroValueInMemory() const override { return false; }
|
bool hasSimpleZeroValueInMemory() const override { return false; }
|
||||||
TypePointer mobileType() const override;
|
TypePointer mobileType() const override;
|
||||||
/// Converts components to their temporary types and performs some wildcard matching.
|
/// Converts components to their temporary types and performs some wildcard matching.
|
||||||
@ -997,6 +1025,8 @@ public:
|
|||||||
|
|
||||||
std::vector<TypePointer> const& components() const { return m_components; }
|
std::vector<TypePointer> const& components() const { return m_components; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<std::tuple<std::string, TypePointer>> makeStackSlots() const override;
|
||||||
private:
|
private:
|
||||||
std::vector<TypePointer> const m_components;
|
std::vector<TypePointer> const m_components;
|
||||||
};
|
};
|
||||||
@ -1158,7 +1188,6 @@ public:
|
|||||||
unsigned storageBytes() const override;
|
unsigned storageBytes() const override;
|
||||||
bool isValueType() const override { return true; }
|
bool isValueType() const override { return true; }
|
||||||
bool canLiveOutsideStorage() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
|
bool canLiveOutsideStorage() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
|
||||||
unsigned sizeOnStack() const override;
|
|
||||||
bool hasSimpleZeroValueInMemory() const override { return false; }
|
bool hasSimpleZeroValueInMemory() const override { return false; }
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
|
MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
|
||||||
TypePointer encodingType() const override;
|
TypePointer encodingType() const override;
|
||||||
@ -1252,6 +1281,8 @@ public:
|
|||||||
/// @param _bound if true, the function type is set to be bound.
|
/// @param _bound if true, the function type is set to be bound.
|
||||||
FunctionTypePointer asCallableFunction(bool _inLibrary, bool _bound = false) const;
|
FunctionTypePointer asCallableFunction(bool _inLibrary, bool _bound = false) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<std::tuple<std::string, TypePointer>> makeStackSlots() const override;
|
||||||
private:
|
private:
|
||||||
static TypePointers parseElementaryTypeVector(strings const& _types);
|
static TypePointers parseElementaryTypeVector(strings const& _types);
|
||||||
|
|
||||||
@ -1321,12 +1352,13 @@ public:
|
|||||||
bool canBeStored() const override { return false; }
|
bool canBeStored() const override { return false; }
|
||||||
u256 storageSize() const override;
|
u256 storageSize() const override;
|
||||||
bool canLiveOutsideStorage() const override { return false; }
|
bool canLiveOutsideStorage() const override { return false; }
|
||||||
unsigned sizeOnStack() const override;
|
|
||||||
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
||||||
std::string toString(bool _short) const override { return "type(" + m_actualType->toString(_short) + ")"; }
|
std::string toString(bool _short) const override { return "type(" + m_actualType->toString(_short) + ")"; }
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
|
MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
|
||||||
|
|
||||||
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
|
protected:
|
||||||
|
std::vector<std::tuple<std::string, TypePointer>> makeStackSlots() const override;
|
||||||
private:
|
private:
|
||||||
TypePointer m_actualType;
|
TypePointer m_actualType;
|
||||||
};
|
};
|
||||||
@ -1346,12 +1378,13 @@ public:
|
|||||||
bool canBeStored() const override { return false; }
|
bool canBeStored() const override { return false; }
|
||||||
u256 storageSize() const override;
|
u256 storageSize() const override;
|
||||||
bool canLiveOutsideStorage() const override { return false; }
|
bool canLiveOutsideStorage() const override { return false; }
|
||||||
unsigned sizeOnStack() const override { return 0; }
|
|
||||||
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
||||||
std::string richIdentifier() const override;
|
std::string richIdentifier() const override;
|
||||||
bool operator==(Type const& _other) const override;
|
bool operator==(Type const& _other) const override;
|
||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<std::tuple<std::string, TypePointer>> makeStackSlots() const override { return {}; }
|
||||||
private:
|
private:
|
||||||
TypePointers m_parameterTypes;
|
TypePointers m_parameterTypes;
|
||||||
};
|
};
|
||||||
@ -1374,11 +1407,12 @@ public:
|
|||||||
bool canBeStored() const override { return false; }
|
bool canBeStored() const override { return false; }
|
||||||
bool canLiveOutsideStorage() const override { return true; }
|
bool canLiveOutsideStorage() const override { return true; }
|
||||||
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
||||||
unsigned sizeOnStack() const override { return 0; }
|
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
|
MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
|
||||||
|
|
||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<std::tuple<std::string, TypePointer>> makeStackSlots() const override { return {}; }
|
||||||
private:
|
private:
|
||||||
SourceUnit const& m_sourceUnit;
|
SourceUnit const& m_sourceUnit;
|
||||||
};
|
};
|
||||||
@ -1413,7 +1447,6 @@ public:
|
|||||||
bool canBeStored() const override { return false; }
|
bool canBeStored() const override { return false; }
|
||||||
bool canLiveOutsideStorage() const override { return true; }
|
bool canLiveOutsideStorage() const override { return true; }
|
||||||
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
||||||
unsigned sizeOnStack() const override { return 0; }
|
|
||||||
MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
|
MemberList::MemberMap nativeMembers(ContractDefinition const*) const override;
|
||||||
|
|
||||||
std::string toString(bool _short) const override;
|
std::string toString(bool _short) const override;
|
||||||
@ -1422,6 +1455,8 @@ public:
|
|||||||
|
|
||||||
TypePointer typeArgument() const;
|
TypePointer typeArgument() const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::vector<std::tuple<std::string, TypePointer>> makeStackSlots() const override { return {}; }
|
||||||
private:
|
private:
|
||||||
Kind m_kind;
|
Kind m_kind;
|
||||||
/// Contract type used for contract metadata magic.
|
/// Contract type used for contract metadata magic.
|
||||||
@ -1445,7 +1480,6 @@ public:
|
|||||||
bool canBeStored() const override { return false; }
|
bool canBeStored() const override { return false; }
|
||||||
bool canLiveOutsideStorage() const override { return false; }
|
bool canLiveOutsideStorage() const override { return false; }
|
||||||
bool isValueType() const override { return true; }
|
bool isValueType() const override { return true; }
|
||||||
unsigned sizeOnStack() const override { return 1; }
|
|
||||||
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
|
||||||
std::string toString(bool) const override { return "inaccessible dynamic type"; }
|
std::string toString(bool) const override { return "inaccessible dynamic type"; }
|
||||||
TypePointer decodingType() const override;
|
TypePointer decodingType() const override;
|
||||||
|
Loading…
Reference in New Issue
Block a user