aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/ExpressionCompiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/ExpressionCompiler.cpp')
-rw-r--r--libsolidity/ExpressionCompiler.cpp41
1 files changed, 30 insertions, 11 deletions
diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp
index 85302afc..8109c03b 100644
--- a/libsolidity/ExpressionCompiler.cpp
+++ b/libsolidity/ExpressionCompiler.cpp
@@ -177,20 +177,18 @@ void ExpressionCompiler::appendStateVariableAccessor(VariableDeclaration const&
bool ExpressionCompiler::visit(Assignment const& _assignment)
{
+// cout << "-----Assignment" << endl;
CompilerContext::LocationSetter locationSetter(m_context, _assignment);
_assignment.rightHandSide().accept(*this);
- TypePointer type = _assignment.rightHandSide().annotation().type;
- if (!_assignment.annotation().type->dataStoredIn(DataLocation::Storage))
- {
- utils().convertType(*type, *_assignment.annotation().type);
- type = _assignment.annotation().type;
- }
- else
- {
- utils().convertType(*type, *type->mobileType());
- type = type->mobileType();
- }
+ // Perform some conversion already. This will convert storage types to memory and literals
+ // to their actual type, but will not convert e.g. memory to storage.
+ TypePointer type = _assignment.rightHandSide().annotation().type->closestTemporaryType(
+ _assignment.leftHandSide().annotation().type
+ );
+// cout << "-----Type conversion" << endl;
+ utils().convertType(*_assignment.rightHandSide().annotation().type, *type);
+// cout << "-----LHS" << endl;
_assignment.leftHandSide().accept(*this);
solAssert(!!m_currentLValue, "LValue not retrieved.");
@@ -216,11 +214,32 @@ bool ExpressionCompiler::visit(Assignment const& _assignment)
m_context << eth::swapInstruction(itemSize + lvalueSize) << eth::Instruction::POP;
}
}
+// cout << "-----Store" << endl;
m_currentLValue->storeValue(*type, _assignment.location());
m_currentLValue.reset();
return false;
}
+bool ExpressionCompiler::visit(TupleExpression const& _tuple)
+{
+ vector<unique_ptr<LValue>> lvalues;
+ for (auto const& component: _tuple.components())
+ if (component)
+ {
+ component->accept(*this);
+ if (_tuple.annotation().lValueRequested)
+ {
+ solAssert(!!m_currentLValue, "");
+ lvalues.push_back(move(m_currentLValue));
+ }
+ }
+ else if (_tuple.annotation().lValueRequested)
+ lvalues.push_back(unique_ptr<LValue>());
+ if (_tuple.annotation().lValueRequested)
+ m_currentLValue.reset(new TupleObject(m_context, move(lvalues)));
+ return false;
+}
+
bool ExpressionCompiler::visit(UnaryOperation const& _unaryOperation)
{
CompilerContext::LocationSetter locationSetter(m_context, _unaryOperation);