From 0ae504f883837828c2e6577ec3d2afc9db2c4254 Mon Sep 17 00:00:00 2001 From: Christian Parpart Date: Mon, 9 Nov 2020 14:50:36 +0100 Subject: [PATCH] ConstantEvaluator: WIP: stage-1 commit. splitting up between type and value. --- libsolidity/analysis/ConstantEvaluator.cpp | 58 ++++++++++++++++------ libsolidity/analysis/ConstantEvaluator.h | 12 +++-- 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/libsolidity/analysis/ConstantEvaluator.cpp b/libsolidity/analysis/ConstantEvaluator.cpp index b5655d3a3..e01dc45b2 100644 --- a/libsolidity/analysis/ConstantEvaluator.cpp +++ b/libsolidity/analysis/ConstantEvaluator.cpp @@ -37,15 +37,15 @@ using namespace solidity::langutil; void ConstantEvaluator::endVisit(UnaryOperation const& _operation) { - auto sub = type(_operation.subExpression()); + auto sub = evaluatedValue(_operation.subExpression()); if (sub) - setType(_operation, sub->unaryOperatorResult(_operation.getOperator())); + setValue(_operation, sub->unaryOperatorResult(_operation.getOperator())); } void ConstantEvaluator::endVisit(BinaryOperation const& _operation) { - auto left = type(_operation.leftExpression()); - auto right = type(_operation.rightExpression()); + auto left = evaluatedValue(_operation.leftExpression()); + auto right = evaluatedValue(_operation.rightExpression()); if (left && right) { TypePointer commonType = left->binaryOperatorResult(_operation.getOperator(), right); @@ -60,7 +60,7 @@ void ConstantEvaluator::endVisit(BinaryOperation const& _operation) " and " + right->toString() ); - setType( + setValue( _operation, TokenTraits::isCompareOp(_operation.getOperator()) ? TypeProvider::boolean() : @@ -71,7 +71,7 @@ void ConstantEvaluator::endVisit(BinaryOperation const& _operation) void ConstantEvaluator::endVisit(Literal const& _literal) { - setType(_literal, TypeProvider::forLiteral(_literal)); + setValue(_literal, TypeProvider::forLiteral(_literal)); } bool ConstantEvaluator::evaluated(ASTNode const& _node) const noexcept @@ -98,25 +98,53 @@ void ConstantEvaluator::endVisit(Identifier const& _identifier) evaluate(*value); } - setType(_identifier, type(*value)); + // Link LHS's identifier to the evaluation result of the RHS expression. + setResult(_identifier, result(*value)); } -void ConstantEvaluator::endVisit(TupleExpression const& _tuple) +void ConstantEvaluator::endVisit(TupleExpression const& _tuple) // TODO: do we actually ever need this code path here? { if (!_tuple.isInlineArray() && _tuple.components().size() == 1) - setType(_tuple, type(*_tuple.components().front())); + setValue(_tuple, evaluatedValue(*_tuple.components().front())); } -void ConstantEvaluator::setType(ASTNode const& _node, TypePointer const& _type) +void ConstantEvaluator::setValue(ASTNode const& _node, TypePointer const& _value) { - if (_type && _type->category() == Type::Category::RationalNumber) - m_evaluations[&_node] = _type; + setResult(_node, TypedValue{_value, _value}); } -TypePointer ConstantEvaluator::type(ASTNode const& _node) +void ConstantEvaluator::setResult(ASTNode const& _node, optional _result) +{ + if (_result.has_value()) + { + auto const sourceType = _result.value().sourceType; + auto const value = _result.value().evaluatedValue; + if (value && value->category() == Type::Category::RationalNumber) + m_evaluations[&_node] = {sourceType, value}; + } +} + +optional ConstantEvaluator::result(ASTNode const& _node) { if (auto p = m_evaluations.find(&_node); p != m_evaluations.end()) - return p->second; + return {p->second}; + + return nullopt; +} + +TypePointer ConstantEvaluator::sourceType(ASTNode const& _node) +{ + if (auto p = m_evaluations.find(&_node); p != m_evaluations.end()) + return p->second.sourceType; + + return nullptr; +} + +TypePointer ConstantEvaluator::evaluatedValue(ASTNode const& _node) +{ + if (auto p = m_evaluations.find(&_node); p != m_evaluations.end()) + return p->second.evaluatedValue; + return nullptr; } @@ -134,5 +162,5 @@ TypePointer ConstantEvaluator::evaluate(Expression const& _expr) _expr.accept(*this); - return type(_expr); + return evaluatedValue(_expr); } diff --git a/libsolidity/analysis/ConstantEvaluator.h b/libsolidity/analysis/ConstantEvaluator.h index 70eeefb96..5ba9ad102 100644 --- a/libsolidity/analysis/ConstantEvaluator.h +++ b/libsolidity/analysis/ConstantEvaluator.h @@ -25,6 +25,7 @@ #include +#include #include namespace solidity::langutil @@ -43,7 +44,8 @@ class TypeChecker; class ConstantEvaluator: private ASTConstVisitor { public: - using EvaluationMap = std::map; + struct TypedValue { TypePointer sourceType; TypePointer evaluatedValue; }; + using EvaluationMap = std::map; ConstantEvaluator(langutil::ErrorReporter& _errorReporter, EvaluationMap& _evaluations): m_errorReporter{ _errorReporter }, @@ -66,9 +68,13 @@ private: void endVisit(Identifier const& _identifier) override; void endVisit(TupleExpression const& _tuple) override; - void setType(ASTNode const& _node, TypePointer const& _value); + void setValue(ASTNode const& _node, TypePointer const& _value); - TypePointer type(ASTNode const& _node); + TypePointer sourceType(ASTNode const& _node); + TypePointer evaluatedValue(ASTNode const& _node); + + std::optional result(ASTNode const& _node); + void setResult(ASTNode const& _node, std::optional _result); bool evaluated(ASTNode const& _node) const noexcept;