diff --git a/libsolidity/ExpressionCompiler.cpp b/libsolidity/ExpressionCompiler.cpp index 6b9b51679..67686df14 100644 --- a/libsolidity/ExpressionCompiler.cpp +++ b/libsolidity/ExpressionCompiler.cpp @@ -1031,30 +1031,19 @@ void ExpressionCompiler::appendExpressionCopyToMemory(Type const& _expectedType, void ExpressionCompiler::setLValueFromDeclaration(Declaration const& _declaration, Expression const& _expression) { - solAssert(!m_currentLValue, "Current LValue not reset when trying to set to new one."); - std::unique_ptr lvalue; if (m_context.isLocalVariable(&_declaration)) - lvalue.reset(new StackVariable(m_context, _declaration)); + setLValue(_expression, _declaration); else if (m_context.isStateVariable(&_declaration)) - lvalue.reset(new StorageItem(m_context, _declaration)); + setLValue(_expression, _declaration); else BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_sourceLocation(_expression.getLocation()) << errinfo_comment("Identifier type not supported or identifier not found.")); - if (_expression.lvalueRequested()) - m_currentLValue = move(lvalue); - else - lvalue->retrieveValue(_expression.getLocation(), true); } void ExpressionCompiler::setLValueToStorageItem(Expression const& _expression) { - solAssert(!m_currentLValue, "Current LValue not reset when trying to set to new one."); - std::unique_ptr lvalue(new StorageItem(m_context, _expression.getType())); - if (_expression.lvalueRequested()) - m_currentLValue = move(lvalue); - else - lvalue->retrieveValue(_expression.getLocation(), true); + setLValue(_expression, _expression.getType()); } } diff --git a/libsolidity/ExpressionCompiler.h b/libsolidity/ExpressionCompiler.h index edb63ad9f..c3ecabbd6 100644 --- a/libsolidity/ExpressionCompiler.h +++ b/libsolidity/ExpressionCompiler.h @@ -120,12 +120,27 @@ private: /// to be on the stack. /// Also retrieves the value if it was not requested by @a _expression. void setLValueToStorageItem(Expression const& _expression); + /// Sets the current LValue to a new LValue constructed from the arguments. + /// Also retrieves the value if it was not requested by @a _expression. + template + void setLValue(Expression const& _expression, _Arguments const&... _arguments); bool m_optimize; CompilerContext& m_context; std::unique_ptr m_currentLValue; }; +template +void ExpressionCompiler::setLValue(Expression const& _expression, _Arguments const&... _arguments) +{ + solAssert(!m_currentLValue, "Current LValue not reset when trying to set to new one."); + std::unique_ptr<_LValueType> lvalue(new _LValueType(m_context, _arguments...)); + if (_expression.lvalueRequested()) + m_currentLValue = move(lvalue); + else + lvalue->retrieveValue(_expression.getLocation(), true); + +} } }