mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Split external type into ecoding and interface type.
This commit is contained in:
parent
d2332769d3
commit
9cc7402c95
@ -280,15 +280,13 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool
|
|||||||
|
|
||||||
// Retain the offset pointer as base_offset, the point from which the data offsets are computed.
|
// Retain the offset pointer as base_offset, the point from which the data offsets are computed.
|
||||||
m_context << eth::Instruction::DUP1;
|
m_context << eth::Instruction::DUP1;
|
||||||
for (TypePointer const& type: _typeParameters)
|
for (TypePointer const& parameterType: _typeParameters)
|
||||||
{
|
{
|
||||||
// stack: v1 v2 ... v(k-1) base_offset current_offset
|
// stack: v1 v2 ... v(k-1) base_offset current_offset
|
||||||
switch (type->category())
|
TypePointer type = parameterType->encodingType();
|
||||||
{
|
if (type->category() == Type::Category::Array)
|
||||||
case Type::Category::Array:
|
|
||||||
{
|
{
|
||||||
auto const& arrayType = dynamic_cast<ArrayType const&>(*type);
|
auto const& arrayType = dynamic_cast<ArrayType const&>(*type);
|
||||||
solAssert(arrayType.location() != DataLocation::Storage, "");
|
|
||||||
solAssert(!arrayType.baseType()->isDynamicallySized(), "Nested arrays not yet implemented.");
|
solAssert(!arrayType.baseType()->isDynamicallySized(), "Nested arrays not yet implemented.");
|
||||||
if (_fromMemory)
|
if (_fromMemory)
|
||||||
{
|
{
|
||||||
@ -344,7 +342,8 @@ void Compiler::appendCalldataUnpacker(TypePointers const& _typeParameters, bool
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
else
|
||||||
|
{
|
||||||
solAssert(!type->isDynamicallySized(), "Unknown dynamically sized type: " + type->toString());
|
solAssert(!type->isDynamicallySized(), "Unknown dynamically sized type: " + type->toString());
|
||||||
CompilerUtils(m_context).loadFromMemoryDynamic(*type, !_fromMemory, true);
|
CompilerUtils(m_context).loadFromMemoryDynamic(*type, !_fromMemory, true);
|
||||||
CompilerUtils(m_context).moveToStackTop(1 + type->sizeOnStack());
|
CompilerUtils(m_context).moveToStackTop(1 + type->sizeOnStack());
|
||||||
|
@ -160,7 +160,7 @@ void CompilerUtils::encodeToMemory(
|
|||||||
TypePointers targetTypes = _targetTypes.empty() ? _givenTypes : _targetTypes;
|
TypePointers targetTypes = _targetTypes.empty() ? _givenTypes : _targetTypes;
|
||||||
solAssert(targetTypes.size() == _givenTypes.size(), "");
|
solAssert(targetTypes.size() == _givenTypes.size(), "");
|
||||||
for (TypePointer& t: targetTypes)
|
for (TypePointer& t: targetTypes)
|
||||||
t = t->mobileType()->externalType();
|
t = t->mobileType()->encodingType();
|
||||||
|
|
||||||
// Stack during operation:
|
// Stack during operation:
|
||||||
// <v1> <v2> ... <vn> <mem_start> <dyn_head_1> ... <dyn_head_r> <end_of_mem>
|
// <v1> <v2> ... <vn> <mem_start> <dyn_head_1> ... <dyn_head_r> <end_of_mem>
|
||||||
|
@ -57,7 +57,7 @@ string InterfaceHandler::abiInterface(ContractDefinition const& _contractDef)
|
|||||||
|
|
||||||
for (auto it: _contractDef.interfaceFunctions())
|
for (auto it: _contractDef.interfaceFunctions())
|
||||||
{
|
{
|
||||||
auto externalFunctionType = it.second->externalFunctionType();
|
auto externalFunctionType = it.second->interfaceFunctionType();
|
||||||
Json::Value method;
|
Json::Value method;
|
||||||
method["type"] = "function";
|
method["type"] = "function";
|
||||||
method["name"] = it.second->declaration().name();
|
method["name"] = it.second->declaration().name();
|
||||||
@ -76,7 +76,7 @@ string InterfaceHandler::abiInterface(ContractDefinition const& _contractDef)
|
|||||||
{
|
{
|
||||||
Json::Value method;
|
Json::Value method;
|
||||||
method["type"] = "constructor";
|
method["type"] = "constructor";
|
||||||
auto externalFunction = FunctionType(*_contractDef.constructor()).externalFunctionType();
|
auto externalFunction = FunctionType(*_contractDef.constructor()).interfaceFunctionType();
|
||||||
solAssert(!!externalFunction, "");
|
solAssert(!!externalFunction, "");
|
||||||
method["inputs"] = populateParameters(
|
method["inputs"] = populateParameters(
|
||||||
externalFunction->parameterNames(),
|
externalFunction->parameterNames(),
|
||||||
@ -120,7 +120,7 @@ string InterfaceHandler::ABISolidityInterface(ContractDefinition const& _contrac
|
|||||||
};
|
};
|
||||||
if (_contractDef.constructor())
|
if (_contractDef.constructor())
|
||||||
{
|
{
|
||||||
auto externalFunction = FunctionType(*_contractDef.constructor()).externalFunctionType();
|
auto externalFunction = FunctionType(*_contractDef.constructor()).interfaceFunctionType();
|
||||||
solAssert(!!externalFunction, "");
|
solAssert(!!externalFunction, "");
|
||||||
ret +=
|
ret +=
|
||||||
"function " +
|
"function " +
|
||||||
|
@ -106,9 +106,23 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable)
|
|||||||
// References are forced to calldata for external function parameters (not return)
|
// References are forced to calldata for external function parameters (not return)
|
||||||
// and memory for parameters (also return) of publicly visible functions.
|
// and memory for parameters (also return) of publicly visible functions.
|
||||||
// They default to memory for function parameters and storage for local variables.
|
// They default to memory for function parameters and storage for local variables.
|
||||||
|
// As an exception, "storage" is allowed for library functions.
|
||||||
if (auto ref = dynamic_cast<ReferenceType const*>(type.get()))
|
if (auto ref = dynamic_cast<ReferenceType const*>(type.get()))
|
||||||
{
|
{
|
||||||
|
if (_variable.isCallableParameter())
|
||||||
|
{
|
||||||
|
auto const& contract = dynamic_cast<ContractDefinition const&>(*_variable.scope()->scope());
|
||||||
if (_variable.isExternalCallableParameter())
|
if (_variable.isExternalCallableParameter())
|
||||||
|
{
|
||||||
|
if (contract.isLibrary())
|
||||||
|
{
|
||||||
|
if (loc == Location::Memory)
|
||||||
|
BOOST_THROW_EXCEPTION(_variable.createTypeError(
|
||||||
|
"Location has to be calldata or storage for external "
|
||||||
|
"library functions (remove the \"memory\" keyword)."
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
// force location of external function parameters (not return) to calldata
|
// force location of external function parameters (not return) to calldata
|
||||||
if (loc != Location::Default)
|
if (loc != Location::Default)
|
||||||
@ -116,18 +130,22 @@ void ReferencesResolver::endVisit(VariableDeclaration const& _variable)
|
|||||||
"Location has to be calldata for external functions "
|
"Location has to be calldata for external functions "
|
||||||
"(remove the \"memory\" or \"storage\" keyword)."
|
"(remove the \"memory\" or \"storage\" keyword)."
|
||||||
));
|
));
|
||||||
|
}
|
||||||
|
if (loc == Location::Default)
|
||||||
type = ref->copyForLocation(DataLocation::CallData, true);
|
type = ref->copyForLocation(DataLocation::CallData, true);
|
||||||
}
|
}
|
||||||
else if (_variable.isCallableParameter() && _variable.scope()->isPublic())
|
else if (_variable.isCallableParameter() && _variable.scope()->isPublic())
|
||||||
{
|
{
|
||||||
// force locations of public or external function (return) parameters to memory
|
// force locations of public or external function (return) parameters to memory
|
||||||
if (loc == VariableDeclaration::Location::Storage)
|
if (loc == Location::Storage && !contract.isLibrary())
|
||||||
BOOST_THROW_EXCEPTION(_variable.createTypeError(
|
BOOST_THROW_EXCEPTION(_variable.createTypeError(
|
||||||
"Location has to be memory for publicly visible functions "
|
"Location has to be memory for publicly visible functions "
|
||||||
"(remove the \"storage\" keyword)."
|
"(remove the \"storage\" keyword)."
|
||||||
));
|
));
|
||||||
|
if (loc == Location::Default)
|
||||||
type = ref->copyForLocation(DataLocation::Memory, true);
|
type = ref->copyForLocation(DataLocation::Memory, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (_variable.isConstant())
|
if (_variable.isConstant())
|
||||||
|
@ -397,11 +397,12 @@ bool TypeChecker::visit(StructDefinition const& _struct)
|
|||||||
|
|
||||||
bool TypeChecker::visit(FunctionDefinition const& _function)
|
bool TypeChecker::visit(FunctionDefinition const& _function)
|
||||||
{
|
{
|
||||||
|
bool isLibraryFunction = dynamic_cast<ContractDefinition const&>(*_function.scope()).isLibrary();
|
||||||
for (ASTPointer<VariableDeclaration> const& var: _function.parameters() + _function.returnParameters())
|
for (ASTPointer<VariableDeclaration> const& var: _function.parameters() + _function.returnParameters())
|
||||||
{
|
{
|
||||||
if (!type(*var)->canLiveOutsideStorage())
|
if (!type(*var)->canLiveOutsideStorage())
|
||||||
typeError(*var, "Type is required to live outside storage.");
|
typeError(*var, "Type is required to live outside storage.");
|
||||||
if (_function.visibility() >= FunctionDefinition::Visibility::Public && !(type(*var)->externalType()))
|
if (_function.visibility() >= FunctionDefinition::Visibility::Public && !(type(*var)->interfaceType(isLibraryFunction)))
|
||||||
typeError(*var, "Internal type is not allowed for public and external functions.");
|
typeError(*var, "Internal type is not allowed for public and external functions.");
|
||||||
}
|
}
|
||||||
for (ASTPointer<ModifierInvocation> const& modifier: _function.modifiers())
|
for (ASTPointer<ModifierInvocation> const& modifier: _function.modifiers())
|
||||||
@ -490,7 +491,7 @@ bool TypeChecker::visit(VariableDeclaration const& _variable)
|
|||||||
}
|
}
|
||||||
else if (
|
else if (
|
||||||
_variable.visibility() >= VariableDeclaration::Visibility::Public &&
|
_variable.visibility() >= VariableDeclaration::Visibility::Public &&
|
||||||
!FunctionType(_variable).externalType()
|
!FunctionType(_variable).interfaceFunctionType()
|
||||||
)
|
)
|
||||||
typeError(_variable, "Internal type is not allowed for public state variables.");
|
typeError(_variable, "Internal type is not allowed for public state variables.");
|
||||||
return false;
|
return false;
|
||||||
@ -557,7 +558,7 @@ bool TypeChecker::visit(EventDefinition const& _eventDef)
|
|||||||
typeError(_eventDef, "More than 3 indexed arguments for event.");
|
typeError(_eventDef, "More than 3 indexed arguments for event.");
|
||||||
if (!type(*var)->canLiveOutsideStorage())
|
if (!type(*var)->canLiveOutsideStorage())
|
||||||
typeError(*var, "Type is required to live outside storage.");
|
typeError(*var, "Type is required to live outside storage.");
|
||||||
if (!type(*var)->externalType())
|
if (!type(*var)->interfaceType(false))
|
||||||
typeError(*var, "Internal type is not allowed as event parameter type.");
|
typeError(*var, "Internal type is not allowed as event parameter type.");
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -839,11 +839,22 @@ string ArrayType::toString(bool _short) const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypePointer ArrayType::externalType() const
|
TypePointer ArrayType::encodingType() const
|
||||||
{
|
{
|
||||||
|
if (location() == DataLocation::Storage)
|
||||||
|
return make_shared<IntegerType>(256);
|
||||||
|
else
|
||||||
|
return this->copyForLocation(DataLocation::Memory, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
TypePointer ArrayType::interfaceType(bool _inLibrary) const
|
||||||
|
{
|
||||||
|
if (_inLibrary && location() == DataLocation::Storage)
|
||||||
|
return shared_from_this();
|
||||||
|
|
||||||
if (m_arrayKind != ArrayKind::Ordinary)
|
if (m_arrayKind != ArrayKind::Ordinary)
|
||||||
return this->copyForLocation(DataLocation::Memory, true);
|
return this->copyForLocation(DataLocation::Memory, true);
|
||||||
TypePointer baseExt = m_baseType->externalType();
|
TypePointer baseExt = m_baseType->interfaceType(_inLibrary);
|
||||||
if (!baseExt)
|
if (!baseExt)
|
||||||
return TypePointer();
|
return TypePointer();
|
||||||
if (m_baseType->category() == Category::Array && m_baseType->isDynamicallySized())
|
if (m_baseType->category() == Category::Array && m_baseType->isDynamicallySized())
|
||||||
@ -1059,6 +1070,14 @@ MemberList const& StructType::members() const
|
|||||||
return *m_members;
|
return *m_members;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypePointer StructType::interfaceType(bool _inLibrary) const
|
||||||
|
{
|
||||||
|
if (_inLibrary && location() == DataLocation::Storage)
|
||||||
|
return shared_from_this();
|
||||||
|
else
|
||||||
|
return TypePointer();
|
||||||
|
}
|
||||||
|
|
||||||
TypePointer StructType::copyForLocation(DataLocation _location, bool _isPointer) const
|
TypePointer StructType::copyForLocation(DataLocation _location, bool _isPointer) const
|
||||||
{
|
{
|
||||||
auto copy = make_shared<StructType>(m_struct, _location);
|
auto copy = make_shared<StructType>(m_struct, _location);
|
||||||
@ -1330,21 +1349,25 @@ unsigned FunctionType::sizeOnStack() const
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionTypePointer FunctionType::externalFunctionType() const
|
FunctionTypePointer FunctionType::interfaceFunctionType() const
|
||||||
{
|
{
|
||||||
|
// Note that m_declaration might also be a state variable!
|
||||||
|
solAssert(m_declaration, "Declaration needed to determine interface function type.");
|
||||||
|
bool isLibraryFunction = dynamic_cast<ContractDefinition const&>(*m_declaration->scope()).isLibrary();
|
||||||
|
|
||||||
TypePointers paramTypes;
|
TypePointers paramTypes;
|
||||||
TypePointers retParamTypes;
|
TypePointers retParamTypes;
|
||||||
|
|
||||||
for (auto type: m_parameterTypes)
|
for (auto type: m_parameterTypes)
|
||||||
{
|
{
|
||||||
if (auto ext = type->externalType())
|
if (auto ext = type->interfaceType(isLibraryFunction))
|
||||||
paramTypes.push_back(ext);
|
paramTypes.push_back(ext);
|
||||||
else
|
else
|
||||||
return FunctionTypePointer();
|
return FunctionTypePointer();
|
||||||
}
|
}
|
||||||
for (auto type: m_returnParameterTypes)
|
for (auto type: m_returnParameterTypes)
|
||||||
{
|
{
|
||||||
if (auto ext = type->externalType())
|
if (auto ext = type->interfaceType(isLibraryFunction))
|
||||||
retParamTypes.push_back(ext);
|
retParamTypes.push_back(ext);
|
||||||
else
|
else
|
||||||
return FunctionTypePointer();
|
return FunctionTypePointer();
|
||||||
@ -1462,7 +1485,7 @@ string FunctionType::externalSignature(std::string const& _name) const
|
|||||||
}
|
}
|
||||||
string ret = funcName + "(";
|
string ret = funcName + "(";
|
||||||
|
|
||||||
FunctionTypePointer external = externalFunctionType();
|
FunctionTypePointer external = interfaceFunctionType();
|
||||||
solAssert(!!external, "External function type requested.");
|
solAssert(!!external, "External function type requested.");
|
||||||
TypePointers externalParameterTypes = external->parameterTypes();
|
TypePointers externalParameterTypes = external->parameterTypes();
|
||||||
for (auto it = externalParameterTypes.cbegin(); it != externalParameterTypes.cend(); ++it)
|
for (auto it = externalParameterTypes.cbegin(); it != externalParameterTypes.cend(); ++it)
|
||||||
|
@ -226,9 +226,16 @@ public:
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @returns a type suitable for outside of Solidity, i.e. for contract types it returns address.
|
/// @returns a (simpler) type that is encoded in the same way for external function calls.
|
||||||
|
/// This for example returns address for contract types.
|
||||||
/// If there is no such type, returns an empty shared pointer.
|
/// If there is no such type, returns an empty shared pointer.
|
||||||
virtual TypePointer externalType() const { return TypePointer(); }
|
virtual TypePointer encodingType() const { return TypePointer(); }
|
||||||
|
/// @returns a type that will be used outside of Solidity for e.g. function signatures.
|
||||||
|
/// This for example returns address for contract types.
|
||||||
|
/// If there is no such type, returns an empty shared pointer.
|
||||||
|
/// @param _inLibrary if set, returns types as used in a library, e.g. struct and contract types
|
||||||
|
/// are returned without modification.
|
||||||
|
virtual TypePointer interfaceType(bool /*_inLibrary*/) const { return TypePointer(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Convenience object used when returning an empty member list.
|
/// Convenience object used when returning an empty member list.
|
||||||
@ -264,7 +271,8 @@ public:
|
|||||||
|
|
||||||
virtual std::string toString(bool _short) const override;
|
virtual std::string toString(bool _short) const override;
|
||||||
|
|
||||||
virtual TypePointer externalType() const override { return shared_from_this(); }
|
virtual TypePointer encodingType() const override { return shared_from_this(); }
|
||||||
|
virtual TypePointer interfaceType(bool) const override { return shared_from_this(); }
|
||||||
|
|
||||||
int numBits() const { return m_bits; }
|
int numBits() const { return m_bits; }
|
||||||
bool isAddress() const { return m_modifier == Modifier::Address; }
|
bool isAddress() const { return m_modifier == Modifier::Address; }
|
||||||
@ -369,7 +377,8 @@ public:
|
|||||||
virtual bool isValueType() const override { return true; }
|
virtual bool isValueType() const override { return true; }
|
||||||
|
|
||||||
virtual std::string toString(bool) const override { return "bytes" + dev::toString(m_bytes); }
|
virtual std::string toString(bool) const override { return "bytes" + dev::toString(m_bytes); }
|
||||||
virtual TypePointer externalType() const override { return shared_from_this(); }
|
virtual TypePointer encodingType() const override { return shared_from_this(); }
|
||||||
|
virtual TypePointer interfaceType(bool) const override { return shared_from_this(); }
|
||||||
|
|
||||||
int numBytes() const { return m_bytes; }
|
int numBytes() const { return m_bytes; }
|
||||||
|
|
||||||
@ -395,7 +404,8 @@ public:
|
|||||||
|
|
||||||
virtual std::string toString(bool) const override { return "bool"; }
|
virtual std::string toString(bool) const override { return "bool"; }
|
||||||
virtual u256 literalValue(Literal const* _literal) const override;
|
virtual u256 literalValue(Literal const* _literal) const override;
|
||||||
virtual TypePointer externalType() const override { return shared_from_this(); }
|
virtual TypePointer encodingType() const override { return shared_from_this(); }
|
||||||
|
virtual TypePointer interfaceType(bool) const override { return shared_from_this(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -493,7 +503,8 @@ public:
|
|||||||
{
|
{
|
||||||
return isString() ? EmptyMemberList : s_arrayTypeMemberList;
|
return isString() ? EmptyMemberList : s_arrayTypeMemberList;
|
||||||
}
|
}
|
||||||
virtual TypePointer externalType() const override;
|
virtual TypePointer encodingType() const override;
|
||||||
|
virtual TypePointer interfaceType(bool _inLibrary) const override;
|
||||||
|
|
||||||
/// @returns true if this is a byte array or a string
|
/// @returns true if this is a byte array or a string
|
||||||
bool isByteArray() const { return m_arrayKind != ArrayKind::Ordinary; }
|
bool isByteArray() const { return m_arrayKind != ArrayKind::Ordinary; }
|
||||||
@ -534,7 +545,7 @@ public:
|
|||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual unsigned calldataEncodedSize(bool _padded ) const override
|
virtual unsigned calldataEncodedSize(bool _padded ) const override
|
||||||
{
|
{
|
||||||
return externalType()->calldataEncodedSize(_padded);
|
return encodingType()->calldataEncodedSize(_padded);
|
||||||
}
|
}
|
||||||
virtual unsigned storageBytes() const override { return 20; }
|
virtual unsigned storageBytes() const override { return 20; }
|
||||||
virtual bool canLiveOutsideStorage() const override { return true; }
|
virtual bool canLiveOutsideStorage() const override { return true; }
|
||||||
@ -542,10 +553,14 @@ public:
|
|||||||
virtual std::string toString(bool _short) const override;
|
virtual std::string toString(bool _short) const override;
|
||||||
|
|
||||||
virtual MemberList const& members() const override;
|
virtual MemberList const& members() const override;
|
||||||
virtual TypePointer externalType() const override
|
virtual TypePointer encodingType() const override
|
||||||
{
|
{
|
||||||
return std::make_shared<IntegerType>(160, IntegerType::Modifier::Address);
|
return std::make_shared<IntegerType>(160, IntegerType::Modifier::Address);
|
||||||
}
|
}
|
||||||
|
virtual TypePointer interfaceType(bool _inLibrary) const override
|
||||||
|
{
|
||||||
|
return _inLibrary ? shared_from_this() : encodingType();
|
||||||
|
}
|
||||||
|
|
||||||
bool isSuper() const { return m_super; }
|
bool isSuper() const { return m_super; }
|
||||||
ContractDefinition const& contractDefinition() const { return m_contract; }
|
ContractDefinition const& contractDefinition() const { return m_contract; }
|
||||||
@ -566,7 +581,7 @@ private:
|
|||||||
ContractDefinition const& m_contract;
|
ContractDefinition const& m_contract;
|
||||||
/// If true, it is the "super" type of the current contract, i.e. it contains only inherited
|
/// If true, it is the "super" type of the current contract, i.e. it contains only inherited
|
||||||
/// members.
|
/// members.
|
||||||
bool m_super;
|
bool m_super = false;
|
||||||
/// Type of the constructor, @see constructorType. Lazily initialized.
|
/// Type of the constructor, @see constructorType. Lazily initialized.
|
||||||
mutable FunctionTypePointer m_constructorType;
|
mutable FunctionTypePointer m_constructorType;
|
||||||
/// List of member types, will be lazy-initialized because of recursive references.
|
/// List of member types, will be lazy-initialized because of recursive references.
|
||||||
@ -591,6 +606,11 @@ public:
|
|||||||
virtual std::string toString(bool _short) const override;
|
virtual std::string toString(bool _short) const override;
|
||||||
|
|
||||||
virtual MemberList const& members() const override;
|
virtual MemberList const& members() const override;
|
||||||
|
virtual TypePointer encodingType() const override
|
||||||
|
{
|
||||||
|
return location() == DataLocation::Storage ? std::make_shared<IntegerType>(256) : TypePointer();
|
||||||
|
}
|
||||||
|
virtual TypePointer interfaceType(bool _inLibrary) const override;
|
||||||
|
|
||||||
TypePointer copyForLocation(DataLocation _location, bool _isPointer) const override;
|
TypePointer copyForLocation(DataLocation _location, bool _isPointer) const override;
|
||||||
|
|
||||||
@ -624,7 +644,7 @@ public:
|
|||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual unsigned calldataEncodedSize(bool _padded) const override
|
virtual unsigned calldataEncodedSize(bool _padded) const override
|
||||||
{
|
{
|
||||||
return externalType()->calldataEncodedSize(_padded);
|
return encodingType()->calldataEncodedSize(_padded);
|
||||||
}
|
}
|
||||||
virtual unsigned storageBytes() const override;
|
virtual unsigned storageBytes() const override;
|
||||||
virtual bool canLiveOutsideStorage() const override { return true; }
|
virtual bool canLiveOutsideStorage() const override { return true; }
|
||||||
@ -632,10 +652,14 @@ public:
|
|||||||
virtual bool isValueType() const override { return true; }
|
virtual bool isValueType() const override { return true; }
|
||||||
|
|
||||||
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
|
||||||
virtual TypePointer externalType() const override
|
virtual TypePointer encodingType() const override
|
||||||
{
|
{
|
||||||
return std::make_shared<IntegerType>(8 * int(storageBytes()));
|
return std::make_shared<IntegerType>(8 * int(storageBytes()));
|
||||||
}
|
}
|
||||||
|
virtual TypePointer interfaceType(bool _inLibrary) const override
|
||||||
|
{
|
||||||
|
return _inLibrary ? shared_from_this() : encodingType();
|
||||||
|
}
|
||||||
|
|
||||||
EnumDefinition const& enumDefinition() const { return m_enum; }
|
EnumDefinition const& enumDefinition() const { return m_enum; }
|
||||||
/// @returns the value that the string has in the Enum
|
/// @returns the value that the string has in the Enum
|
||||||
@ -684,13 +708,6 @@ public:
|
|||||||
|
|
||||||
virtual Category category() const override { return Category::Function; }
|
virtual Category category() const override { return Category::Function; }
|
||||||
|
|
||||||
/// @returns TypePointer of a new FunctionType object. All input/return parameters are an
|
|
||||||
/// appropriate external types of input/return parameters of current function.
|
|
||||||
/// Returns an empty shared pointer if one of the input/return parameters does not have an
|
|
||||||
/// external type.
|
|
||||||
FunctionTypePointer externalFunctionType() const;
|
|
||||||
virtual TypePointer externalType() const override { return externalFunctionType(); }
|
|
||||||
|
|
||||||
/// Creates the type of a function.
|
/// Creates the type of a function.
|
||||||
explicit FunctionType(FunctionDefinition const& _function, bool _isInternal = true);
|
explicit FunctionType(FunctionDefinition const& _function, bool _isInternal = true);
|
||||||
/// Creates the accessor function type of a state variable.
|
/// Creates the accessor function type of a state variable.
|
||||||
@ -749,6 +766,13 @@ public:
|
|||||||
virtual unsigned sizeOnStack() const override;
|
virtual unsigned sizeOnStack() const override;
|
||||||
virtual MemberList const& members() const override;
|
virtual MemberList const& members() const override;
|
||||||
|
|
||||||
|
/// @returns TypePointer of a new FunctionType object. All input/return parameters are an
|
||||||
|
/// appropriate external types (i.e. the interfaceType()s) of input/return parameters of
|
||||||
|
/// current function.
|
||||||
|
/// Returns an empty shared pointer if one of the input/return parameters does not have an
|
||||||
|
/// external type.
|
||||||
|
FunctionTypePointer interfaceFunctionType() const;
|
||||||
|
|
||||||
/// @returns true if this function can take the given argument types (possibly
|
/// @returns true if this function can take the given argument types (possibly
|
||||||
/// after implicit conversion).
|
/// after implicit conversion).
|
||||||
bool canTakeArguments(TypePointers const& _arguments) const;
|
bool canTakeArguments(TypePointers const& _arguments) const;
|
||||||
@ -823,6 +847,14 @@ public:
|
|||||||
virtual bool operator==(Type const& _other) const override;
|
virtual bool operator==(Type const& _other) const override;
|
||||||
virtual std::string toString(bool _short) const override;
|
virtual std::string toString(bool _short) const override;
|
||||||
virtual bool canLiveOutsideStorage() const override { return false; }
|
virtual bool canLiveOutsideStorage() const override { return false; }
|
||||||
|
virtual TypePointer encodingType() const override
|
||||||
|
{
|
||||||
|
return std::make_shared<IntegerType>(256);
|
||||||
|
}
|
||||||
|
virtual TypePointer interfaceType(bool _inLibrary) const override
|
||||||
|
{
|
||||||
|
return _inLibrary ? shared_from_this() : TypePointer();
|
||||||
|
}
|
||||||
|
|
||||||
TypePointer const& keyType() const { return m_keyType; }
|
TypePointer const& keyType() const { return m_keyType; }
|
||||||
TypePointer const& valueType() const { return m_valueType; }
|
TypePointer const& valueType() const { return m_valueType; }
|
||||||
|
Loading…
Reference in New Issue
Block a user