mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
libyul: changing some AST members from shared_ptr<> to unique_ptr<>
* Some spaces look a little more verbose now, but that shouln't be a problem as it also should raise readability, too. * This makes some use of return-value-optimizations also.
This commit is contained in:
parent
778b14de26
commit
065c3c87af
@ -59,25 +59,25 @@ struct StackAssignment { langutil::SourceLocation location; Identifier variableN
|
|||||||
/// Multiple assignment ("x, y := f()"), where the left hand side variables each occupy
|
/// Multiple assignment ("x, y := f()"), where the left hand side variables each occupy
|
||||||
/// a single stack slot and expects a single expression on the right hand returning
|
/// a single stack slot and expects a single expression on the right hand returning
|
||||||
/// the same amount of items as the number of variables.
|
/// the same amount of items as the number of variables.
|
||||||
struct Assignment { langutil::SourceLocation location; std::vector<Identifier> variableNames; std::shared_ptr<Expression> value; };
|
struct Assignment { langutil::SourceLocation location; std::vector<Identifier> variableNames; std::unique_ptr<Expression> value; };
|
||||||
/// Functional instruction, e.g. "mul(mload(20:u256), add(2:u256, x))"
|
/// Functional instruction, e.g. "mul(mload(20:u256), add(2:u256, x))"
|
||||||
struct FunctionalInstruction { langutil::SourceLocation location; dev::solidity::Instruction instruction; std::vector<Expression> arguments; };
|
struct FunctionalInstruction { langutil::SourceLocation location; dev::solidity::Instruction instruction; std::vector<Expression> arguments; };
|
||||||
struct FunctionCall { langutil::SourceLocation location; Identifier functionName; std::vector<Expression> arguments; };
|
struct FunctionCall { langutil::SourceLocation location; Identifier functionName; std::vector<Expression> arguments; };
|
||||||
/// Statement that contains only a single expression
|
/// Statement that contains only a single expression
|
||||||
struct ExpressionStatement { langutil::SourceLocation location; Expression expression; };
|
struct ExpressionStatement { langutil::SourceLocation location; Expression expression; };
|
||||||
/// Block-scope variable declaration ("let x:u256 := mload(20:u256)"), non-hoisted
|
/// Block-scope variable declaration ("let x:u256 := mload(20:u256)"), non-hoisted
|
||||||
struct VariableDeclaration { langutil::SourceLocation location; TypedNameList variables; std::shared_ptr<Expression> value; };
|
struct VariableDeclaration { langutil::SourceLocation location; TypedNameList variables; std::unique_ptr<Expression> value; };
|
||||||
/// Block that creates a scope (frees declared stack variables)
|
/// Block that creates a scope (frees declared stack variables)
|
||||||
struct Block { langutil::SourceLocation location; std::vector<Statement> statements; };
|
struct Block { langutil::SourceLocation location; std::vector<Statement> statements; };
|
||||||
/// Function definition ("function f(a, b) -> (d, e) { ... }")
|
/// Function definition ("function f(a, b) -> (d, e) { ... }")
|
||||||
struct FunctionDefinition { langutil::SourceLocation location; YulString name; TypedNameList parameters; TypedNameList returnVariables; Block body; };
|
struct FunctionDefinition { langutil::SourceLocation location; YulString name; TypedNameList parameters; TypedNameList returnVariables; Block body; };
|
||||||
/// Conditional execution without "else" part.
|
/// Conditional execution without "else" part.
|
||||||
struct If { langutil::SourceLocation location; std::shared_ptr<Expression> condition; Block body; };
|
struct If { langutil::SourceLocation location; std::unique_ptr<Expression> condition; Block body; };
|
||||||
/// Switch case or default case
|
/// Switch case or default case
|
||||||
struct Case { langutil::SourceLocation location; std::shared_ptr<Literal> value; Block body; };
|
struct Case { langutil::SourceLocation location; std::unique_ptr<Literal> value; Block body; };
|
||||||
/// Switch statement
|
/// Switch statement
|
||||||
struct Switch { langutil::SourceLocation location; std::shared_ptr<Expression> expression; std::vector<Case> cases; };
|
struct Switch { langutil::SourceLocation location; std::unique_ptr<Expression> expression; std::vector<Case> cases; };
|
||||||
struct ForLoop { langutil::SourceLocation location; Block pre; std::shared_ptr<Expression> condition; Block post; Block body; };
|
struct ForLoop { langutil::SourceLocation location; Block pre; std::unique_ptr<Expression> condition; Block post; Block body; };
|
||||||
|
|
||||||
struct LocationExtractor: boost::static_visitor<langutil::SourceLocation>
|
struct LocationExtractor: boost::static_visitor<langutil::SourceLocation>
|
||||||
{
|
{
|
||||||
|
@ -81,15 +81,15 @@ Statement Parser::parseStatement()
|
|||||||
{
|
{
|
||||||
If _if = createWithLocation<If>();
|
If _if = createWithLocation<If>();
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
_if.condition = make_shared<Expression>(parseExpression());
|
_if.condition = make_unique<Expression>(parseExpression());
|
||||||
_if.body = parseBlock();
|
_if.body = parseBlock();
|
||||||
return _if;
|
return Statement{move(_if)};
|
||||||
}
|
}
|
||||||
case Token::Switch:
|
case Token::Switch:
|
||||||
{
|
{
|
||||||
Switch _switch = createWithLocation<Switch>();
|
Switch _switch = createWithLocation<Switch>();
|
||||||
m_scanner->next();
|
m_scanner->next();
|
||||||
_switch.expression = make_shared<Expression>(parseExpression());
|
_switch.expression = make_unique<Expression>(parseExpression());
|
||||||
while (m_scanner->currentToken() == Token::Case)
|
while (m_scanner->currentToken() == Token::Case)
|
||||||
_switch.cases.emplace_back(parseCase());
|
_switch.cases.emplace_back(parseCase());
|
||||||
if (m_scanner->currentToken() == Token::Default)
|
if (m_scanner->currentToken() == Token::Default)
|
||||||
@ -101,7 +101,7 @@ Statement Parser::parseStatement()
|
|||||||
if (_switch.cases.empty())
|
if (_switch.cases.empty())
|
||||||
fatalParserError("Switch statement without any cases.");
|
fatalParserError("Switch statement without any cases.");
|
||||||
_switch.location.end = _switch.cases.back().body.location.end;
|
_switch.location.end = _switch.cases.back().body.location.end;
|
||||||
return _switch;
|
return Statement{move(_switch)};
|
||||||
}
|
}
|
||||||
case Token::For:
|
case Token::For:
|
||||||
return parseForLoop();
|
return parseForLoop();
|
||||||
@ -120,7 +120,7 @@ Statement Parser::parseStatement()
|
|||||||
fatalParserError("Identifier expected, got instruction name.");
|
fatalParserError("Identifier expected, got instruction name.");
|
||||||
assignment.location.end = endPosition();
|
assignment.location.end = endPosition();
|
||||||
expectToken(Token::Identifier);
|
expectToken(Token::Identifier);
|
||||||
return assignment;
|
return Statement{move(assignment)};
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@ -163,7 +163,7 @@ Statement Parser::parseStatement()
|
|||||||
|
|
||||||
assignment.value.reset(new Expression(parseExpression()));
|
assignment.value.reset(new Expression(parseExpression()));
|
||||||
assignment.location.end = locationOf(*assignment.value).end;
|
assignment.location.end = locationOf(*assignment.value).end;
|
||||||
return assignment;
|
return Statement{std::move(assignment)};
|
||||||
}
|
}
|
||||||
case Token::Colon:
|
case Token::Colon:
|
||||||
{
|
{
|
||||||
@ -184,7 +184,7 @@ Statement Parser::parseStatement()
|
|||||||
assignment.variableNames.emplace_back(identifier);
|
assignment.variableNames.emplace_back(identifier);
|
||||||
assignment.value.reset(new Expression(parseExpression()));
|
assignment.value.reset(new Expression(parseExpression()));
|
||||||
assignment.location.end = locationOf(*assignment.value).end;
|
assignment.location.end = locationOf(*assignment.value).end;
|
||||||
return assignment;
|
return Statement{std::move(assignment)};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -230,7 +230,7 @@ Case Parser::parseCase()
|
|||||||
ElementaryOperation literal = parseElementaryOperation();
|
ElementaryOperation literal = parseElementaryOperation();
|
||||||
if (literal.type() != typeid(Literal))
|
if (literal.type() != typeid(Literal))
|
||||||
fatalParserError("Literal expected.");
|
fatalParserError("Literal expected.");
|
||||||
_case.value = make_shared<Literal>(boost::get<Literal>(std::move(literal)));
|
_case.value = make_unique<Literal>(boost::get<Literal>(std::move(literal)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
fatalParserError("Case or default case expected.");
|
fatalParserError("Case or default case expected.");
|
||||||
@ -245,7 +245,7 @@ ForLoop Parser::parseForLoop()
|
|||||||
ForLoop forLoop = createWithLocation<ForLoop>();
|
ForLoop forLoop = createWithLocation<ForLoop>();
|
||||||
expectToken(Token::For);
|
expectToken(Token::For);
|
||||||
forLoop.pre = parseBlock();
|
forLoop.pre = parseBlock();
|
||||||
forLoop.condition = make_shared<Expression>(parseExpression());
|
forLoop.condition = make_unique<Expression>(parseExpression());
|
||||||
forLoop.post = parseBlock();
|
forLoop.post = parseBlock();
|
||||||
forLoop.body = parseBlock();
|
forLoop.body = parseBlock();
|
||||||
forLoop.location.end = forLoop.body.location.end;
|
forLoop.location.end = forLoop.body.location.end;
|
||||||
@ -443,7 +443,7 @@ VariableDeclaration Parser::parseVariableDeclaration()
|
|||||||
{
|
{
|
||||||
expectToken(Token::Colon);
|
expectToken(Token::Colon);
|
||||||
expectToken(Token::Assign);
|
expectToken(Token::Assign);
|
||||||
varDecl.value.reset(new Expression(parseExpression()));
|
varDecl.value = make_unique<Expression>(parseExpression());
|
||||||
varDecl.location.end = locationOf(*varDecl.value).end;
|
varDecl.location.end = locationOf(*varDecl.value).end;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -93,10 +93,11 @@ protected:
|
|||||||
std::vector<T> translateVector(std::vector<T> const& _values);
|
std::vector<T> translateVector(std::vector<T> const& _values);
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
std::shared_ptr<T> translate(std::shared_ptr<T> const& _v)
|
std::unique_ptr<T> translate(std::unique_ptr<T> const& _v)
|
||||||
{
|
{
|
||||||
return _v ? std::make_shared<T>(translate(*_v)) : nullptr;
|
return _v ? std::make_unique<T>(translate(*_v)) : nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
Block translate(Block const& _block);
|
Block translate(Block const& _block);
|
||||||
Case translate(Case const& _case);
|
Case translate(Case const& _case);
|
||||||
Identifier translate(Identifier const& _identifier);
|
Identifier translate(Identifier const& _identifier);
|
||||||
|
@ -51,8 +51,10 @@ void DataFlowAnalyzer::operator()(VariableDeclaration& _varDecl)
|
|||||||
for (auto const& var: _varDecl.variables)
|
for (auto const& var: _varDecl.variables)
|
||||||
names.emplace(var.name);
|
names.emplace(var.name);
|
||||||
m_variableScopes.back().variables += names;
|
m_variableScopes.back().variables += names;
|
||||||
|
|
||||||
if (_varDecl.value)
|
if (_varDecl.value)
|
||||||
visit(*_varDecl.value);
|
visit(*_varDecl.value);
|
||||||
|
|
||||||
handleAssignment(names, _varDecl.value.get());
|
handleAssignment(names, _varDecl.value.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ void ExpressionSplitter::outlineExpression(Expression& _expr)
|
|||||||
m_statementsToPrefix.emplace_back(VariableDeclaration{
|
m_statementsToPrefix.emplace_back(VariableDeclaration{
|
||||||
location,
|
location,
|
||||||
{{TypedName{location, var, {}}}},
|
{{TypedName{location, var, {}}}},
|
||||||
make_shared<Expression>(std::move(_expr))
|
make_unique<Expression>(std::move(_expr))
|
||||||
});
|
});
|
||||||
_expr = Identifier{location, var};
|
_expr = Identifier{location, var};
|
||||||
}
|
}
|
||||||
|
@ -181,9 +181,9 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
|
|||||||
variableReplacements[_existingVariable.name] = newName;
|
variableReplacements[_existingVariable.name] = newName;
|
||||||
VariableDeclaration varDecl{_funCall.location, {{_funCall.location, newName, _existingVariable.type}}, {}};
|
VariableDeclaration varDecl{_funCall.location, {{_funCall.location, newName, _existingVariable.type}}, {}};
|
||||||
if (_value)
|
if (_value)
|
||||||
varDecl.value = make_shared<Expression>(std::move(*_value));
|
varDecl.value = make_unique<Expression>(std::move(*_value));
|
||||||
else
|
else
|
||||||
varDecl.value = make_shared<Expression>(zero);
|
varDecl.value = make_unique<Expression>(zero);
|
||||||
newStatements.emplace_back(std::move(varDecl));
|
newStatements.emplace_back(std::move(varDecl));
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -202,7 +202,7 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
|
|||||||
newStatements.emplace_back(Assignment{
|
newStatements.emplace_back(Assignment{
|
||||||
_assignment.location,
|
_assignment.location,
|
||||||
{_assignment.variableNames[i]},
|
{_assignment.variableNames[i]},
|
||||||
make_shared<Expression>(Identifier{
|
make_unique<Expression>(Identifier{
|
||||||
_assignment.location,
|
_assignment.location,
|
||||||
variableReplacements.at(function->returnVariables[i].name)
|
variableReplacements.at(function->returnVariables[i].name)
|
||||||
})
|
})
|
||||||
@ -214,7 +214,7 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
|
|||||||
newStatements.emplace_back(VariableDeclaration{
|
newStatements.emplace_back(VariableDeclaration{
|
||||||
_varDecl.location,
|
_varDecl.location,
|
||||||
{std::move(_varDecl.variables[i])},
|
{std::move(_varDecl.variables[i])},
|
||||||
make_shared<Expression>(Identifier{
|
make_unique<Expression>(Identifier{
|
||||||
_varDecl.location,
|
_varDecl.location,
|
||||||
variableReplacements.at(function->returnVariables[i].name)
|
variableReplacements.at(function->returnVariables[i].name)
|
||||||
})
|
})
|
||||||
@ -232,10 +232,10 @@ Statement BodyCopier::operator()(VariableDeclaration const& _varDecl)
|
|||||||
return ASTCopier::operator()(_varDecl);
|
return ASTCopier::operator()(_varDecl);
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement BodyCopier::operator()(FunctionDefinition const& _funDef)
|
Statement BodyCopier::operator()(FunctionDefinition const&)
|
||||||
{
|
{
|
||||||
assertThrow(false, OptimizerException, "Function hoisting has to be done before function inlining.");
|
assertThrow(false, OptimizerException, "Function hoisting has to be done before function inlining.");
|
||||||
return _funDef;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
YulString BodyCopier::translateIdentifier(YulString _name)
|
YulString BodyCopier::translateIdentifier(YulString _name)
|
||||||
|
@ -66,12 +66,13 @@ void SSATransform::operator()(Block& _block)
|
|||||||
|
|
||||||
// Creates a new variable (and returns its declaration) with value _value
|
// Creates a new variable (and returns its declaration) with value _value
|
||||||
// and replaces _value by a reference to that new variable.
|
// and replaces _value by a reference to that new variable.
|
||||||
auto replaceByNew = [&](SourceLocation _loc, YulString _varName, YulString _type, shared_ptr<Expression>& _value) -> VariableDeclaration
|
|
||||||
|
auto replaceByNew = [&](SourceLocation _loc, YulString _varName, YulString _type, unique_ptr<Expression>& _value) -> VariableDeclaration
|
||||||
{
|
{
|
||||||
YulString newName = m_nameDispenser.newName(_varName);
|
YulString newName = m_nameDispenser.newName(_varName);
|
||||||
m_currentVariableValues[_varName] = newName;
|
m_currentVariableValues[_varName] = newName;
|
||||||
variablesToClearAtEnd.emplace(_varName);
|
variablesToClearAtEnd.emplace(_varName);
|
||||||
shared_ptr<Expression> v = make_shared<Expression>(Identifier{_loc, newName});
|
unique_ptr<Expression> v = make_unique<Expression>(Identifier{_loc, newName});
|
||||||
_value.swap(v);
|
_value.swap(v);
|
||||||
return VariableDeclaration{_loc, {TypedName{_loc, std::move(newName), std::move(_type)}}, std::move(v)};
|
return VariableDeclaration{_loc, {TypedName{_loc, std::move(newName), std::move(_type)}}, std::move(v)};
|
||||||
};
|
};
|
||||||
@ -87,14 +88,16 @@ void SSATransform::operator()(Block& _block)
|
|||||||
visit(*varDecl.value);
|
visit(*varDecl.value);
|
||||||
if (varDecl.variables.size() != 1 || !m_variablesToReplace.count(varDecl.variables.front().name))
|
if (varDecl.variables.size() != 1 || !m_variablesToReplace.count(varDecl.variables.front().name))
|
||||||
return {};
|
return {};
|
||||||
// Replace "let a := v" by "let a_1 := v let a := v"
|
vector<Statement> v;
|
||||||
VariableDeclaration newVarDecl = replaceByNew(
|
// Replace "let a := v" by "let a_1 := v let a := a_1"
|
||||||
|
v.emplace_back(replaceByNew(
|
||||||
varDecl.location,
|
varDecl.location,
|
||||||
varDecl.variables.front().name,
|
varDecl.variables.front().name,
|
||||||
varDecl.variables.front().type,
|
varDecl.variables.front().type,
|
||||||
varDecl.value
|
varDecl.value
|
||||||
);
|
));
|
||||||
return vector<Statement>{std::move(newVarDecl), std::move(varDecl)};
|
v.emplace_back(move(varDecl));
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
else if (_s.type() == typeid(Assignment))
|
else if (_s.type() == typeid(Assignment))
|
||||||
{
|
{
|
||||||
@ -103,14 +106,16 @@ void SSATransform::operator()(Block& _block)
|
|||||||
if (assignment.variableNames.size() != 1)
|
if (assignment.variableNames.size() != 1)
|
||||||
return {};
|
return {};
|
||||||
assertThrow(m_variablesToReplace.count(assignment.variableNames.front().name), OptimizerException, "");
|
assertThrow(m_variablesToReplace.count(assignment.variableNames.front().name), OptimizerException, "");
|
||||||
|
vector<Statement> v;
|
||||||
// Replace "a := v" by "let a_1 := v a := v"
|
// Replace "a := v" by "let a_1 := v a := v"
|
||||||
VariableDeclaration newVarDecl = replaceByNew(
|
v.emplace_back(replaceByNew(
|
||||||
assignment.location,
|
assignment.location,
|
||||||
assignment.variableNames.front().name,
|
assignment.variableNames.front().name,
|
||||||
{}, // TODO determine type
|
{}, // TODO determine type
|
||||||
assignment.value
|
assignment.value
|
||||||
);
|
));
|
||||||
return vector<Statement>{std::move(newVarDecl), std::move(assignment)};
|
v.emplace_back(move(assignment));
|
||||||
|
return v;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
visit(_s);
|
visit(_s);
|
||||||
|
@ -51,7 +51,11 @@ void StructuralSimplifier::simplify(std::vector<yul::Statement>& _statements)
|
|||||||
GenericFallbackReturnsVisitor<OptionalStatements, If, Switch, ForLoop> const visitor(
|
GenericFallbackReturnsVisitor<OptionalStatements, If, Switch, ForLoop> const visitor(
|
||||||
[&](If& _ifStmt) -> OptionalStatements {
|
[&](If& _ifStmt) -> OptionalStatements {
|
||||||
if (_ifStmt.body.statements.empty())
|
if (_ifStmt.body.statements.empty())
|
||||||
return {{makePopExpressionStatement(_ifStmt.location, std::move(*_ifStmt.condition))}};
|
{
|
||||||
|
OptionalStatements s = vector<Statement>{};
|
||||||
|
s->emplace_back(makePopExpressionStatement(_ifStmt.location, std::move(*_ifStmt.condition)));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
if (expressionAlwaysTrue(*_ifStmt.condition))
|
if (expressionAlwaysTrue(*_ifStmt.condition))
|
||||||
return {std::move(_ifStmt.body.statements)};
|
return {std::move(_ifStmt.body.statements)};
|
||||||
else if (expressionAlwaysFalse(*_ifStmt.condition))
|
else if (expressionAlwaysFalse(*_ifStmt.condition))
|
||||||
@ -64,18 +68,24 @@ void StructuralSimplifier::simplify(std::vector<yul::Statement>& _statements)
|
|||||||
auto& switchCase = _switchStmt.cases.front();
|
auto& switchCase = _switchStmt.cases.front();
|
||||||
auto loc = locationOf(*_switchStmt.expression);
|
auto loc = locationOf(*_switchStmt.expression);
|
||||||
if (switchCase.value)
|
if (switchCase.value)
|
||||||
return {{If{
|
{
|
||||||
|
OptionalStatements s = vector<Statement>{};
|
||||||
|
s->emplace_back(If{
|
||||||
std::move(_switchStmt.location),
|
std::move(_switchStmt.location),
|
||||||
make_shared<Expression>(FunctionalInstruction{
|
make_unique<Expression>(FunctionalInstruction{
|
||||||
std::move(loc),
|
std::move(loc),
|
||||||
solidity::Instruction::EQ,
|
solidity::Instruction::EQ,
|
||||||
{std::move(*switchCase.value), std::move(*_switchStmt.expression)}
|
{std::move(*switchCase.value), std::move(*_switchStmt.expression)}
|
||||||
}), std::move(switchCase.body)}}};
|
}), std::move(switchCase.body)});
|
||||||
|
return s;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
return {{
|
{
|
||||||
makePopExpressionStatement(loc, std::move(*_switchStmt.expression)),
|
OptionalStatements s = vector<Statement>{};
|
||||||
std::move(switchCase.body)
|
s->emplace_back(makePopExpressionStatement(loc, std::move(*_switchStmt.expression)));
|
||||||
}};
|
s->emplace_back(std::move(switchCase.body));
|
||||||
|
return s;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return {};
|
return {};
|
||||||
|
@ -100,7 +100,7 @@ bool SyntacticallyEqual::statementEqual(Assignment const& _lhs, Assignment const
|
|||||||
bool SyntacticallyEqual::statementEqual(VariableDeclaration const& _lhs, VariableDeclaration const& _rhs)
|
bool SyntacticallyEqual::statementEqual(VariableDeclaration const& _lhs, VariableDeclaration const& _rhs)
|
||||||
{
|
{
|
||||||
// first visit expression, then variable declarations
|
// first visit expression, then variable declarations
|
||||||
if (!compareSharedPtr<Expression, &SyntacticallyEqual::operator()>(_lhs.value, _rhs.value))
|
if (!compareUniquePtr<Expression, &SyntacticallyEqual::operator()>(_lhs.value, _rhs.value))
|
||||||
return false;
|
return false;
|
||||||
return containerEqual(_lhs.variables, _rhs.variables, [this](TypedName const& _lhsVarName, TypedName const& _rhsVarName) -> bool {
|
return containerEqual(_lhs.variables, _rhs.variables, [this](TypedName const& _lhsVarName, TypedName const& _rhsVarName) -> bool {
|
||||||
return this->visitDeclaration(_lhsVarName, _rhsVarName);
|
return this->visitDeclaration(_lhsVarName, _rhsVarName);
|
||||||
@ -123,7 +123,7 @@ bool SyntacticallyEqual::statementEqual(FunctionDefinition const& _lhs, Function
|
|||||||
bool SyntacticallyEqual::statementEqual(If const& _lhs, If const& _rhs)
|
bool SyntacticallyEqual::statementEqual(If const& _lhs, If const& _rhs)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
compareSharedPtr<Expression, &SyntacticallyEqual::operator()>(_lhs.condition, _rhs.condition) &&
|
compareUniquePtr<Expression, &SyntacticallyEqual::operator()>(_lhs.condition, _rhs.condition) &&
|
||||||
statementEqual(_lhs.body, _rhs.body);
|
statementEqual(_lhs.body, _rhs.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -139,7 +139,7 @@ bool SyntacticallyEqual::statementEqual(Switch const& _lhs, Switch const& _rhs)
|
|||||||
for (auto const& rhsCase: _rhs.cases)
|
for (auto const& rhsCase: _rhs.cases)
|
||||||
rhsCases.insert(&rhsCase);
|
rhsCases.insert(&rhsCase);
|
||||||
return
|
return
|
||||||
compareSharedPtr<Expression, &SyntacticallyEqual::operator()>(_lhs.expression, _rhs.expression) &&
|
compareUniquePtr<Expression, &SyntacticallyEqual::operator()>(_lhs.expression, _rhs.expression) &&
|
||||||
containerEqual(lhsCases, rhsCases, [this](Case const* _lhsCase, Case const* _rhsCase) -> bool {
|
containerEqual(lhsCases, rhsCases, [this](Case const* _lhsCase, Case const* _rhsCase) -> bool {
|
||||||
return this->switchCaseEqual(*_lhsCase, *_rhsCase);
|
return this->switchCaseEqual(*_lhsCase, *_rhsCase);
|
||||||
});
|
});
|
||||||
@ -149,7 +149,7 @@ bool SyntacticallyEqual::statementEqual(Switch const& _lhs, Switch const& _rhs)
|
|||||||
bool SyntacticallyEqual::switchCaseEqual(Case const& _lhs, Case const& _rhs)
|
bool SyntacticallyEqual::switchCaseEqual(Case const& _lhs, Case const& _rhs)
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
compareSharedPtr<Literal, &SyntacticallyEqual::expressionEqual>(_lhs.value, _rhs.value) &&
|
compareUniquePtr<Literal, &SyntacticallyEqual::expressionEqual>(_lhs.value, _rhs.value) &&
|
||||||
statementEqual(_lhs.body, _rhs.body);
|
statementEqual(_lhs.body, _rhs.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +157,7 @@ bool SyntacticallyEqual::statementEqual(ForLoop const& _lhs, ForLoop const& _rhs
|
|||||||
{
|
{
|
||||||
return
|
return
|
||||||
statementEqual(_lhs.pre, _rhs.pre) &&
|
statementEqual(_lhs.pre, _rhs.pre) &&
|
||||||
compareSharedPtr<Expression, &SyntacticallyEqual::operator()>(_lhs.condition, _rhs.condition) &&
|
compareUniquePtr<Expression, &SyntacticallyEqual::operator()>(_lhs.condition, _rhs.condition) &&
|
||||||
statementEqual(_lhs.body, _rhs.body) &&
|
statementEqual(_lhs.body, _rhs.body) &&
|
||||||
statementEqual(_lhs.post, _rhs.post);
|
statementEqual(_lhs.post, _rhs.post);
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<typename T, bool (SyntacticallyEqual::*CompareMember)(T const&, T const&)>
|
template<typename T, bool (SyntacticallyEqual::*CompareMember)(T const&, T const&)>
|
||||||
bool compareSharedPtr(std::shared_ptr<T> const& _lhs, std::shared_ptr<T> const& _rhs)
|
bool compareUniquePtr(std::unique_ptr<T> const& _lhs, std::unique_ptr<T> const& _rhs)
|
||||||
{
|
{
|
||||||
return (_lhs == _rhs) || (_lhs && _rhs && (this->*CompareMember)(*_lhs, *_rhs));
|
return (_lhs == _rhs) || (_lhs && _rhs && (this->*CompareMember)(*_lhs, *_rhs));
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ void VarDeclInitializer::operator()(Block& _block)
|
|||||||
return {};
|
return {};
|
||||||
else if (_varDecl.variables.size() == 1)
|
else if (_varDecl.variables.size() == 1)
|
||||||
{
|
{
|
||||||
_varDecl.value = make_shared<Expression>(zero);
|
_varDecl.value = make_unique<Expression>(zero);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -47,7 +47,7 @@ void VarDeclInitializer::operator()(Block& _block)
|
|||||||
OptionalStatements ret{vector<Statement>{}};
|
OptionalStatements ret{vector<Statement>{}};
|
||||||
langutil::SourceLocation loc{std::move(_varDecl.location)};
|
langutil::SourceLocation loc{std::move(_varDecl.location)};
|
||||||
for (auto& var: _varDecl.variables)
|
for (auto& var: _varDecl.variables)
|
||||||
ret->push_back(VariableDeclaration{loc, {std::move(var)}, make_shared<Expression>(zero)});
|
ret->push_back(VariableDeclaration{loc, {std::move(var)}, make_unique<Expression>(zero)});
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user