From 7c62193524beacaa2052dda5f0516be7f2566d5d Mon Sep 17 00:00:00 2001 From: chriseth Date: Thu, 2 May 2019 21:22:23 +0200 Subject: [PATCH 1/2] Change some AST elements to post visit. --- .../codegen/ir/IRGeneratorForStatements.cpp | 25 ++++--------------- .../codegen/ir/IRGeneratorForStatements.h | 6 ++--- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 3c6d02c87..9c0b14a5f 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -86,7 +86,7 @@ string IRGeneratorForStatements::code() const return m_code.str(); } -bool IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDeclStatement) +void IRGeneratorForStatements::endVisit(VariableDeclarationStatement const& _varDeclStatement) { for (auto const& decl: _varDeclStatement.declarations()) if (decl) @@ -96,8 +96,6 @@ bool IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDec { solUnimplementedAssert(_varDeclStatement.declarations().size() == 1, ""); - expression->accept(*this); - VariableDeclaration const& varDecl = *_varDeclStatement.declarations().front(); m_code << "let " << @@ -110,8 +108,6 @@ bool IRGeneratorForStatements::visit(VariableDeclarationStatement const& _varDec for (auto const& decl: _varDeclStatement.declarations()) if (decl) m_code << "let " << m_context.localVariableName(*decl) << "\n"; - - return false; } bool IRGeneratorForStatements::visit(Assignment const& _assignment) @@ -171,7 +167,7 @@ bool IRGeneratorForStatements::visit(Break const&) return false; } -bool IRGeneratorForStatements::visit(Return const& _return) +void IRGeneratorForStatements::endVisit(Return const& _return) { if (Expression const* value = _return.expression()) { @@ -182,8 +178,6 @@ bool IRGeneratorForStatements::visit(Return const& _return) for (auto const& retVariable: returnParameters) types.push_back(retVariable->annotation().type); - value->accept(*this); - // TODO support tuples solUnimplementedAssert(types.size() == 1, "Multi-returns not implemented."); m_code << @@ -193,7 +187,6 @@ bool IRGeneratorForStatements::visit(Return const& _return) "\n"; } m_code << "return_flag := 0\n" << "break\n"; - return false; } void IRGeneratorForStatements::endVisit(BinaryOperation const& _binOp) @@ -227,7 +220,7 @@ void IRGeneratorForStatements::endVisit(BinaryOperation const& _binOp) } } -bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall) +void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) { solUnimplementedAssert( _functionCall.annotation().kind == FunctionCallKind::FunctionCall || @@ -241,13 +234,12 @@ bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall) { solAssert(funcType->category() == Type::Category::TypeType, "Expected category to be TypeType"); solAssert(_functionCall.arguments().size() == 1, "Expected one argument for type conversion"); - _functionCall.arguments().front()->accept(*this); defineExpression(_functionCall) << expressionAsType(*_functionCall.arguments().front(), *_functionCall.annotation().type) << "\n"; - return false; + return; } FunctionTypePointer functionType = dynamic_cast(funcType); @@ -281,14 +273,10 @@ bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall) { vector args; for (unsigned i = 0; i < arguments.size(); ++i) - { - arguments[i]->accept(*this); - if (functionType->takesArbitraryParameters()) args.emplace_back(m_context.variable(*arguments[i])); else args.emplace_back(expressionAsType(*arguments[i], *parameterTypes[i])); - } if (auto identifier = dynamic_cast(&_functionCall.expression())) { @@ -301,12 +289,10 @@ bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall) "(" << joinHumanReadable(args) << ")\n"; - return false; + return; } } - _functionCall.expression().accept(*this); - // @TODO The function can very well return multiple vars. args = vector{m_context.variable(_functionCall.expression())} + args; defineExpression(_functionCall) << @@ -319,7 +305,6 @@ bool IRGeneratorForStatements::visit(FunctionCall const& _functionCall) default: solUnimplemented(""); } - return false; } bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.h b/libsolidity/codegen/ir/IRGeneratorForStatements.h index 5f196ad7d..4ad86e924 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.h +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.h @@ -45,14 +45,14 @@ public: std::string code() const; - bool visit(VariableDeclarationStatement const& _variableDeclaration) override; + void endVisit(VariableDeclarationStatement const& _variableDeclaration) override; bool visit(Assignment const& _assignment) override; bool visit(ForStatement const& _forStatement) override; bool visit(Continue const& _continueStatement) override; bool visit(Break const& _breakStatement) override; - bool visit(Return const& _return) override; + void endVisit(Return const& _return) override; void endVisit(BinaryOperation const& _binOp) override; - bool visit(FunctionCall const& _funCall) override; + void endVisit(FunctionCall const& _funCall) override; bool visit(InlineAssembly const& _inlineAsm) override; bool visit(Identifier const& _identifier) override; bool visit(Literal const& _literal) override; From 3365cb9b4ab36546a355eb95ae39b66ba5e72dee Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 6 May 2019 11:09:50 +0200 Subject: [PATCH 2/2] Add type helper function. --- .../codegen/ir/IRGeneratorForStatements.cpp | 24 ++++++++++++------- .../codegen/ir/IRGeneratorForStatements.h | 2 ++ 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 9c0b14a5f..8b1f4a4a5 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -116,7 +116,7 @@ bool IRGeneratorForStatements::visit(Assignment const& _assignment) _assignment.rightHandSide().accept(*this); Type const* intermediateType = _assignment.rightHandSide().annotation().type->closestTemporaryType( - _assignment.leftHandSide().annotation().type + &type(_assignment.leftHandSide()) ); string intermediateValue = m_context.newYulVariable(); m_code << "let " << intermediateValue << " := " << expressionAsType(_assignment.rightHandSide(), *intermediateType) << "\n"; @@ -228,21 +228,21 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall) "This type of function call is not yet implemented" ); - TypePointer const funcType = _functionCall.expression().annotation().type; + Type const& funcType = type(_functionCall.expression()); if (_functionCall.annotation().kind == FunctionCallKind::TypeConversion) { - solAssert(funcType->category() == Type::Category::TypeType, "Expected category to be TypeType"); + solAssert(funcType.category() == Type::Category::TypeType, "Expected category to be TypeType"); solAssert(_functionCall.arguments().size() == 1, "Expected one argument for type conversion"); defineExpression(_functionCall) << - expressionAsType(*_functionCall.arguments().front(), *_functionCall.annotation().type) << + expressionAsType(*_functionCall.arguments().front(), type(_functionCall)) << "\n"; return; } - FunctionTypePointer functionType = dynamic_cast(funcType); + FunctionTypePointer functionType = dynamic_cast(&funcType); TypePointers parameterTypes = functionType->parameterTypes(); vector> const& callArguments = _functionCall.arguments(); @@ -347,14 +347,14 @@ bool IRGeneratorForStatements::visit(Identifier const& _identifier) bool IRGeneratorForStatements::visit(Literal const& _literal) { - TypePointer type = _literal.annotation().type; + Type const& literalType = type(_literal); - switch (type->category()) + switch (literalType.category()) { case Type::Category::RationalNumber: case Type::Category::Bool: case Type::Category::Address: - defineExpression(_literal) << toCompactHexWithPrefix(type->literalValue(&_literal)) << "\n"; + defineExpression(_literal) << toCompactHexWithPrefix(literalType.literalValue(&_literal)) << "\n"; break; case Type::Category::StringLiteral: solUnimplemented(""); @@ -367,7 +367,7 @@ bool IRGeneratorForStatements::visit(Literal const& _literal) string IRGeneratorForStatements::expressionAsType(Expression const& _expression, Type const& _to) { - Type const& from = *_expression.annotation().type; + Type const& from = type(_expression); string varName = m_context.variable(_expression); if (from == _to) @@ -391,3 +391,9 @@ void IRGeneratorForStatements::setLValue(Expression const& _expression, unique_p else defineExpression(_expression) << _lvalue->retrieveValue() << "\n"; } + +Type const& IRGeneratorForStatements::type(Expression const& _expression) +{ + solAssert(_expression.annotation().type, "Type of expression not set."); + return *_expression.annotation().type; +} diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.h b/libsolidity/codegen/ir/IRGeneratorForStatements.h index 4ad86e924..f68e9042f 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.h +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.h @@ -65,6 +65,8 @@ private: void setLValue(Expression const& _expression, std::unique_ptr _lvalue); + static Type const& type(Expression const& _expression); + std::ostringstream m_code; IRGenerationContext& m_context; YulUtilFunctions& m_utils;