mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Struct constructors.
This commit is contained in:
+52
-24
@@ -313,38 +313,66 @@ bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
using Location = FunctionType::Location;
|
||||
if (_functionCall.isTypeConversion())
|
||||
{
|
||||
//@todo struct construction
|
||||
solAssert(_functionCall.getArguments().size() == 1, "");
|
||||
solAssert(_functionCall.getNames().empty(), "");
|
||||
Expression const& firstArgument = *_functionCall.getArguments().front();
|
||||
firstArgument.accept(*this);
|
||||
utils().convertType(*firstArgument.getType(), *_functionCall.getType());
|
||||
return false;
|
||||
}
|
||||
|
||||
FunctionTypePointer functionType;
|
||||
if (_functionCall.isStructConstructorCall())
|
||||
{
|
||||
TypeType const& type = dynamic_cast<TypeType const&>(*_functionCall.getExpression().getType());
|
||||
auto const& structType = dynamic_cast<StructType const&>(*type.getActualType());
|
||||
functionType = structType.constructorType();
|
||||
}
|
||||
else
|
||||
functionType = dynamic_pointer_cast<FunctionType const>(_functionCall.getExpression().getType());
|
||||
|
||||
TypePointers const& parameterTypes = functionType->getParameterTypes();
|
||||
vector<ASTPointer<Expression const>> const& callArguments = _functionCall.getArguments();
|
||||
vector<ASTPointer<ASTString>> const& callArgumentNames = _functionCall.getNames();
|
||||
if (!functionType->takesArbitraryParameters())
|
||||
solAssert(callArguments.size() == parameterTypes.size(), "");
|
||||
|
||||
vector<ASTPointer<Expression const>> arguments;
|
||||
if (callArgumentNames.empty())
|
||||
// normal arguments
|
||||
arguments = callArguments;
|
||||
else
|
||||
// named arguments
|
||||
for (auto const& parameterName: functionType->getParameterNames())
|
||||
{
|
||||
bool found = false;
|
||||
for (size_t j = 0; j < callArgumentNames.size() && !found; j++)
|
||||
if ((found = (parameterName == *callArgumentNames[j])))
|
||||
// we found the actual parameter position
|
||||
arguments.push_back(callArguments[j]);
|
||||
solAssert(found, "");
|
||||
}
|
||||
|
||||
if (_functionCall.isStructConstructorCall())
|
||||
{
|
||||
TypeType const& type = dynamic_cast<TypeType const&>(*_functionCall.getExpression().getType());
|
||||
auto const& structType = dynamic_cast<StructType const&>(*type.getActualType());
|
||||
|
||||
m_context << u256(max(32u, structType.getCalldataEncodedSize(true)));
|
||||
utils().allocateMemory();
|
||||
m_context << eth::Instruction::DUP1;
|
||||
|
||||
for (unsigned i = 0; i < arguments.size(); ++i)
|
||||
{
|
||||
arguments[i]->accept(*this);
|
||||
utils().convertType(*arguments[i]->getType(), *functionType->getParameterTypes()[i]);
|
||||
utils().storeInMemoryDynamic(*functionType->getParameterTypes()[i]);
|
||||
}
|
||||
m_context << eth::Instruction::POP;
|
||||
}
|
||||
else
|
||||
{
|
||||
FunctionType const& function = dynamic_cast<FunctionType const&>(*_functionCall.getExpression().getType());
|
||||
TypePointers const& parameterTypes = function.getParameterTypes();
|
||||
vector<ASTPointer<Expression const>> const& callArguments = _functionCall.getArguments();
|
||||
vector<ASTPointer<ASTString>> const& callArgumentNames = _functionCall.getNames();
|
||||
if (!function.takesArbitraryParameters())
|
||||
solAssert(callArguments.size() == parameterTypes.size(), "");
|
||||
|
||||
vector<ASTPointer<Expression const>> arguments;
|
||||
if (callArgumentNames.empty())
|
||||
// normal arguments
|
||||
arguments = callArguments;
|
||||
else
|
||||
// named arguments
|
||||
for (auto const& parameterName: function.getParameterNames())
|
||||
{
|
||||
bool found = false;
|
||||
for (size_t j = 0; j < callArgumentNames.size() && !found; j++)
|
||||
if ((found = (parameterName == *callArgumentNames[j])))
|
||||
// we found the actual parameter position
|
||||
arguments.push_back(callArguments[j]);
|
||||
solAssert(found, "");
|
||||
}
|
||||
|
||||
FunctionType const& function = *functionType;
|
||||
switch (function.getLocation())
|
||||
{
|
||||
case Location::Internal:
|
||||
|
||||
Reference in New Issue
Block a user