Replace boost::variant by std::variant in libyul

This commit is contained in:
Leonardo Alt 2019-11-19 16:42:49 +01:00
parent 6d85b63f87
commit be849b3c47
75 changed files with 371 additions and 372 deletions

View File

@ -21,7 +21,9 @@
#include <libyul/backends/evm/EVMDialect.h> #include <libyul/backends/evm/EVMDialect.h>
#include <liblangutil/ErrorReporter.h> #include <liblangutil/ErrorReporter.h>
#include <libevmasm/SemanticInformation.h> #include <libevmasm/SemanticInformation.h>
#include <functional> #include <functional>
#include <variant>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -31,7 +33,7 @@ using namespace dev::solidity;
namespace namespace
{ {
class AssemblyViewPureChecker: public boost::static_visitor<void> class AssemblyViewPureChecker
{ {
public: public:
explicit AssemblyViewPureChecker( explicit AssemblyViewPureChecker(
@ -52,21 +54,21 @@ public:
{ {
checkInstruction(_instr.location, _instr.instruction); checkInstruction(_instr.location, _instr.instruction);
for (auto const& arg: _instr.arguments) for (auto const& arg: _instr.arguments)
boost::apply_visitor(*this, arg); std::visit(*this, arg);
} }
void operator()(yul::ExpressionStatement const& _expr) void operator()(yul::ExpressionStatement const& _expr)
{ {
boost::apply_visitor(*this, _expr.expression); std::visit(*this, _expr.expression);
} }
void operator()(yul::StackAssignment const&) {} void operator()(yul::StackAssignment const&) {}
void operator()(yul::Assignment const& _assignment) void operator()(yul::Assignment const& _assignment)
{ {
boost::apply_visitor(*this, *_assignment.value); std::visit(*this, *_assignment.value);
} }
void operator()(yul::VariableDeclaration const& _varDecl) void operator()(yul::VariableDeclaration const& _varDecl)
{ {
if (_varDecl.value) if (_varDecl.value)
boost::apply_visitor(*this, *_varDecl.value); std::visit(*this, *_varDecl.value);
} }
void operator()(yul::FunctionDefinition const& _funDef) void operator()(yul::FunctionDefinition const& _funDef)
{ {
@ -80,16 +82,16 @@ public:
checkInstruction(_funCall.location, *fun->instruction); checkInstruction(_funCall.location, *fun->instruction);
for (auto const& arg: _funCall.arguments) for (auto const& arg: _funCall.arguments)
boost::apply_visitor(*this, arg); std::visit(*this, arg);
} }
void operator()(yul::If const& _if) void operator()(yul::If const& _if)
{ {
boost::apply_visitor(*this, *_if.condition); std::visit(*this, *_if.condition);
(*this)(_if.body); (*this)(_if.body);
} }
void operator()(yul::Switch const& _switch) void operator()(yul::Switch const& _switch)
{ {
boost::apply_visitor(*this, *_switch.expression); std::visit(*this, *_switch.expression);
for (auto const& _case: _switch.cases) for (auto const& _case: _switch.cases)
{ {
if (_case.value) if (_case.value)
@ -100,7 +102,7 @@ public:
void operator()(yul::ForLoop const& _for) void operator()(yul::ForLoop const& _for)
{ {
(*this)(_for.pre); (*this)(_for.pre);
boost::apply_visitor(*this, *_for.condition); std::visit(*this, *_for.condition);
(*this)(_for.body); (*this)(_for.body);
(*this)(_for.post); (*this)(_for.post);
} }
@ -113,7 +115,7 @@ public:
void operator()(yul::Block const& _block) void operator()(yul::Block const& _block)
{ {
for (auto const& s: _block.statements) for (auto const& s: _block.statements)
boost::apply_visitor(*this, s); std::visit(*this, s);
} }
private: private:

View File

@ -833,9 +833,9 @@ bool IRGeneratorForStatements::visit(InlineAssembly const& _inlineAsm)
yul::Statement modified = bodyCopier(_inlineAsm.operations()); yul::Statement modified = bodyCopier(_inlineAsm.operations());
solAssert(modified.type() == typeid(yul::Block), ""); solAssert(holds_alternative<yul::Block>(modified), "");
m_code << yul::AsmPrinter()(boost::get<yul::Block>(std::move(modified))) << "\n"; m_code << yul::AsmPrinter()(std::get<yul::Block>(std::move(modified))) << "\n";
return false; return false;
} }

View File

@ -214,7 +214,7 @@ bool AsmAnalyzer::operator()(FunctionalInstruction const& _instr)
bool AsmAnalyzer::operator()(ExpressionStatement const& _statement) bool AsmAnalyzer::operator()(ExpressionStatement const& _statement)
{ {
int initialStackHeight = m_stackHeight; int initialStackHeight = m_stackHeight;
bool success = boost::apply_visitor(*this, _statement.expression); bool success = std::visit(*this, _statement.expression);
if (m_stackHeight != initialStackHeight && (m_dialect.flavour != AsmFlavour::Loose || m_errorTypeForLoose)) if (m_stackHeight != initialStackHeight && (m_dialect.flavour != AsmFlavour::Loose || m_errorTypeForLoose))
{ {
Error::Type errorType = m_dialect.flavour == AsmFlavour::Loose ? *m_errorTypeForLoose : Error::Type::TypeError; Error::Type errorType = m_dialect.flavour == AsmFlavour::Loose ? *m_errorTypeForLoose : Error::Type::TypeError;
@ -249,7 +249,7 @@ bool AsmAnalyzer::operator()(Assignment const& _assignment)
int const expectedItems = _assignment.variableNames.size(); int const expectedItems = _assignment.variableNames.size();
solAssert(expectedItems >= 1, ""); solAssert(expectedItems >= 1, "");
int const stackHeight = m_stackHeight; int const stackHeight = m_stackHeight;
bool success = boost::apply_visitor(*this, *_assignment.value); bool success = std::visit(*this, *_assignment.value);
if ((m_stackHeight - stackHeight) != expectedItems) if ((m_stackHeight - stackHeight) != expectedItems)
{ {
m_errorReporter.declarationError( m_errorReporter.declarationError(
@ -276,7 +276,7 @@ bool AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
if (_varDecl.value) if (_varDecl.value)
{ {
int const stackHeight = m_stackHeight; int const stackHeight = m_stackHeight;
success = boost::apply_visitor(*this, *_varDecl.value); success = std::visit(*this, *_varDecl.value);
int numValues = m_stackHeight - stackHeight; int numValues = m_stackHeight - stackHeight;
if (numValues != numVariables) if (numValues != numVariables)
{ {
@ -298,7 +298,7 @@ bool AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
for (auto const& variable: _varDecl.variables) for (auto const& variable: _varDecl.variables)
{ {
expectValidType(variable.type.str(), variable.location); expectValidType(variable.type.str(), variable.location);
m_activeVariables.insert(&boost::get<Scope::Variable>(m_currentScope->identifiers.at(variable.name))); m_activeVariables.insert(&std::get<Scope::Variable>(m_currentScope->identifiers.at(variable.name)));
} }
m_info.stackHeightInfo[&_varDecl] = m_stackHeight; m_info.stackHeightInfo[&_varDecl] = m_stackHeight;
return success; return success;
@ -313,7 +313,7 @@ bool AsmAnalyzer::operator()(FunctionDefinition const& _funDef)
for (auto const& var: _funDef.parameters + _funDef.returnVariables) for (auto const& var: _funDef.parameters + _funDef.returnVariables)
{ {
expectValidType(var.type.str(), var.location); expectValidType(var.type.str(), var.location);
m_activeVariables.insert(&boost::get<Scope::Variable>(varScope.identifiers.at(var.name))); m_activeVariables.insert(&std::get<Scope::Variable>(varScope.identifiers.at(var.name)));
} }
int const stackHeight = m_stackHeight; int const stackHeight = m_stackHeight;
@ -388,15 +388,15 @@ bool AsmAnalyzer::operator()(FunctionCall const& _funCall)
success = false; success = false;
else if (needsLiteralArguments) else if (needsLiteralArguments)
{ {
if (arg.type() != typeid(Literal)) if (!holds_alternative<Literal>(arg))
m_errorReporter.typeError( m_errorReporter.typeError(
_funCall.functionName.location, _funCall.functionName.location,
"Function expects direct literals as arguments." "Function expects direct literals as arguments."
); );
else if (!m_dataNames.count(boost::get<Literal>(arg).value)) else if (!m_dataNames.count(std::get<Literal>(arg).value))
m_errorReporter.typeError( m_errorReporter.typeError(
_funCall.functionName.location, _funCall.functionName.location,
"Unknown data object \"" + boost::get<Literal>(arg).value.str() + "\"." "Unknown data object \"" + std::get<Literal>(arg).value.str() + "\"."
); );
} }
} }
@ -556,7 +556,7 @@ bool AsmAnalyzer::operator()(Block const& _block)
int const initialStackHeight = m_stackHeight; int const initialStackHeight = m_stackHeight;
for (auto const& s: _block.statements) for (auto const& s: _block.statements)
if (!boost::apply_visitor(*this, s)) if (!std::visit(*this, s))
success = false; success = false;
m_stackHeight -= scope(&_block).numberOfVariables(); m_stackHeight -= scope(&_block).numberOfVariables();
@ -585,7 +585,7 @@ bool AsmAnalyzer::expectExpression(Expression const& _expr)
{ {
bool success = true; bool success = true;
int const initialHeight = m_stackHeight; int const initialHeight = m_stackHeight;
if (!boost::apply_visitor(*this, _expr)) if (!std::visit(*this, _expr))
success = false; success = false;
if (!expectDeposit(1, initialHeight, locationOf(_expr))) if (!expectDeposit(1, initialHeight, locationOf(_expr)))
success = false; success = false;
@ -616,12 +616,12 @@ bool AsmAnalyzer::checkAssignment(Identifier const& _variable, size_t _valueSize
if (Scope::Identifier const* var = m_currentScope->lookup(_variable.name)) if (Scope::Identifier const* var = m_currentScope->lookup(_variable.name))
{ {
// Check that it is a variable // Check that it is a variable
if (var->type() != typeid(Scope::Variable)) if (!holds_alternative<Scope::Variable>(*var))
{ {
m_errorReporter.typeError(_variable.location, "Assignment requires variable."); m_errorReporter.typeError(_variable.location, "Assignment requires variable.");
success = false; success = false;
} }
else if (!m_activeVariables.count(&boost::get<Scope::Variable>(*var))) else if (!m_activeVariables.count(&std::get<Scope::Variable>(*var)))
{ {
m_errorReporter.declarationError( m_errorReporter.declarationError(
_variable.location, _variable.location,

View File

@ -30,8 +30,6 @@
#include <libyul/backends/evm/AbstractAssembly.h> #include <libyul/backends/evm/AbstractAssembly.h>
#include <libyul/backends/evm/EVMDialect.h> #include <libyul/backends/evm/EVMDialect.h>
#include <boost/variant.hpp>
#include <functional> #include <functional>
#include <list> #include <list>
#include <memory> #include <memory>
@ -53,7 +51,7 @@ struct AsmAnalysisInfo;
* references and performs other checks. * references and performs other checks.
* If all these checks pass, code generation should not throw errors. * If all these checks pass, code generation should not throw errors.
*/ */
class AsmAnalyzer: public boost::static_visitor<bool> class AsmAnalyzer
{ {
public: public:
explicit AsmAnalyzer( explicit AsmAnalyzer(

View File

@ -28,7 +28,6 @@
#include <libevmasm/Instruction.h> #include <libevmasm/Instruction.h>
#include <liblangutil/SourceLocation.h> #include <liblangutil/SourceLocation.h>
#include <boost/variant.hpp>
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#include <map> #include <map>
@ -83,7 +82,7 @@ struct Break { langutil::SourceLocation location; };
/// Continue statement (valid within for loop) /// Continue statement (valid within for loop)
struct Continue { langutil::SourceLocation location; }; struct Continue { langutil::SourceLocation location; };
struct LocationExtractor: boost::static_visitor<langutil::SourceLocation> struct LocationExtractor
{ {
template <class T> langutil::SourceLocation operator()(T const& _node) const template <class T> langutil::SourceLocation operator()(T const& _node) const
{ {
@ -94,7 +93,7 @@ struct LocationExtractor: boost::static_visitor<langutil::SourceLocation>
/// Extracts the source location from an inline assembly node. /// Extracts the source location from an inline assembly node.
template <class T> inline langutil::SourceLocation locationOf(T const& _node) template <class T> inline langutil::SourceLocation locationOf(T const& _node)
{ {
return boost::apply_visitor(LocationExtractor(), _node); return std::visit(LocationExtractor(), _node);
} }
} }

View File

@ -22,7 +22,7 @@
#pragma once #pragma once
#include <boost/variant.hpp> #include <variant>
namespace yul namespace yul
{ {
@ -48,7 +48,7 @@ struct Block;
struct TypedName; struct TypedName;
using Expression = boost::variant<FunctionalInstruction, FunctionCall, Identifier, Literal>; using Expression = std::variant<FunctionalInstruction, FunctionCall, Identifier, Literal>;
using Statement = boost::variant<ExpressionStatement, Instruction, Label, StackAssignment, Assignment, VariableDeclaration, FunctionDefinition, If, Switch, ForLoop, Break, Continue, Block>; using Statement = std::variant<ExpressionStatement, Instruction, Label, StackAssignment, Assignment, VariableDeclaration, FunctionDefinition, If, Switch, ForLoop, Break, Continue, Block>;
} }

View File

@ -184,7 +184,7 @@ Statement Parser::parseStatement()
while (true) while (true)
{ {
if (elementary.type() != typeid(Identifier)) if (!holds_alternative<Identifier>(elementary))
{ {
auto const token = currentToken() == Token::Comma ? "," : ":="; auto const token = currentToken() == Token::Comma ? "," : ":=";
@ -196,7 +196,7 @@ Statement Parser::parseStatement()
); );
} }
auto const& identifier = boost::get<Identifier>(elementary); auto const& identifier = std::get<Identifier>(elementary);
if (m_dialect.builtin(identifier.name)) if (m_dialect.builtin(identifier.name))
fatalParserError("Cannot assign to builtin function \"" + identifier.name.str() + "\"."); fatalParserError("Cannot assign to builtin function \"" + identifier.name.str() + "\".");
@ -212,7 +212,7 @@ Statement Parser::parseStatement()
} }
Assignment assignment = Assignment assignment =
createWithLocation<Assignment>(boost::get<Identifier>(elementary).location); createWithLocation<Assignment>(std::get<Identifier>(elementary).location);
assignment.variableNames = std::move(variableNames); assignment.variableNames = std::move(variableNames);
expectToken(Token::AssemblyAssign); expectToken(Token::AssemblyAssign);
@ -224,10 +224,10 @@ Statement Parser::parseStatement()
} }
case Token::Colon: case Token::Colon:
{ {
if (elementary.type() != typeid(Identifier)) if (!holds_alternative<Identifier>(elementary))
fatalParserError("Label name must precede \":\"."); fatalParserError("Label name must precede \":\".");
Identifier const& identifier = boost::get<Identifier>(elementary); Identifier const& identifier = std::get<Identifier>(elementary);
advance(); advance();
@ -245,20 +245,20 @@ Statement Parser::parseStatement()
break; break;
} }
if (elementary.type() == typeid(Identifier)) if (holds_alternative<Identifier>(elementary))
{ {
Identifier& identifier = boost::get<Identifier>(elementary); Identifier& identifier = std::get<Identifier>(elementary);
return ExpressionStatement{identifier.location, { move(identifier) }}; return ExpressionStatement{identifier.location, { move(identifier) }};
} }
else if (elementary.type() == typeid(Literal)) else if (holds_alternative<Literal>(elementary))
{ {
Expression expr = boost::get<Literal>(elementary); Expression expr = std::get<Literal>(elementary);
return ExpressionStatement{locationOf(expr), expr}; return ExpressionStatement{locationOf(expr), expr};
} }
else else
{ {
solAssert(elementary.type() == typeid(Instruction), "Invalid elementary operation."); solAssert(holds_alternative<Instruction>(elementary), "Invalid elementary operation.");
return boost::get<Instruction>(elementary); return std::get<Instruction>(elementary);
} }
} }
@ -272,9 +272,9 @@ Case Parser::parseCase()
{ {
advance(); advance();
ElementaryOperation literal = parseElementaryOperation(); ElementaryOperation literal = parseElementaryOperation();
if (literal.type() != typeid(Literal)) if (!holds_alternative<Literal>(literal))
fatalParserError("Literal expected."); fatalParserError("Literal expected.");
_case.value = make_unique<Literal>(boost::get<Literal>(std::move(literal))); _case.value = make_unique<Literal>(std::get<Literal>(std::move(literal)));
} }
else else
solAssert(false, "Case or default case expected."); solAssert(false, "Case or default case expected.");
@ -311,12 +311,12 @@ Expression Parser::parseExpression()
RecursionGuard recursionGuard(*this); RecursionGuard recursionGuard(*this);
ElementaryOperation operation = parseElementaryOperation(); ElementaryOperation operation = parseElementaryOperation();
if (operation.type() == typeid(FunctionCall)) if (holds_alternative<FunctionCall>(operation))
return parseCall(std::move(operation)); return parseCall(std::move(operation));
else if (operation.type() == typeid(Instruction)) else if (holds_alternative<Instruction>(operation))
{ {
solAssert(m_dialect.flavour == AsmFlavour::Loose, ""); solAssert(m_dialect.flavour == AsmFlavour::Loose, "");
Instruction const& instr = boost::get<Instruction>(operation); Instruction const& instr = std::get<Instruction>(operation);
// Disallow instructions returning multiple values (and DUP/SWAP) as expression. // Disallow instructions returning multiple values (and DUP/SWAP) as expression.
if ( if (
instructionInfo(instr.instruction).ret != 1 || instructionInfo(instr.instruction).ret != 1 ||
@ -345,19 +345,19 @@ Expression Parser::parseExpression()
} }
if (currentToken() == Token::LParen) if (currentToken() == Token::LParen)
return parseCall(std::move(operation)); return parseCall(std::move(operation));
else if (operation.type() == typeid(Instruction)) else if (holds_alternative<Instruction>(operation))
{ {
// Instructions not taking arguments are allowed as expressions. // Instructions not taking arguments are allowed as expressions.
solAssert(m_dialect.flavour == AsmFlavour::Loose, ""); solAssert(m_dialect.flavour == AsmFlavour::Loose, "");
Instruction& instr = boost::get<Instruction>(operation); Instruction& instr = std::get<Instruction>(operation);
return FunctionalInstruction{std::move(instr.location), instr.instruction, {}}; return FunctionalInstruction{std::move(instr.location), instr.instruction, {}};
} }
else if (operation.type() == typeid(Identifier)) else if (holds_alternative<Identifier>(operation))
return boost::get<Identifier>(operation); return std::get<Identifier>(operation);
else else
{ {
solAssert(operation.type() == typeid(Literal), ""); solAssert(holds_alternative<Literal>(operation), "");
return boost::get<Literal>(operation); return std::get<Literal>(operation);
} }
} }
@ -537,10 +537,10 @@ FunctionDefinition Parser::parseFunctionDefinition()
Expression Parser::parseCall(Parser::ElementaryOperation&& _initialOp) Expression Parser::parseCall(Parser::ElementaryOperation&& _initialOp)
{ {
RecursionGuard recursionGuard(*this); RecursionGuard recursionGuard(*this);
if (_initialOp.type() == typeid(Instruction)) if (holds_alternative<Instruction>(_initialOp))
{ {
solAssert(m_dialect.flavour != AsmFlavour::Yul, "Instructions are invalid in Yul"); solAssert(m_dialect.flavour != AsmFlavour::Yul, "Instructions are invalid in Yul");
Instruction& instruction = boost::get<Instruction>(_initialOp); Instruction& instruction = std::get<Instruction>(_initialOp);
FunctionalInstruction ret; FunctionalInstruction ret;
ret.instruction = instruction.instruction; ret.instruction = instruction.instruction;
ret.location = std::move(instruction.location); ret.location = std::move(instruction.location);
@ -591,16 +591,16 @@ Expression Parser::parseCall(Parser::ElementaryOperation&& _initialOp)
expectToken(Token::RParen); expectToken(Token::RParen);
return ret; return ret;
} }
else if (_initialOp.type() == typeid(Identifier) || _initialOp.type() == typeid(FunctionCall)) else if (holds_alternative<Identifier>(_initialOp) || holds_alternative<FunctionCall>(_initialOp))
{ {
FunctionCall ret; FunctionCall ret;
if (_initialOp.type() == typeid(Identifier)) if (holds_alternative<Identifier>(_initialOp))
{ {
ret.functionName = std::move(boost::get<Identifier>(_initialOp)); ret.functionName = std::move(std::get<Identifier>(_initialOp));
ret.location = ret.functionName.location; ret.location = ret.functionName.location;
} }
else else
ret = std::move(boost::get<FunctionCall>(_initialOp)); ret = std::move(std::get<FunctionCall>(_initialOp));
expectToken(Token::LParen); expectToken(Token::LParen);
if (currentToken() != Token::RParen) if (currentToken() != Token::RParen)
{ {

View File

@ -30,9 +30,9 @@
#include <liblangutil/ParserBase.h> #include <liblangutil/ParserBase.h>
#include <memory> #include <memory>
#include <variant>
#include <vector> #include <vector>
namespace yul namespace yul
{ {
@ -56,7 +56,7 @@ public:
static std::map<std::string, dev::eth::Instruction> const& instructions(); static std::map<std::string, dev::eth::Instruction> const& instructions();
protected: protected:
using ElementaryOperation = boost::variant<Instruction, Literal, Identifier, FunctionCall>; using ElementaryOperation = std::variant<Instruction, Literal, Identifier, FunctionCall>;
/// Creates an inline assembly node with the given source location. /// Creates an inline assembly node with the given source location.
template <class T> T createWithLocation(langutil::SourceLocation const& _loc = {}) const template <class T> T createWithLocation(langutil::SourceLocation const& _loc = {}) const

View File

@ -103,14 +103,15 @@ string AsmPrinter::operator()(FunctionalInstruction const& _functionalInstructio
boost::to_lower_copy(instructionInfo(_functionalInstruction.instruction).name) + boost::to_lower_copy(instructionInfo(_functionalInstruction.instruction).name) +
"(" + "(" +
boost::algorithm::join( boost::algorithm::join(
_functionalInstruction.arguments | boost::adaptors::transformed(boost::apply_visitor(*this)), _functionalInstruction.arguments | boost::adaptors::transformed([&](auto&& _node) { return std::visit(*this, _node); }),
", ") + ", "
) +
")"; ")";
} }
string AsmPrinter::operator()(ExpressionStatement const& _statement) const string AsmPrinter::operator()(ExpressionStatement const& _statement) const
{ {
return boost::apply_visitor(*this, _statement.expression); return std::visit(*this, _statement.expression);
} }
string AsmPrinter::operator()(Label const& _label) const string AsmPrinter::operator()(Label const& _label) const
@ -133,7 +134,7 @@ string AsmPrinter::operator()(Assignment const& _assignment) const
string variables = (*this)(_assignment.variableNames.front()); string variables = (*this)(_assignment.variableNames.front());
for (size_t i = 1; i < _assignment.variableNames.size(); ++i) for (size_t i = 1; i < _assignment.variableNames.size(); ++i)
variables += ", " + (*this)(_assignment.variableNames[i]); variables += ", " + (*this)(_assignment.variableNames[i]);
return variables + " := " + boost::apply_visitor(*this, *_assignment.value); return variables + " := " + std::visit(*this, *_assignment.value);
} }
string AsmPrinter::operator()(VariableDeclaration const& _variableDeclaration) const string AsmPrinter::operator()(VariableDeclaration const& _variableDeclaration) const
@ -148,7 +149,7 @@ string AsmPrinter::operator()(VariableDeclaration const& _variableDeclaration) c
if (_variableDeclaration.value) if (_variableDeclaration.value)
{ {
out += " := "; out += " := ";
out += boost::apply_visitor(*this, *_variableDeclaration.value); out += std::visit(*this, *_variableDeclaration.value);
} }
return out; return out;
} }
@ -183,7 +184,7 @@ string AsmPrinter::operator()(FunctionCall const& _functionCall) const
return return
(*this)(_functionCall.functionName) + "(" + (*this)(_functionCall.functionName) + "(" +
boost::algorithm::join( boost::algorithm::join(
_functionCall.arguments | boost::adaptors::transformed(boost::apply_visitor(*this)), _functionCall.arguments | boost::adaptors::transformed([&](auto&& _node) { return std::visit(*this, _node); }),
", " ) + ", " ) +
")"; ")";
} }
@ -195,13 +196,13 @@ string AsmPrinter::operator()(If const& _if) const
char delim = '\n'; char delim = '\n';
if (body.find('\n') == string::npos) if (body.find('\n') == string::npos)
delim = ' '; delim = ' ';
return "if " + boost::apply_visitor(*this, *_if.condition) + delim + (*this)(_if.body); return "if " + std::visit(*this, *_if.condition) + delim + (*this)(_if.body);
} }
string AsmPrinter::operator()(Switch const& _switch) const string AsmPrinter::operator()(Switch const& _switch) const
{ {
solAssert(_switch.expression, "Invalid expression pointer."); solAssert(_switch.expression, "Invalid expression pointer.");
string out = "switch " + boost::apply_visitor(*this, *_switch.expression); string out = "switch " + std::visit(*this, *_switch.expression);
for (auto const& _case: _switch.cases) for (auto const& _case: _switch.cases)
{ {
if (!_case.value) if (!_case.value)
@ -217,7 +218,7 @@ string AsmPrinter::operator()(ForLoop const& _forLoop) const
{ {
solAssert(_forLoop.condition, "Invalid for loop condition."); solAssert(_forLoop.condition, "Invalid for loop condition.");
string pre = (*this)(_forLoop.pre); string pre = (*this)(_forLoop.pre);
string condition = boost::apply_visitor(*this, *_forLoop.condition); string condition = std::visit(*this, *_forLoop.condition);
string post = (*this)(_forLoop.post); string post = (*this)(_forLoop.post);
char delim = '\n'; char delim = '\n';
if ( if (
@ -246,7 +247,7 @@ string AsmPrinter::operator()(Block const& _block) const
if (_block.statements.empty()) if (_block.statements.empty())
return "{ }"; return "{ }";
string body = boost::algorithm::join( string body = boost::algorithm::join(
_block.statements | boost::adaptors::transformed(boost::apply_visitor(*this)), _block.statements | boost::adaptors::transformed([&](auto&& _node) { return std::visit(*this, _node); }),
"\n" "\n"
); );
if (body.size() < 30 && body.find('\n') == string::npos) if (body.size() < 30 && body.find('\n') == string::npos)

View File

@ -26,12 +26,10 @@
#include <libyul/YulString.h> #include <libyul/YulString.h>
#include <boost/variant.hpp>
namespace yul namespace yul
{ {
class AsmPrinter: public boost::static_visitor<std::string> class AsmPrinter
{ {
public: public:
explicit AsmPrinter(bool _yul = false): m_yul(_yul) {} explicit AsmPrinter(bool _yul = false): m_yul(_yul) {}

View File

@ -58,7 +58,7 @@ Scope::Identifier* Scope::lookup(YulString _name)
auto id = s->identifiers.find(_name); auto id = s->identifiers.find(_name);
if (id != s->identifiers.end()) if (id != s->identifiers.end())
{ {
if (crossedFunctionBoundary && id->second.type() == typeid(Scope::Variable)) if (crossedFunctionBoundary && holds_alternative<Scope::Variable>(id->second))
return nullptr; return nullptr;
else else
return &id->second; return &id->second;
@ -84,7 +84,7 @@ size_t Scope::numberOfVariables() const
{ {
size_t count = 0; size_t count = 0;
for (auto const& identifier: identifiers) for (auto const& identifier: identifiers)
if (identifier.second.type() == typeid(Scope::Variable)) if (holds_alternative<Scope::Variable>(identifier.second))
count++; count++;
return count; return count;
} }

View File

@ -26,11 +26,10 @@
#include <libdevcore/Visitor.h> #include <libdevcore/Visitor.h>
#include <boost/variant.hpp>
#include <functional> #include <functional>
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <variant>
namespace yul namespace yul
{ {
@ -48,7 +47,7 @@ struct Scope
std::vector<YulType> returns; std::vector<YulType> returns;
}; };
using Identifier = boost::variant<Variable, Label, Function>; using Identifier = std::variant<Variable, Label, Function>;
using Visitor = dev::GenericVisitor<Variable const, Label const, Function const>; using Visitor = dev::GenericVisitor<Variable const, Label const, Function const>;
using NonconstVisitor = dev::GenericVisitor<Variable, Label, Function>; using NonconstVisitor = dev::GenericVisitor<Variable, Label, Function>;
@ -74,7 +73,7 @@ struct Scope
{ {
if (Identifier* id = lookup(_name)) if (Identifier* id = lookup(_name))
{ {
boost::apply_visitor(_visitor, *id); std::visit(_visitor, *id);
return true; return true;
} }
else else

View File

@ -47,7 +47,7 @@ ScopeFiller::ScopeFiller(AsmAnalysisInfo& _info, ErrorReporter& _errorReporter):
bool ScopeFiller::operator()(ExpressionStatement const& _expr) bool ScopeFiller::operator()(ExpressionStatement const& _expr)
{ {
return boost::apply_visitor(*this, _expr.expression); return std::visit(*this, _expr.expression);
} }
bool ScopeFiller::operator()(Label const& _item) bool ScopeFiller::operator()(Label const& _item)
@ -116,7 +116,7 @@ bool ScopeFiller::operator()(ForLoop const& _forLoop)
if (!(*this)(_forLoop.pre)) if (!(*this)(_forLoop.pre))
success = false; success = false;
m_currentScope = &scope(&_forLoop.pre); m_currentScope = &scope(&_forLoop.pre);
if (!boost::apply_visitor(*this, *_forLoop.condition)) if (!std::visit(*this, *_forLoop.condition))
success = false; success = false;
if (!(*this)(_forLoop.body)) if (!(*this)(_forLoop.body))
success = false; success = false;
@ -137,11 +137,11 @@ bool ScopeFiller::operator()(Block const& _block)
// First visit all functions to make them create // First visit all functions to make them create
// an entry in the scope according to their visibility. // an entry in the scope according to their visibility.
for (auto const& s: _block.statements) for (auto const& s: _block.statements)
if (s.type() == typeid(FunctionDefinition)) if (holds_alternative<FunctionDefinition>(s))
if (!registerFunction(boost::get<FunctionDefinition>(s))) if (!registerFunction(std::get<FunctionDefinition>(s)))
success = false; success = false;
for (auto const& s: _block.statements) for (auto const& s: _block.statements)
if (!boost::apply_visitor(*this, s)) if (!std::visit(*this, s))
success = false; success = false;
m_currentScope = m_currentScope->superScope; m_currentScope = m_currentScope->superScope;

View File

@ -22,8 +22,6 @@
#include <libyul/AsmDataForward.h> #include <libyul/AsmDataForward.h>
#include <boost/variant.hpp>
#include <functional> #include <functional>
#include <memory> #include <memory>
@ -44,7 +42,7 @@ struct AsmAnalysisInfo;
* Fills scopes with identifiers and checks for name clashes. * Fills scopes with identifiers and checks for name clashes.
* Does not resolve references. * Does not resolve references.
*/ */
class ScopeFiller: public boost::static_visitor<bool> class ScopeFiller
{ {
public: public:
ScopeFiller(AsmAnalysisInfo& _info, langutil::ErrorReporter& _errorReporter); ScopeFiller(AsmAnalysisInfo& _info, langutil::ErrorReporter& _errorReporter);

View File

@ -27,6 +27,8 @@
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
#include <variant>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace yul; using namespace yul;
@ -35,13 +37,13 @@ using Representation = ConstantOptimiser::Representation;
namespace namespace
{ {
struct MiniEVMInterpreter: boost::static_visitor<u256> struct MiniEVMInterpreter
{ {
explicit MiniEVMInterpreter(EVMDialect const& _dialect): m_dialect(_dialect) {} explicit MiniEVMInterpreter(EVMDialect const& _dialect): m_dialect(_dialect) {}
u256 eval(Expression const& _expr) u256 eval(Expression const& _expr)
{ {
return boost::apply_visitor(*this, _expr); return std::visit(*this, _expr);
} }
u256 eval(dev::eth::Instruction _instr, vector<Expression> const& _arguments) u256 eval(dev::eth::Instruction _instr, vector<Expression> const& _arguments)
@ -92,9 +94,9 @@ struct MiniEVMInterpreter: boost::static_visitor<u256>
void ConstantOptimiser::visit(Expression& _e) void ConstantOptimiser::visit(Expression& _e)
{ {
if (_e.type() == typeid(Literal)) if (holds_alternative<Literal>(_e))
{ {
Literal const& literal = boost::get<Literal>(_e); Literal const& literal = std::get<Literal>(_e);
if (literal.kind != LiteralKind::Number) if (literal.kind != LiteralKind::Number)
return; return;
@ -115,7 +117,7 @@ Expression const* RepresentationFinder::tryFindRepresentation(dev::u256 const& _
return nullptr; return nullptr;
Representation const& repr = findRepresentation(_value); Representation const& repr = findRepresentation(_value);
if (repr.expression->type() == typeid(Literal)) if (holds_alternative<Literal>(*repr.expression))
return nullptr; return nullptr;
else else
return repr.expression.get(); return repr.expression.get();

View File

@ -29,6 +29,8 @@
#include <boost/range/adaptor/reversed.hpp> #include <boost/range/adaptor/reversed.hpp>
#include <variant>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace yul; using namespace yul;
@ -146,9 +148,9 @@ void CodeTransform::freeUnusedVariables()
return; return;
for (auto const& identifier: m_scope->identifiers) for (auto const& identifier: m_scope->identifiers)
if (identifier.second.type() == typeid(Scope::Variable)) if (holds_alternative<Scope::Variable>(identifier.second))
{ {
Scope::Variable const& var = boost::get<Scope::Variable>(identifier.second); Scope::Variable const& var = std::get<Scope::Variable>(identifier.second);
if (m_variablesScheduledForDeletion.count(&var)) if (m_variablesScheduledForDeletion.count(&var))
deleteVariable(var); deleteVariable(var);
} }
@ -179,7 +181,7 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl)
int height = m_assembly.stackHeight(); int height = m_assembly.stackHeight();
if (_varDecl.value) if (_varDecl.value)
{ {
boost::apply_visitor(*this, *_varDecl.value); std::visit(*this, *_varDecl.value);
expectDeposit(numVariables, height); expectDeposit(numVariables, height);
} }
else else
@ -193,7 +195,7 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl)
for (int varIndex = numVariables - 1; varIndex >= 0; --varIndex) for (int varIndex = numVariables - 1; varIndex >= 0; --varIndex)
{ {
YulString varName = _varDecl.variables[varIndex].name; YulString varName = _varDecl.variables[varIndex].name;
auto& var = boost::get<Scope::Variable>(m_scope->identifiers.at(varName)); auto& var = std::get<Scope::Variable>(m_scope->identifiers.at(varName));
m_context->variableStackHeights[&var] = height + varIndex; m_context->variableStackHeights[&var] = height + varIndex;
if (!m_allowStackOpt) if (!m_allowStackOpt)
continue; continue;
@ -242,7 +244,7 @@ void CodeTransform::stackError(StackTooDeepError _error, int _targetStackHeight)
void CodeTransform::operator()(Assignment const& _assignment) void CodeTransform::operator()(Assignment const& _assignment)
{ {
int height = m_assembly.stackHeight(); int height = m_assembly.stackHeight();
boost::apply_visitor(*this, *_assignment.value); std::visit(*this, *_assignment.value);
expectDeposit(_assignment.variableNames.size(), height); expectDeposit(_assignment.variableNames.size(), height);
m_assembly.setSourceLocation(_assignment.location); m_assembly.setSourceLocation(_assignment.location);
@ -261,7 +263,7 @@ void CodeTransform::operator()(StackAssignment const& _assignment)
void CodeTransform::operator()(ExpressionStatement const& _statement) void CodeTransform::operator()(ExpressionStatement const& _statement)
{ {
m_assembly.setSourceLocation(_statement.location); m_assembly.setSourceLocation(_statement.location);
boost::apply_visitor(*this, _statement.expression); std::visit(*this, _statement.expression);
checkStackHeight(&_statement); checkStackHeight(&_statement);
} }
@ -271,7 +273,7 @@ void CodeTransform::operator()(Label const& _label)
m_assembly.setSourceLocation(_label.location); m_assembly.setSourceLocation(_label.location);
solAssert(m_scope, ""); solAssert(m_scope, "");
solAssert(m_scope->identifiers.count(_label.name), ""); solAssert(m_scope->identifiers.count(_label.name), "");
Scope::Label& label = boost::get<Scope::Label>(m_scope->identifiers.at(_label.name)); Scope::Label& label = std::get<Scope::Label>(m_scope->identifiers.at(_label.name));
m_assembly.appendLabel(labelID(label)); m_assembly.appendLabel(labelID(label));
checkStackHeight(&_label); checkStackHeight(&_label);
} }
@ -340,7 +342,7 @@ void CodeTransform::operator()(FunctionalInstruction const& _instruction)
solAssert(_instruction.arguments.size() == 1, ""); solAssert(_instruction.arguments.size() == 1, "");
} }
m_assembly.setSourceLocation(_instruction.location); m_assembly.setSourceLocation(_instruction.location);
auto label = labelFromIdentifier(boost::get<Identifier>(_instruction.arguments.at(0))); auto label = labelFromIdentifier(std::get<Identifier>(_instruction.arguments.at(0)));
if (isJumpI) if (isJumpI)
m_assembly.appendJumpToIf(label); m_assembly.appendJumpToIf(label);
else else
@ -476,7 +478,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
{ {
solAssert(m_scope, ""); solAssert(m_scope, "");
solAssert(m_scope->identifiers.count(_function.name), ""); solAssert(m_scope->identifiers.count(_function.name), "");
Scope::Function& function = boost::get<Scope::Function>(m_scope->identifiers.at(_function.name)); Scope::Function& function = std::get<Scope::Function>(m_scope->identifiers.at(_function.name));
int const localStackAdjustment = m_evm15 ? 0 : 1; int const localStackAdjustment = m_evm15 ? 0 : 1;
int height = localStackAdjustment; int height = localStackAdjustment;
@ -485,7 +487,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
solAssert(varScope, ""); solAssert(varScope, "");
for (auto const& v: _function.parameters | boost::adaptors::reversed) for (auto const& v: _function.parameters | boost::adaptors::reversed)
{ {
auto& var = boost::get<Scope::Variable>(varScope->identifiers.at(v.name)); auto& var = std::get<Scope::Variable>(varScope->identifiers.at(v.name));
m_context->variableStackHeights[&var] = height++; m_context->variableStackHeights[&var] = height++;
} }
@ -503,7 +505,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
for (auto const& v: _function.returnVariables) for (auto const& v: _function.returnVariables)
{ {
auto& var = boost::get<Scope::Variable>(varScope->identifiers.at(v.name)); auto& var = std::get<Scope::Variable>(varScope->identifiers.at(v.name));
m_context->variableStackHeights[&var] = height++; m_context->variableStackHeights[&var] = height++;
// Preset stack slots for return variables to zero. // Preset stack slots for return variables to zero.
m_assembly.appendConstant(u256(0)); m_assembly.appendConstant(u256(0));
@ -717,7 +719,7 @@ AbstractAssembly::LabelID CodeTransform::functionEntryID(YulString _name, Scope:
void CodeTransform::visitExpression(Expression const& _expression) void CodeTransform::visitExpression(Expression const& _expression)
{ {
int height = m_assembly.stackHeight(); int height = m_assembly.stackHeight();
boost::apply_visitor(*this, _expression); std::visit(*this, _expression);
expectDeposit(1, height); expectDeposit(1, height);
} }
@ -728,7 +730,7 @@ void CodeTransform::visitStatements(vector<Statement> const& _statements)
for (auto const& statement: _statements) for (auto const& statement: _statements)
{ {
freeUnusedVariables(); freeUnusedVariables();
auto const* functionDefinition = boost::get<FunctionDefinition>(&statement); auto const* functionDefinition = std::get_if<FunctionDefinition>(&statement);
if (functionDefinition && !jumpTarget) if (functionDefinition && !jumpTarget)
{ {
m_assembly.setSourceLocation(locationOf(statement)); m_assembly.setSourceLocation(locationOf(statement));
@ -741,7 +743,7 @@ void CodeTransform::visitStatements(vector<Statement> const& _statements)
jumpTarget = std::nullopt; jumpTarget = std::nullopt;
} }
boost::apply_visitor(*this, statement); std::visit(*this, statement);
} }
// we may have a leftover jumpTarget // we may have a leftover jumpTarget
if (jumpTarget) if (jumpTarget)
@ -759,9 +761,9 @@ void CodeTransform::finalizeBlock(Block const& _block, int blockStartStackHeight
// pop variables // pop variables
solAssert(m_info.scopes.at(&_block).get() == m_scope, ""); solAssert(m_info.scopes.at(&_block).get() == m_scope, "");
for (auto const& id: m_scope->identifiers) for (auto const& id: m_scope->identifiers)
if (id.second.type() == typeid(Scope::Variable)) if (holds_alternative<Scope::Variable>(id.second))
{ {
Scope::Variable const& var = boost::get<Scope::Variable>(id.second); Scope::Variable const& var = std::get<Scope::Variable>(id.second);
if (m_allowStackOpt) if (m_allowStackOpt)
{ {
solAssert(!m_context->variableStackHeights.count(&var), ""); solAssert(!m_context->variableStackHeights.count(&var), "");
@ -789,7 +791,7 @@ void CodeTransform::generateAssignment(Identifier const& _variableName)
solAssert(m_scope, ""); solAssert(m_scope, "");
if (auto var = m_scope->lookup(_variableName.name)) if (auto var = m_scope->lookup(_variableName.name))
{ {
Scope::Variable const& _var = boost::get<Scope::Variable>(*var); Scope::Variable const& _var = std::get<Scope::Variable>(*var);
if (int heightDiff = variableHeightDiff(_var, _variableName.name, true)) if (int heightDiff = variableHeightDiff(_var, _variableName.name, true))
m_assembly.appendInstruction(dev::eth::swapInstruction(heightDiff - 1)); m_assembly.appendInstruction(dev::eth::swapInstruction(heightDiff - 1));
m_assembly.appendInstruction(dev::eth::Instruction::POP); m_assembly.appendInstruction(dev::eth::Instruction::POP);

View File

@ -27,8 +27,6 @@
#include <libyul/AsmDataForward.h> #include <libyul/AsmDataForward.h>
#include <libyul/AsmScope.h> #include <libyul/AsmScope.h>
#include <boost/variant.hpp>
#include <optional> #include <optional>
#include <stack> #include <stack>
@ -107,7 +105,7 @@ private:
Scope* m_scope = nullptr; Scope* m_scope = nullptr;
}; };
class CodeTransform: public boost::static_visitor<> class CodeTransform
{ {
public: public:
/// Create the code transformer. /// Create the code transformer.

View File

@ -113,7 +113,7 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe
yulAssert(_context.currentObject, "No object available."); yulAssert(_context.currentObject, "No object available.");
yulAssert(_call.arguments.size() == 1, ""); yulAssert(_call.arguments.size() == 1, "");
Expression const& arg = _call.arguments.front(); Expression const& arg = _call.arguments.front();
YulString dataName = boost::get<Literal>(arg).value; YulString dataName = std::get<Literal>(arg).value;
if (_context.currentObject->name == dataName) if (_context.currentObject->name == dataName)
_assembly.appendAssemblySize(); _assembly.appendAssemblySize();
else else
@ -134,7 +134,7 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe
yulAssert(_context.currentObject, "No object available."); yulAssert(_context.currentObject, "No object available.");
yulAssert(_call.arguments.size() == 1, ""); yulAssert(_call.arguments.size() == 1, "");
Expression const& arg = _call.arguments.front(); Expression const& arg = _call.arguments.front();
YulString dataName = boost::get<Literal>(arg).value; YulString dataName = std::get<Literal>(arg).value;
if (_context.currentObject->name == dataName) if (_context.currentObject->name == dataName)
_assembly.appendConstant(0); _assembly.appendConstant(0);
else else

View File

@ -298,12 +298,12 @@ bytes BinaryTransform::operator()(BuiltinCall const& _call)
// they are references to object names that should not end up in the code. // they are references to object names that should not end up in the code.
if (_call.functionName == "dataoffset") if (_call.functionName == "dataoffset")
{ {
string name = boost::get<StringLiteral>(_call.arguments.at(0)).value; string name = std::get<StringLiteral>(_call.arguments.at(0)).value;
return toBytes(Opcode::I64Const) + lebEncodeSigned(m_subModulePosAndSize.at(name).first); return toBytes(Opcode::I64Const) + lebEncodeSigned(m_subModulePosAndSize.at(name).first);
} }
else if (_call.functionName == "datasize") else if (_call.functionName == "datasize")
{ {
string name = boost::get<StringLiteral>(_call.arguments.at(0)).value; string name = std::get<StringLiteral>(_call.arguments.at(0)).value;
return toBytes(Opcode::I64Const) + lebEncodeSigned(m_subModulePosAndSize.at(name).second); return toBytes(Opcode::I64Const) + lebEncodeSigned(m_subModulePosAndSize.at(name).second);
} }
@ -333,7 +333,7 @@ bytes BinaryTransform::operator()(FunctionCall const& _call)
bytes BinaryTransform::operator()(LocalAssignment const& _assignment) bytes BinaryTransform::operator()(LocalAssignment const& _assignment)
{ {
return return
boost::apply_visitor(*this, *_assignment.value) + std::visit(*this, *_assignment.value) +
toBytes(Opcode::LocalSet) + toBytes(Opcode::LocalSet) +
lebEncode(m_locals.at(_assignment.variableName)); lebEncode(m_locals.at(_assignment.variableName));
} }
@ -341,7 +341,7 @@ bytes BinaryTransform::operator()(LocalAssignment const& _assignment)
bytes BinaryTransform::operator()(GlobalAssignment const& _assignment) bytes BinaryTransform::operator()(GlobalAssignment const& _assignment)
{ {
return return
boost::apply_visitor(*this, *_assignment.value) + std::visit(*this, *_assignment.value) +
toBytes(Opcode::GlobalSet) + toBytes(Opcode::GlobalSet) +
lebEncode(m_globals.at(_assignment.variableName)); lebEncode(m_globals.at(_assignment.variableName));
} }
@ -349,7 +349,7 @@ bytes BinaryTransform::operator()(GlobalAssignment const& _assignment)
bytes BinaryTransform::operator()(If const& _if) bytes BinaryTransform::operator()(If const& _if)
{ {
bytes result = bytes result =
boost::apply_visitor(*this, *_if.condition) + std::visit(*this, *_if.condition) +
toBytes(Opcode::If) + toBytes(Opcode::If) +
toBytes(ValueType::Void); toBytes(ValueType::Void);
@ -559,7 +559,7 @@ bytes BinaryTransform::visit(vector<Expression> const& _expressions)
{ {
bytes result; bytes result;
for (auto const& expr: _expressions) for (auto const& expr: _expressions)
result += boost::apply_visitor(*this, expr); result += std::visit(*this, expr);
return result; return result;
} }
@ -567,7 +567,7 @@ bytes BinaryTransform::visitReversed(vector<Expression> const& _expressions)
{ {
bytes result; bytes result;
for (auto const& expr: _expressions | boost::adaptors::reversed) for (auto const& expr: _expressions | boost::adaptors::reversed)
result += boost::apply_visitor(*this, expr); result += std::visit(*this, expr);
return result; return result;
} }

View File

@ -35,7 +35,7 @@ namespace wasm
/** /**
* Web assembly to binary transform. * Web assembly to binary transform.
*/ */
class BinaryTransform: public boost::static_visitor<dev::bytes> class BinaryTransform
{ {
public: public:
static dev::bytes run(Module const& _module); static dev::bytes run(Module const& _module);

View File

@ -694,7 +694,7 @@ Object EVMToEWasmTranslator::run(Object const& _object)
if (!m_polyfill) if (!m_polyfill)
parsePolyfill(); parsePolyfill();
Block ast = boost::get<Block>(Disambiguator(m_dialect, *_object.analysisInfo)(*_object.code)); Block ast = std::get<Block>(Disambiguator(m_dialect, *_object.analysisInfo)(*_object.code));
set<YulString> reservedIdentifiers; set<YulString> reservedIdentifiers;
NameDispenser nameDispenser{m_dialect, ast, reservedIdentifiers}; NameDispenser nameDispenser{m_dialect, ast, reservedIdentifiers};
OptimiserStepContext context{m_dialect, nameDispenser, reservedIdentifiers}; OptimiserStepContext context{m_dialect, nameDispenser, reservedIdentifiers};
@ -752,6 +752,6 @@ void EVMToEWasmTranslator::parsePolyfill()
m_polyfillFunctions.clear(); m_polyfillFunctions.clear();
for (auto const& statement: m_polyfill->statements) for (auto const& statement: m_polyfill->statements)
m_polyfillFunctions.insert(boost::get<FunctionDefinition>(statement).name); m_polyfillFunctions.insert(std::get<FunctionDefinition>(statement).name);
} }

View File

@ -20,7 +20,7 @@
#pragma once #pragma once
#include <boost/variant.hpp> #include <variant>
#include <string> #include <string>
#include <vector> #include <vector>
#include <map> #include <map>
@ -44,7 +44,7 @@ struct If;
struct Loop; struct Loop;
struct Break; struct Break;
struct BreakIf; struct BreakIf;
using Expression = boost::variant< using Expression = std::variant<
Literal, StringLiteral, LocalVariable, GlobalVariable, Literal, StringLiteral, LocalVariable, GlobalVariable,
FunctionCall, BuiltinCall, LocalAssignment, GlobalAssignment, FunctionCall, BuiltinCall, LocalAssignment, GlobalAssignment,
Block, If, Loop, Break, BreakIf Block, If, Loop, Break, BreakIf

View File

@ -45,11 +45,11 @@ wasm::Module EWasmCodeTransform::run(Dialect const& _dialect, yul::Block const&
for (auto const& statement: _ast.statements) for (auto const& statement: _ast.statements)
{ {
yulAssert( yulAssert(
statement.type() == typeid(yul::FunctionDefinition), holds_alternative<yul::FunctionDefinition>(statement),
"Expected only function definitions at the highest level." "Expected only function definitions at the highest level."
); );
if (statement.type() == typeid(yul::FunctionDefinition)) if (holds_alternative<yul::FunctionDefinition>(statement))
module.functions.emplace_back(transform.translateFunction(boost::get<yul::FunctionDefinition>(statement))); module.functions.emplace_back(transform.translateFunction(std::get<yul::FunctionDefinition>(statement)));
} }
for (auto& imp: transform.m_functionsToImport) for (auto& imp: transform.m_functionsToImport)
@ -157,7 +157,7 @@ wasm::Expression EWasmCodeTransform::operator()(FunctionCall const& _call)
{ {
vector<wasm::Expression> literals; vector<wasm::Expression> literals;
for (auto const& arg: _call.arguments) for (auto const& arg: _call.arguments)
literals.emplace_back(wasm::StringLiteral{boost::get<Literal>(arg).value.str()}); literals.emplace_back(wasm::StringLiteral{std::get<Literal>(arg).value.str()});
return wasm::BuiltinCall{_call.functionName.name.str(), std::move(literals)}; return wasm::BuiltinCall{_call.functionName.name.str(), std::move(literals)};
} }
else else
@ -303,12 +303,12 @@ wasm::Expression EWasmCodeTransform::operator()(Block const& _block)
unique_ptr<wasm::Expression> EWasmCodeTransform::visit(yul::Expression const& _expression) unique_ptr<wasm::Expression> EWasmCodeTransform::visit(yul::Expression const& _expression)
{ {
return make_unique<wasm::Expression>(boost::apply_visitor(*this, _expression)); return make_unique<wasm::Expression>(std::visit(*this, _expression));
} }
wasm::Expression EWasmCodeTransform::visitReturnByValue(yul::Expression const& _expression) wasm::Expression EWasmCodeTransform::visitReturnByValue(yul::Expression const& _expression)
{ {
return boost::apply_visitor(*this, _expression); return std::visit(*this, _expression);
} }
vector<wasm::Expression> EWasmCodeTransform::visit(vector<yul::Expression> const& _expressions) vector<wasm::Expression> EWasmCodeTransform::visit(vector<yul::Expression> const& _expressions)
@ -321,7 +321,7 @@ vector<wasm::Expression> EWasmCodeTransform::visit(vector<yul::Expression> const
wasm::Expression EWasmCodeTransform::visit(yul::Statement const& _statement) wasm::Expression EWasmCodeTransform::visit(yul::Statement const& _statement)
{ {
return boost::apply_visitor(*this, _statement); return std::visit(*this, _statement);
} }
vector<wasm::Expression> EWasmCodeTransform::visit(vector<yul::Statement> const& _statements) vector<wasm::Expression> EWasmCodeTransform::visit(vector<yul::Statement> const& _statements)

View File

@ -32,7 +32,7 @@ namespace yul
{ {
struct AsmAnalysisInfo; struct AsmAnalysisInfo;
class EWasmCodeTransform: public boost::static_visitor<wasm::Expression> class EWasmCodeTransform
{ {
public: public:
static wasm::Module run(Dialect const& _dialect, yul::Block const& _ast); static wasm::Module run(Dialect const& _dialect, yul::Block const& _ast);

View File

@ -171,7 +171,7 @@ string EWasmToText::transform(wasm::FunctionDefinition const& _function)
string EWasmToText::visit(wasm::Expression const& _expression) string EWasmToText::visit(wasm::Expression const& _expression)
{ {
return boost::apply_visitor(*this, _expression); return std::visit(*this, _expression);
} }
string EWasmToText::joinTransformed(vector<wasm::Expression> const& _expressions, char _separator) string EWasmToText::joinTransformed(vector<wasm::Expression> const& _expressions, char _separator)

View File

@ -28,7 +28,7 @@ namespace yul
{ {
struct AsmAnalysisInfo; struct AsmAnalysisInfo;
class EWasmToText: public boost::static_visitor<std::string> class EWasmToText
{ {
public: public:
std::string run(wasm::Module const& _module); std::string run(wasm::Module const& _module);

View File

@ -25,6 +25,7 @@
#include <array> #include <array>
#include <map> #include <map>
#include <variant>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -84,13 +85,13 @@ void WordSizeTransform::operator()(Block& _block)
_block.statements, _block.statements,
[&](Statement& _s) -> std::optional<vector<Statement>> [&](Statement& _s) -> std::optional<vector<Statement>>
{ {
if (_s.type() == typeid(VariableDeclaration)) if (holds_alternative<VariableDeclaration>(_s))
{ {
VariableDeclaration& varDecl = boost::get<VariableDeclaration>(_s); VariableDeclaration& varDecl = std::get<VariableDeclaration>(_s);
// Special handling for datasize and dataoffset - they will only need one variable. // Special handling for datasize and dataoffset - they will only need one variable.
if (varDecl.value && varDecl.value->type() == typeid(FunctionCall)) if (varDecl.value && holds_alternative<FunctionCall>(*varDecl.value))
if (BuiltinFunction const* f = m_inputDialect.builtin(boost::get<FunctionCall>(*varDecl.value).functionName.name)) if (BuiltinFunction const* f = m_inputDialect.builtin(std::get<FunctionCall>(*varDecl.value).functionName.name))
if (f->literalArguments) if (f->literalArguments)
{ {
yulAssert(f->name == "datasize"_yulstring || f->name == "dataoffset"_yulstring, ""); yulAssert(f->name == "datasize"_yulstring || f->name == "dataoffset"_yulstring, "");
@ -113,8 +114,8 @@ void WordSizeTransform::operator()(Block& _block)
if ( if (
!varDecl.value || !varDecl.value ||
varDecl.value->type() == typeid(FunctionalInstruction) || holds_alternative<FunctionalInstruction>(*varDecl.value) ||
varDecl.value->type() == typeid(FunctionCall) holds_alternative<FunctionCall>(*varDecl.value)
) )
{ {
if (varDecl.value) visit(*varDecl.value); if (varDecl.value) visit(*varDecl.value);
@ -122,8 +123,8 @@ void WordSizeTransform::operator()(Block& _block)
return std::nullopt; return std::nullopt;
} }
else if ( else if (
varDecl.value->type() == typeid(Identifier) || holds_alternative<Identifier>(*varDecl.value) ||
varDecl.value->type() == typeid(Literal) holds_alternative<Literal>(*varDecl.value)
) )
{ {
yulAssert(varDecl.variables.size() == 1, ""); yulAssert(varDecl.variables.size() == 1, "");
@ -143,14 +144,14 @@ void WordSizeTransform::operator()(Block& _block)
else else
yulAssert(false, ""); yulAssert(false, "");
} }
else if (_s.type() == typeid(Assignment)) else if (holds_alternative<Assignment>(_s))
{ {
Assignment& assignment = boost::get<Assignment>(_s); Assignment& assignment = std::get<Assignment>(_s);
yulAssert(assignment.value, ""); yulAssert(assignment.value, "");
// Special handling for datasize and dataoffset - they will only need one variable. // Special handling for datasize and dataoffset - they will only need one variable.
if (assignment.value->type() == typeid(FunctionCall)) if (holds_alternative<FunctionCall>(*assignment.value))
if (BuiltinFunction const* f = m_inputDialect.builtin(boost::get<FunctionCall>(*assignment.value).functionName.name)) if (BuiltinFunction const* f = m_inputDialect.builtin(std::get<FunctionCall>(*assignment.value).functionName.name))
if (f->literalArguments) if (f->literalArguments)
{ {
yulAssert(f->name == "datasize"_yulstring || f->name == "dataoffset"_yulstring, ""); yulAssert(f->name == "datasize"_yulstring || f->name == "dataoffset"_yulstring, "");
@ -172,8 +173,8 @@ void WordSizeTransform::operator()(Block& _block)
} }
if ( if (
assignment.value->type() == typeid(FunctionalInstruction) || holds_alternative<FunctionalInstruction>(*assignment.value) ||
assignment.value->type() == typeid(FunctionCall) holds_alternative<FunctionCall>(*assignment.value)
) )
{ {
if (assignment.value) visit(*assignment.value); if (assignment.value) visit(*assignment.value);
@ -181,8 +182,8 @@ void WordSizeTransform::operator()(Block& _block)
return std::nullopt; return std::nullopt;
} }
else if ( else if (
assignment.value->type() == typeid(Identifier) || holds_alternative<Identifier>(*assignment.value) ||
assignment.value->type() == typeid(Literal) holds_alternative<Literal>(*assignment.value)
) )
{ {
yulAssert(assignment.variableNames.size() == 1, ""); yulAssert(assignment.variableNames.size() == 1, "");
@ -202,8 +203,8 @@ void WordSizeTransform::operator()(Block& _block)
else else
yulAssert(false, ""); yulAssert(false, "");
} }
else if (_s.type() == typeid(Switch)) else if (holds_alternative<Switch>(_s))
return handleSwitch(boost::get<Switch>(_s)); return handleSwitch(std::get<Switch>(_s));
else else
visit(_s); visit(_s);
return std::nullopt; return std::nullopt;
@ -342,7 +343,7 @@ std::vector<Statement> WordSizeTransform::handleSwitch(Switch& _switch)
} }
vector<YulString> splitExpressions; vector<YulString> splitExpressions;
for (auto const& expr: expandValue(*_switch.expression)) for (auto const& expr: expandValue(*_switch.expression))
splitExpressions.emplace_back(boost::get<Identifier>(*expr).name); splitExpressions.emplace_back(std::get<Identifier>(*expr).name);
ret += handleSwitchInternal( ret += handleSwitchInternal(
_switch.location, _switch.location,
@ -372,15 +373,15 @@ array<YulString, 4> WordSizeTransform::generateU64IdentifierNames(YulString cons
array<unique_ptr<Expression>, 4> WordSizeTransform::expandValue(Expression const& _e) array<unique_ptr<Expression>, 4> WordSizeTransform::expandValue(Expression const& _e)
{ {
array<unique_ptr<Expression>, 4> ret; array<unique_ptr<Expression>, 4> ret;
if (_e.type() == typeid(Identifier)) if (holds_alternative<Identifier>(_e))
{ {
Identifier const& id = boost::get<Identifier>(_e); Identifier const& id = std::get<Identifier>(_e);
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
ret[i] = make_unique<Expression>(Identifier{id.location, m_variableMapping.at(id.name)[i]}); ret[i] = make_unique<Expression>(Identifier{id.location, m_variableMapping.at(id.name)[i]});
} }
else if (_e.type() == typeid(Literal)) else if (holds_alternative<Literal>(_e))
{ {
Literal const& lit = boost::get<Literal>(_e); Literal const& lit = std::get<Literal>(_e);
u256 val = valueOfLiteral(lit); u256 val = valueOfLiteral(lit);
for (int i = 3; i >= 0; i--) for (int i = 3; i >= 0; i--)
{ {

View File

@ -155,12 +155,12 @@ Statement ASTCopier::operator ()(Block const& _block)
Expression ASTCopier::translate(Expression const& _expression) Expression ASTCopier::translate(Expression const& _expression)
{ {
return _expression.apply_visitor(static_cast<ExpressionCopier&>(*this)); return std::visit(static_cast<ExpressionCopier&>(*this), _expression);
} }
Statement ASTCopier::translate(Statement const& _statement) Statement ASTCopier::translate(Statement const& _statement)
{ {
return _statement.apply_visitor(static_cast<StatementCopier&>(*this)); return std::visit(static_cast<StatementCopier&>(*this), _statement);
} }
Block ASTCopier::translate(Block const& _block) Block ASTCopier::translate(Block const& _block)

View File

@ -24,8 +24,6 @@
#include <libyul/YulString.h> #include <libyul/YulString.h>
#include <boost/variant.hpp>
#include <memory> #include <memory>
#include <optional> #include <optional>
#include <set> #include <set>
@ -34,7 +32,7 @@
namespace yul namespace yul
{ {
class ExpressionCopier: public boost::static_visitor<Expression> class ExpressionCopier
{ {
public: public:
virtual ~ExpressionCopier() = default; virtual ~ExpressionCopier() = default;
@ -44,7 +42,7 @@ public:
virtual Expression operator()(FunctionCall const&) = 0; virtual Expression operator()(FunctionCall const&) = 0;
}; };
class StatementCopier: public boost::static_visitor<Statement> class StatementCopier
{ {
public: public:
virtual ~StatementCopier() = default; virtual ~StatementCopier() = default;

View File

@ -94,12 +94,12 @@ void ASTWalker::operator()(Block const& _block)
void ASTWalker::visit(Statement const& _st) void ASTWalker::visit(Statement const& _st)
{ {
boost::apply_visitor(*this, _st); std::visit(*this, _st);
} }
void ASTWalker::visit(Expression const& _e) void ASTWalker::visit(Expression const& _e)
{ {
boost::apply_visitor(*this, _e); std::visit(*this, _e);
} }
void ASTModifier::operator()(FunctionalInstruction& _instr) void ASTModifier::operator()(FunctionalInstruction& _instr)
@ -176,10 +176,10 @@ void ASTModifier::operator()(Block& _block)
void ASTModifier::visit(Statement& _st) void ASTModifier::visit(Statement& _st)
{ {
boost::apply_visitor(*this, _st); std::visit(*this, _st);
} }
void ASTModifier::visit(Expression& _e) void ASTModifier::visit(Expression& _e)
{ {
boost::apply_visitor(*this, _e); std::visit(*this, _e);
} }

View File

@ -25,8 +25,6 @@
#include <libyul/Exceptions.h> #include <libyul/Exceptions.h>
#include <libyul/YulString.h> #include <libyul/YulString.h>
#include <boost/variant.hpp>
#include <map> #include <map>
#include <optional> #include <optional>
#include <set> #include <set>
@ -38,7 +36,7 @@ namespace yul
/** /**
* Generic AST walker. * Generic AST walker.
*/ */
class ASTWalker: public boost::static_visitor<> class ASTWalker
{ {
public: public:
virtual ~ASTWalker() = default; virtual ~ASTWalker() = default;
@ -75,7 +73,7 @@ protected:
/** /**
* Generic AST modifier (i.e. non-const version of ASTWalker). * Generic AST modifier (i.e. non-const version of ASTWalker).
*/ */
class ASTModifier: public boost::static_visitor<> class ASTModifier
{ {
public: public:
virtual ~ASTModifier() = default; virtual ~ASTModifier() = default;

View File

@ -32,8 +32,8 @@ void BlockFlattener::operator()(Block& _block)
_block.statements, _block.statements,
[](Statement& _s) -> std::optional<vector<Statement>> [](Statement& _s) -> std::optional<vector<Statement>>
{ {
if (_s.type() == typeid(Block)) if (holds_alternative<Block>(_s))
return std::move(boost::get<Block>(_s).statements); return std::move(std::get<Block>(_s).statements);
else else
return {}; return {};
} }

View File

@ -56,8 +56,8 @@ void CommonSubexpressionEliminator::visit(Expression& _e)
bool descend = true; bool descend = true;
// If this is a function call to a function that requires literal arguments, // If this is a function call to a function that requires literal arguments,
// do not try to simplify there. // do not try to simplify there.
if (_e.type() == typeid(FunctionCall)) if (holds_alternative<FunctionCall>(_e))
if (BuiltinFunction const* builtin = m_dialect.builtin(boost::get<FunctionCall>(_e).functionName.name)) if (BuiltinFunction const* builtin = m_dialect.builtin(std::get<FunctionCall>(_e).functionName.name))
if (builtin->literalArguments) if (builtin->literalArguments)
// We should not modify function arguments that have to be literals // We should not modify function arguments that have to be literals
// Note that replacing the function call entirely is fine, // Note that replacing the function call entirely is fine,
@ -72,16 +72,16 @@ void CommonSubexpressionEliminator::visit(Expression& _e)
if (descend) if (descend)
DataFlowAnalyzer::visit(_e); DataFlowAnalyzer::visit(_e);
if (_e.type() == typeid(Identifier)) if (holds_alternative<Identifier>(_e))
{ {
Identifier& identifier = boost::get<Identifier>(_e); Identifier& identifier = std::get<Identifier>(_e);
YulString name = identifier.name; YulString name = identifier.name;
if (m_value.count(name)) if (m_value.count(name))
{ {
assertThrow(m_value.at(name), OptimizerException, ""); assertThrow(m_value.at(name), OptimizerException, "");
if (m_value.at(name)->type() == typeid(Identifier)) if (holds_alternative<Identifier>(*m_value.at(name)))
{ {
YulString value = boost::get<Identifier>(*m_value.at(name)).name; YulString value = std::get<Identifier>(*m_value.at(name)).name;
assertThrow(inScope(value), OptimizerException, ""); assertThrow(inScope(value), OptimizerException, "");
_e = Identifier{locationOf(_e), value}; _e = Identifier{locationOf(_e), value};
} }

View File

@ -29,12 +29,12 @@ using namespace yul;
void ConditionalSimplifier::operator()(Switch& _switch) void ConditionalSimplifier::operator()(Switch& _switch)
{ {
visit(*_switch.expression); visit(*_switch.expression);
if (_switch.expression->type() != typeid(Identifier)) if (!holds_alternative<Identifier>(*_switch.expression))
{ {
ASTModifier::operator()(_switch); ASTModifier::operator()(_switch);
return; return;
} }
YulString expr = boost::get<Identifier>(*_switch.expression).name; YulString expr = std::get<Identifier>(*_switch.expression).name;
for (auto& _case: _switch.cases) for (auto& _case: _switch.cases)
{ {
if (_case.value) if (_case.value)
@ -59,17 +59,17 @@ void ConditionalSimplifier::operator()(Block& _block)
[&](Statement& _s) -> std::optional<vector<Statement>> [&](Statement& _s) -> std::optional<vector<Statement>>
{ {
visit(_s); visit(_s);
if (_s.type() == typeid(If)) if (holds_alternative<If>(_s))
{ {
If& _if = boost::get<If>(_s); If& _if = std::get<If>(_s);
if ( if (
_if.condition->type() == typeid(Identifier) && holds_alternative<Identifier>(*_if.condition) &&
!_if.body.statements.empty() && !_if.body.statements.empty() &&
TerminationFinder(m_dialect).controlFlowKind(_if.body.statements.back()) != TerminationFinder(m_dialect).controlFlowKind(_if.body.statements.back()) !=
TerminationFinder::ControlFlow::FlowOut TerminationFinder::ControlFlow::FlowOut
) )
{ {
YulString condition = boost::get<Identifier>(*_if.condition).name; YulString condition = std::get<Identifier>(*_if.condition).name;
langutil::SourceLocation location = _if.location; langutil::SourceLocation location = _if.location;
return make_vector<Statement>( return make_vector<Statement>(
std::move(_s), std::move(_s),

View File

@ -29,12 +29,12 @@ using namespace yul;
void ConditionalUnsimplifier::operator()(Switch& _switch) void ConditionalUnsimplifier::operator()(Switch& _switch)
{ {
visit(*_switch.expression); visit(*_switch.expression);
if (_switch.expression->type() != typeid(Identifier)) if (!holds_alternative<Identifier>(*_switch.expression))
{ {
ASTModifier::operator()(_switch); ASTModifier::operator()(_switch);
return; return;
} }
YulString expr = boost::get<Identifier>(*_switch.expression).name; YulString expr = std::get<Identifier>(*_switch.expression).name;
for (auto& _case: _switch.cases) for (auto& _case: _switch.cases)
{ {
if (_case.value) if (_case.value)
@ -42,15 +42,15 @@ void ConditionalUnsimplifier::operator()(Switch& _switch)
(*this)(*_case.value); (*this)(*_case.value);
if ( if (
!_case.body.statements.empty() && !_case.body.statements.empty() &&
_case.body.statements.front().type() == typeid(Assignment) holds_alternative<Assignment>(_case.body.statements.front())
) )
{ {
Assignment const& assignment = boost::get<Assignment>(_case.body.statements.front()); Assignment const& assignment = std::get<Assignment>(_case.body.statements.front());
if ( if (
assignment.variableNames.size() == 1 && assignment.variableNames.size() == 1 &&
assignment.variableNames.front().name == expr && assignment.variableNames.front().name == expr &&
assignment.value->type() == typeid(Literal) && holds_alternative<Literal>(*assignment.value) &&
valueOfLiteral(boost::get<Literal>(*assignment.value)) == valueOfLiteral(*_case.value) valueOfLiteral(std::get<Literal>(*assignment.value)) == valueOfLiteral(*_case.value)
) )
_case.body.statements.erase(_case.body.statements.begin()); _case.body.statements.erase(_case.body.statements.begin());
} }
@ -66,27 +66,27 @@ void ConditionalUnsimplifier::operator()(Block& _block)
_block.statements, _block.statements,
[&](Statement& _stmt1, Statement& _stmt2) -> std::optional<vector<Statement>> [&](Statement& _stmt1, Statement& _stmt2) -> std::optional<vector<Statement>>
{ {
if (_stmt1.type() == typeid(If)) if (holds_alternative<If>(_stmt1))
{ {
If& _if = boost::get<If>(_stmt1); If& _if = std::get<If>(_stmt1);
if ( if (
_if.condition->type() == typeid(Identifier) && holds_alternative<Identifier>(*_if.condition) &&
!_if.body.statements.empty() !_if.body.statements.empty()
) )
{ {
YulString condition = boost::get<Identifier>(*_if.condition).name; YulString condition = std::get<Identifier>(*_if.condition).name;
if ( if (
_stmt2.type() == typeid(Assignment) && holds_alternative<Assignment>(_stmt2) &&
TerminationFinder(m_dialect).controlFlowKind(_if.body.statements.back()) != TerminationFinder(m_dialect).controlFlowKind(_if.body.statements.back()) !=
TerminationFinder::ControlFlow::FlowOut TerminationFinder::ControlFlow::FlowOut
) )
{ {
Assignment const& assignment = boost::get<Assignment>(_stmt2); Assignment const& assignment = std::get<Assignment>(_stmt2);
if ( if (
assignment.variableNames.size() == 1 && assignment.variableNames.size() == 1 &&
assignment.variableNames.front().name == condition && assignment.variableNames.front().name == condition &&
assignment.value->type() == typeid(Literal) && holds_alternative<Literal>(*assignment.value) &&
valueOfLiteral(boost::get<Literal>(*assignment.value)) == 0 valueOfLiteral(std::get<Literal>(*assignment.value)) == 0
) )
return {make_vector<Statement>(std::move(_stmt1))}; return {make_vector<Statement>(std::move(_stmt1))};
} }

View File

@ -138,9 +138,9 @@ void ControlFlowSimplifier::operator()(Block& _block)
void ControlFlowSimplifier::visit(Statement& _st) void ControlFlowSimplifier::visit(Statement& _st)
{ {
if (_st.type() == typeid(ForLoop)) if (holds_alternative<ForLoop>(_st))
{ {
ForLoop& forLoop = boost::get<ForLoop>(_st); ForLoop& forLoop = std::get<ForLoop>(_st);
yulAssert(forLoop.pre.statements.empty(), ""); yulAssert(forLoop.pre.statements.empty(), "");
size_t outerBreak = m_numBreakStatements; size_t outerBreak = m_numBreakStatements;
@ -211,7 +211,7 @@ void ControlFlowSimplifier::simplify(std::vector<yul::Statement>& _statements)
_statements, _statements,
[&](Statement& _stmt) -> OptionalStatements [&](Statement& _stmt) -> OptionalStatements
{ {
OptionalStatements result = boost::apply_visitor(visitor, _stmt); OptionalStatements result = std::visit(visitor, _stmt);
if (result) if (result)
simplify(*result); simplify(*result);
else else

View File

@ -32,6 +32,7 @@
#include <boost/range/adaptor/reversed.hpp> #include <boost/range/adaptor/reversed.hpp>
#include <boost/range/algorithm_ext/erase.hpp> #include <boost/range/algorithm_ext/erase.hpp>
#include <variant>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -364,19 +365,19 @@ std::optional<pair<YulString, YulString>> DataFlowAnalyzer::isSimpleStore(
_store == dev::eth::Instruction::SSTORE, _store == dev::eth::Instruction::SSTORE,
"" ""
); );
if (_statement.expression.type() == typeid(FunctionCall)) if (holds_alternative<FunctionCall>(_statement.expression))
{ {
FunctionCall const& funCall = boost::get<FunctionCall>(_statement.expression); FunctionCall const& funCall = std::get<FunctionCall>(_statement.expression);
if (EVMDialect const* dialect = dynamic_cast<EVMDialect const*>(&m_dialect)) if (EVMDialect const* dialect = dynamic_cast<EVMDialect const*>(&m_dialect))
if (auto const* builtin = dialect->builtin(funCall.functionName.name)) if (auto const* builtin = dialect->builtin(funCall.functionName.name))
if (builtin->instruction == _store) if (builtin->instruction == _store)
if ( if (
funCall.arguments.at(0).type() == typeid(Identifier) && holds_alternative<Identifier>(funCall.arguments.at(0)) &&
funCall.arguments.at(1).type() == typeid(Identifier) holds_alternative<Identifier>(funCall.arguments.at(1))
) )
{ {
YulString key = boost::get<Identifier>(funCall.arguments.at(0)).name; YulString key = std::get<Identifier>(funCall.arguments.at(0)).name;
YulString value = boost::get<Identifier>(funCall.arguments.at(1)).name; YulString value = std::get<Identifier>(funCall.arguments.at(1)).name;
return make_pair(key, value); return make_pair(key, value);
} }
} }

View File

@ -56,7 +56,7 @@ void DeadCodeEliminator::operator()(Block& _block)
remove_if( remove_if(
_block.statements.begin() + index + 1, _block.statements.begin() + index + 1,
_block.statements.end(), _block.statements.end(),
[] (Statement const& _s) { return _s.type() != typeid(yul::FunctionDefinition); } [] (Statement const& _s) { return !holds_alternative<yul::FunctionDefinition>(_s); }
), ),
_block.statements.end() _block.statements.end()
); );

View File

@ -25,8 +25,6 @@
#include <libyul/optimiser/ASTCopier.h> #include <libyul/optimiser/ASTCopier.h>
#include <libyul/optimiser/NameDispenser.h> #include <libyul/optimiser/NameDispenser.h>
#include <boost/variant.hpp>
#include <optional> #include <optional>
#include <set> #include <set>

View File

@ -49,9 +49,9 @@ void ExpressionInliner::operator()(FunctionDefinition& _fun)
void ExpressionInliner::visit(Expression& _expression) void ExpressionInliner::visit(Expression& _expression)
{ {
ASTModifier::visit(_expression); ASTModifier::visit(_expression);
if (_expression.type() == typeid(FunctionCall)) if (holds_alternative<FunctionCall>(_expression))
{ {
FunctionCall& funCall = boost::get<FunctionCall>(_expression); FunctionCall& funCall = std::get<FunctionCall>(_expression);
if (!m_inlinableFunctions.count(funCall.functionName.name)) if (!m_inlinableFunctions.count(funCall.functionName.name))
return; return;
FunctionDefinition const& fun = *m_inlinableFunctions.at(funCall.functionName.name); FunctionDefinition const& fun = *m_inlinableFunctions.at(funCall.functionName.name);
@ -74,6 +74,6 @@ void ExpressionInliner::visit(Expression& _expression)
substitutions[paraName] = &arg; substitutions[paraName] = &arg;
} }
_expression = Substitution(substitutions).translate(*boost::get<Assignment>(fun.body.statements.front()).value); _expression = Substitution(substitutions).translate(*std::get<Assignment>(fun.body.statements.front()).value);
} }
} }

View File

@ -22,9 +22,7 @@
#include <libyul/optimiser/ASTWalker.h> #include <libyul/optimiser/ASTWalker.h>
#include <libyul/AsmDataForward.h> #include <libyul/AsmDataForward.h>
#include <boost/variant.hpp>
#include <optional> #include <optional>
#include <set> #include <set>
namespace yul namespace yul

View File

@ -66,12 +66,12 @@ void ExpressionJoiner::operator()(Block& _block)
void ExpressionJoiner::visit(Expression& _e) void ExpressionJoiner::visit(Expression& _e)
{ {
if (_e.type() == typeid(Identifier)) if (holds_alternative<Identifier>(_e))
{ {
Identifier const& identifier = boost::get<Identifier>(_e); Identifier const& identifier = std::get<Identifier>(_e);
if (isLatestStatementVarDeclJoinable(identifier)) if (isLatestStatementVarDeclJoinable(identifier))
{ {
VariableDeclaration& varDecl = boost::get<VariableDeclaration>(*latestStatement()); VariableDeclaration& varDecl = std::get<VariableDeclaration>(*latestStatement());
_e = std::move(*varDecl.value); _e = std::move(*varDecl.value);
// Delete the variable declaration (also get the moved-from structure back into a sane state) // Delete the variable declaration (also get the moved-from structure back into a sane state)
@ -101,7 +101,7 @@ void ExpressionJoiner::handleArguments(vector<Expression>& _arguments)
for (Expression const& arg: _arguments | boost::adaptors::reversed) for (Expression const& arg: _arguments | boost::adaptors::reversed)
{ {
--i; --i;
if (arg.type() != typeid(Identifier) && arg.type() != typeid(Literal)) if (!holds_alternative<Identifier>(arg) && !holds_alternative<Literal>(arg))
break; break;
} }
// i points to the last element that is neither an identifier nor a literal, // i points to the last element that is neither an identifier nor a literal,
@ -138,9 +138,9 @@ Statement* ExpressionJoiner::latestStatement()
bool ExpressionJoiner::isLatestStatementVarDeclJoinable(Identifier const& _identifier) bool ExpressionJoiner::isLatestStatementVarDeclJoinable(Identifier const& _identifier)
{ {
Statement const* statement = latestStatement(); Statement const* statement = latestStatement();
if (!statement || statement->type() != typeid(VariableDeclaration)) if (!statement || !holds_alternative<VariableDeclaration>(*statement))
return false; return false;
VariableDeclaration const& varDecl = boost::get<VariableDeclaration>(*statement); VariableDeclaration const& varDecl = std::get<VariableDeclaration>(*statement);
if (varDecl.variables.size() != 1 || !varDecl.value) if (varDecl.variables.size() != 1 || !varDecl.value)
return false; return false;
assertThrow(varDecl.variables.size() == 1, OptimizerException, ""); assertThrow(varDecl.variables.size() == 1, OptimizerException, "");

View File

@ -101,7 +101,7 @@ void ExpressionSplitter::operator()(Block& _block)
void ExpressionSplitter::outlineExpression(Expression& _expr) void ExpressionSplitter::outlineExpression(Expression& _expr)
{ {
if (_expr.type() == typeid(Identifier)) if (holds_alternative<Identifier>(_expr))
return; return;
visit(_expr); visit(_expr);

View File

@ -33,8 +33,8 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop)
{ {
if ( if (
m_dialect.booleanNegationFunction() && m_dialect.booleanNegationFunction() &&
_forLoop.condition->type() != typeid(Literal) && !holds_alternative<Literal>(*_forLoop.condition) &&
_forLoop.condition->type() != typeid(Identifier) !holds_alternative<Identifier>(*_forLoop.condition)
) )
{ {
langutil::SourceLocation loc = locationOf(*_forLoop.condition); langutil::SourceLocation loc = locationOf(*_forLoop.condition);

View File

@ -36,17 +36,17 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop)
if ( if (
!m_dialect.booleanNegationFunction() || !m_dialect.booleanNegationFunction() ||
_forLoop.condition->type() != typeid(Literal) || !holds_alternative<Literal>(*_forLoop.condition) ||
valueOfLiteral(boost::get<Literal>(*_forLoop.condition)) == u256(0) || valueOfLiteral(std::get<Literal>(*_forLoop.condition)) == u256(0) ||
_forLoop.body.statements.empty() || _forLoop.body.statements.empty() ||
_forLoop.body.statements.front().type() != typeid(If) !holds_alternative<If>(_forLoop.body.statements.front())
) )
return; return;
If& firstStatement = boost::get<If>(_forLoop.body.statements.front()); If& firstStatement = std::get<If>(_forLoop.body.statements.front());
if ( if (
firstStatement.body.statements.empty() || firstStatement.body.statements.empty() ||
firstStatement.body.statements.front().type() != typeid(Break) !holds_alternative<Break>(firstStatement.body.statements.front())
) )
return; return;
if (!SideEffectsCollector(m_dialect, *firstStatement.condition).movable()) if (!SideEffectsCollector(m_dialect, *firstStatement.condition).movable())
@ -56,10 +56,10 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop)
langutil::SourceLocation location = locationOf(*firstStatement.condition); langutil::SourceLocation location = locationOf(*firstStatement.condition);
if ( if (
firstStatement.condition->type() == typeid(FunctionCall) && holds_alternative<FunctionCall>(*firstStatement.condition) &&
boost::get<FunctionCall>(*firstStatement.condition).functionName.name == iszero std::get<FunctionCall>(*firstStatement.condition).functionName.name == iszero
) )
_forLoop.condition = make_unique<Expression>(std::move(boost::get<FunctionCall>(*firstStatement.condition).arguments.front())); _forLoop.condition = make_unique<Expression>(std::move(std::get<FunctionCall>(*firstStatement.condition).arguments.front()));
else else
_forLoop.condition = make_unique<Expression>(FunctionCall{ _forLoop.condition = make_unique<Expression>(FunctionCall{
location, location,

View File

@ -29,9 +29,9 @@ void ForLoopInitRewriter::operator()(Block& _block)
_block.statements, _block.statements,
[&](Statement& _stmt) -> std::optional<vector<Statement>> [&](Statement& _stmt) -> std::optional<vector<Statement>>
{ {
if (_stmt.type() == typeid(ForLoop)) if (holds_alternative<ForLoop>(_stmt))
{ {
auto& forLoop = boost::get<ForLoop>(_stmt); auto& forLoop = std::get<ForLoop>(_stmt);
(*this)(forLoop.pre); (*this)(forLoop.pre);
(*this)(forLoop.body); (*this)(forLoop.body);
(*this)(forLoop.post); (*this)(forLoop.post);

View File

@ -50,7 +50,7 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser):
SSAValueTracker tracker; SSAValueTracker tracker;
tracker(m_ast); tracker(m_ast);
for (auto const& ssaValue: tracker.values()) for (auto const& ssaValue: tracker.values())
if (ssaValue.second && ssaValue.second->type() == typeid(Literal)) if (ssaValue.second && holds_alternative<Literal>(*ssaValue.second))
m_constants.emplace(ssaValue.first); m_constants.emplace(ssaValue.first);
// Store size of global statements. // Store size of global statements.
@ -58,9 +58,9 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser):
map<YulString, size_t> references = ReferencesCounter::countReferences(m_ast); map<YulString, size_t> references = ReferencesCounter::countReferences(m_ast);
for (auto& statement: m_ast.statements) for (auto& statement: m_ast.statements)
{ {
if (statement.type() != typeid(FunctionDefinition)) if (!holds_alternative<FunctionDefinition>(statement))
continue; continue;
FunctionDefinition& fun = boost::get<FunctionDefinition>(statement); FunctionDefinition& fun = std::get<FunctionDefinition>(statement);
m_functions[fun.name] = &fun; m_functions[fun.name] = &fun;
// Always inline functions that are only called once. // Always inline functions that are only called once.
if (references[fun.name] == 1) if (references[fun.name] == 1)
@ -72,8 +72,8 @@ FullInliner::FullInliner(Block& _ast, NameDispenser& _dispenser):
void FullInliner::run() void FullInliner::run()
{ {
for (auto& statement: m_ast.statements) for (auto& statement: m_ast.statements)
if (statement.type() == typeid(Block)) if (holds_alternative<Block>(statement))
handleBlock({}, boost::get<Block>(statement)); handleBlock({}, std::get<Block>(statement));
// TODO it might be good to determine a visiting order: // TODO it might be good to determine a visiting order:
// first handle functions that are called from many places. // first handle functions that are called from many places.
@ -112,9 +112,9 @@ bool FullInliner::shallInline(FunctionCall const& _funCall, YulString _callSite)
// Constant arguments might provide a means for further optimization, so they cause a bonus. // Constant arguments might provide a means for further optimization, so they cause a bonus.
bool constantArg = false; bool constantArg = false;
for (auto const& argument: _funCall.arguments) for (auto const& argument: _funCall.arguments)
if (argument.type() == typeid(Literal) || ( if (holds_alternative<Literal>(argument) || (
argument.type() == typeid(Identifier) && holds_alternative<Identifier>(argument) &&
m_constants.count(boost::get<Identifier>(argument).name) m_constants.count(std::get<Identifier>(argument).name)
)) ))
{ {
constantArg = true; constantArg = true;
@ -157,7 +157,7 @@ void InlineModifier::operator()(Block& _block)
std::optional<vector<Statement>> InlineModifier::tryInlineStatement(Statement& _statement) std::optional<vector<Statement>> InlineModifier::tryInlineStatement(Statement& _statement)
{ {
// Only inline for expression statements, assignments and variable declarations. // Only inline for expression statements, assignments and variable declarations.
Expression* e = boost::apply_visitor(GenericFallbackReturnsVisitor<Expression*, ExpressionStatement, Assignment, VariableDeclaration>( Expression* e = std::visit(GenericFallbackReturnsVisitor<Expression*, ExpressionStatement, Assignment, VariableDeclaration>(
[](ExpressionStatement& _s) { return &_s.expression; }, [](ExpressionStatement& _s) { return &_s.expression; },
[](Assignment& _s) { return _s.value.get(); }, [](Assignment& _s) { return _s.value.get(); },
[](VariableDeclaration& _s) { return _s.value.get(); } [](VariableDeclaration& _s) { return _s.value.get(); }
@ -165,7 +165,7 @@ std::optional<vector<Statement>> InlineModifier::tryInlineStatement(Statement& _
if (e) if (e)
{ {
// Only inline direct function calls. // Only inline direct function calls.
FunctionCall* funCall = boost::apply_visitor(GenericFallbackReturnsVisitor<FunctionCall*, FunctionCall&>( FunctionCall* funCall = std::visit(GenericFallbackReturnsVisitor<FunctionCall*, FunctionCall&>(
[](FunctionCall& _e) { return &_e; } [](FunctionCall& _e) { return &_e; }
), *e); ), *e);
if (funCall && m_driver.shallInline(*funCall, m_currentFunction)) if (funCall && m_driver.shallInline(*funCall, m_currentFunction))
@ -203,9 +203,9 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
newVariable(var, nullptr); newVariable(var, nullptr);
Statement newBody = BodyCopier(m_nameDispenser, variableReplacements)(function->body); Statement newBody = BodyCopier(m_nameDispenser, variableReplacements)(function->body);
newStatements += std::move(boost::get<Block>(newBody).statements); newStatements += std::move(std::get<Block>(newBody).statements);
boost::apply_visitor(GenericFallbackVisitor<Assignment, VariableDeclaration>{ std::visit(GenericFallbackVisitor<Assignment, VariableDeclaration>{
[&](Assignment& _assignment) [&](Assignment& _assignment)
{ {
for (size_t i = 0; i < _assignment.variableNames.size(); ++i) for (size_t i = 0; i < _assignment.variableNames.size(); ++i)

View File

@ -29,8 +29,6 @@
#include <liblangutil/SourceLocation.h> #include <liblangutil/SourceLocation.h>
#include <boost/variant.hpp>
#include <optional> #include <optional>
#include <set> #include <set>

View File

@ -40,10 +40,10 @@ void FunctionGrouper::operator()(Block& _block)
for (auto&& statement: _block.statements) for (auto&& statement: _block.statements)
{ {
if (statement.type() == typeid(FunctionDefinition)) if (holds_alternative<FunctionDefinition>(statement))
reordered.emplace_back(std::move(statement)); reordered.emplace_back(std::move(statement));
else else
boost::get<Block>(reordered.front()).statements.emplace_back(std::move(statement)); std::get<Block>(reordered.front()).statements.emplace_back(std::move(statement));
} }
_block.statements = std::move(reordered); _block.statements = std::move(reordered);
} }
@ -52,10 +52,10 @@ bool FunctionGrouper::alreadyGrouped(Block const& _block)
{ {
if (_block.statements.empty()) if (_block.statements.empty())
return false; return false;
if (_block.statements.front().type() != typeid(Block)) if (!holds_alternative<Block>(_block.statements.front()))
return false; return false;
for (size_t i = 1; i < _block.statements.size(); ++i) for (size_t i = 1; i < _block.statements.size(); ++i)
if (_block.statements.at(i).type() != typeid(FunctionDefinition)) if (!holds_alternative<FunctionDefinition>(_block.statements.at(i)))
return false; return false;
return true; return true;
} }

View File

@ -36,8 +36,8 @@ void FunctionHoister::operator()(Block& _block)
m_isTopLevel = false; m_isTopLevel = false;
for (auto&& statement: _block.statements) for (auto&& statement: _block.statements)
{ {
boost::apply_visitor(*this, statement); std::visit(*this, statement);
if (statement.type() == typeid(FunctionDefinition)) if (holds_alternative<FunctionDefinition>(statement))
{ {
m_functions.emplace_back(std::move(statement)); m_functions.emplace_back(std::move(statement));
statement = Block{_block.location, {}}; statement = Block{_block.location, {}};

View File

@ -45,9 +45,9 @@ void InlinableExpressionFunctionFinder::operator()(FunctionDefinition const& _fu
{ {
YulString retVariable = _function.returnVariables.front().name; YulString retVariable = _function.returnVariables.front().name;
Statement const& bodyStatement = _function.body.statements.front(); Statement const& bodyStatement = _function.body.statements.front();
if (bodyStatement.type() == typeid(Assignment)) if (holds_alternative<Assignment>(bodyStatement))
{ {
Assignment const& assignment = boost::get<Assignment>(bodyStatement); Assignment const& assignment = std::get<Assignment>(bodyStatement);
if (assignment.variableNames.size() == 1 && assignment.variableNames.front().name == retVariable) if (assignment.variableNames.size() == 1 && assignment.variableNames.front().name == retVariable)
{ {
// TODO: use code size metric here // TODO: use code size metric here
@ -57,7 +57,7 @@ void InlinableExpressionFunctionFinder::operator()(FunctionDefinition const& _fu
// function body. // function body.
assertThrow(m_disallowedIdentifiers.empty() && !m_foundDisallowedIdentifier, OptimizerException, ""); assertThrow(m_disallowedIdentifiers.empty() && !m_foundDisallowedIdentifier, OptimizerException, "");
m_disallowedIdentifiers = set<YulString>{retVariable, _function.name}; m_disallowedIdentifiers = set<YulString>{retVariable, _function.name};
boost::apply_visitor(*this, *assignment.value); std::visit(*this, *assignment.value);
if (!m_foundDisallowedIdentifier) if (!m_foundDisallowedIdentifier)
m_inlinableFunctions[_function.name] = &_function; m_inlinableFunctions[_function.name] = &_function;
m_disallowedIdentifiers.clear(); m_disallowedIdentifiers.clear();

View File

@ -27,6 +27,9 @@
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
#include <variant>
using namespace std;
using namespace yul; using namespace yul;
using namespace dev; using namespace dev;
@ -37,12 +40,12 @@ bool KnowledgeBase::knownToBeDifferent(YulString _a, YulString _b)
// If that fails, try `eq(_a, _b)`. // If that fails, try `eq(_a, _b)`.
Expression expr1 = simplify(FunctionCall{{}, {{}, "sub"_yulstring}, make_vector<Expression>(Identifier{{}, _a}, Identifier{{}, _b})}); Expression expr1 = simplify(FunctionCall{{}, {{}, "sub"_yulstring}, make_vector<Expression>(Identifier{{}, _a}, Identifier{{}, _b})});
if (expr1.type() == typeid(Literal)) if (holds_alternative<Literal>(expr1))
return valueOfLiteral(boost::get<Literal>(expr1)) != 0; return valueOfLiteral(std::get<Literal>(expr1)) != 0;
Expression expr2 = simplify(FunctionCall{{}, {{}, "eq"_yulstring}, make_vector<Expression>(Identifier{{}, _a}, Identifier{{}, _b})}); Expression expr2 = simplify(FunctionCall{{}, {{}, "eq"_yulstring}, make_vector<Expression>(Identifier{{}, _a}, Identifier{{}, _b})});
if (expr2.type() == typeid(Literal)) if (holds_alternative<Literal>(expr2))
return valueOfLiteral(boost::get<Literal>(expr2)) == 0; return valueOfLiteral(std::get<Literal>(expr2)) == 0;
return false; return false;
} }
@ -53,9 +56,9 @@ bool KnowledgeBase::knownToBeDifferentByAtLeast32(YulString _a, YulString _b)
// current values to turn `sub(_a, _b)` into a constant whose absolute value is at least 32. // current values to turn `sub(_a, _b)` into a constant whose absolute value is at least 32.
Expression expr1 = simplify(FunctionCall{{}, {{}, "sub"_yulstring}, make_vector<Expression>(Identifier{{}, _a}, Identifier{{}, _b})}); Expression expr1 = simplify(FunctionCall{{}, {{}, "sub"_yulstring}, make_vector<Expression>(Identifier{{}, _a}, Identifier{{}, _b})});
if (expr1.type() == typeid(Literal)) if (holds_alternative<Literal>(expr1))
{ {
u256 val = valueOfLiteral(boost::get<Literal>(expr1)); u256 val = valueOfLiteral(std::get<Literal>(expr1));
return val >= 32 && val <= u256(0) - 32; return val >= 32 && val <= u256(0) - 32;
} }
@ -74,11 +77,11 @@ Expression KnowledgeBase::simplify(Expression _expression)
else else
--m_recursionCounter; --m_recursionCounter;
if (_expression.type() == typeid(FunctionCall)) if (holds_alternative<FunctionCall>(_expression))
for (Expression& arg: boost::get<FunctionCall>(_expression).arguments) for (Expression& arg: std::get<FunctionCall>(_expression).arguments)
arg = simplify(arg); arg = simplify(arg);
else if (_expression.type() == typeid(FunctionalInstruction)) else if (holds_alternative<FunctionalInstruction>(_expression))
for (Expression& arg: boost::get<FunctionalInstruction>(_expression).arguments) for (Expression& arg: std::get<FunctionalInstruction>(_expression).arguments)
arg = simplify(arg); arg = simplify(arg);
if (auto match = SimplificationRules::findFirstMatch(_expression, m_dialect, m_variableValues)) if (auto match = SimplificationRules::findFirstMatch(_expression, m_dialect, m_variableValues))

View File

@ -48,16 +48,16 @@ void LoadResolver::visit(Expression& _e)
if (!dynamic_cast<EVMDialect const*>(&m_dialect)) if (!dynamic_cast<EVMDialect const*>(&m_dialect))
return; return;
if (_e.type() == typeid(FunctionCall)) if (holds_alternative<FunctionCall>(_e))
{ {
FunctionCall const& funCall = boost::get<FunctionCall>(_e); FunctionCall const& funCall = std::get<FunctionCall>(_e);
if (auto const* builtin = dynamic_cast<EVMDialect const&>(m_dialect).builtin(funCall.functionName.name)) if (auto const* builtin = dynamic_cast<EVMDialect const&>(m_dialect).builtin(funCall.functionName.name))
if (builtin->instruction) if (builtin->instruction)
tryResolve(_e, *builtin->instruction, funCall.arguments); tryResolve(_e, *builtin->instruction, funCall.arguments);
} }
else if (_e.type() == typeid(FunctionalInstruction)) else if (holds_alternative<FunctionalInstruction>(_e))
{ {
FunctionalInstruction const& instruction = boost::get<FunctionalInstruction>(_e); FunctionalInstruction const& instruction = std::get<FunctionalInstruction>(_e);
tryResolve(_e, instruction.instruction, instruction.arguments); tryResolve(_e, instruction.instruction, instruction.arguments);
} }
} }
@ -68,10 +68,10 @@ void LoadResolver::tryResolve(
vector<Expression> const& _arguments vector<Expression> const& _arguments
) )
{ {
if (_arguments.empty() || _arguments.at(0).type() != typeid(Identifier)) if (_arguments.empty() || !holds_alternative<Identifier>(_arguments.at(0)))
return; return;
YulString key = boost::get<Identifier>(_arguments.at(0)).name; YulString key = std::get<Identifier>(_arguments.at(0)).name;
if ( if (
_instruction == dev::eth::Instruction::SLOAD && _instruction == dev::eth::Instruction::SLOAD &&
m_storage.values.count(key) m_storage.values.count(key)

View File

@ -35,13 +35,13 @@ using namespace yul;
void MainFunction::operator()(Block& _block) void MainFunction::operator()(Block& _block)
{ {
assertThrow(_block.statements.size() >= 1, OptimizerException, ""); assertThrow(_block.statements.size() >= 1, OptimizerException, "");
assertThrow(_block.statements[0].type() == typeid(Block), OptimizerException, ""); assertThrow(holds_alternative<Block>(_block.statements[0]), OptimizerException, "");
for (size_t i = 1; i < _block.statements.size(); ++i) for (size_t i = 1; i < _block.statements.size(); ++i)
assertThrow(_block.statements.at(i).type() == typeid(FunctionDefinition), OptimizerException, ""); assertThrow(holds_alternative<FunctionDefinition>(_block.statements.at(i)), OptimizerException, "");
/// @todo this should handle scopes properly and instead of an assertion it should rename the conflicting function /// @todo this should handle scopes properly and instead of an assertion it should rename the conflicting function
assertThrow(NameCollector(_block).names().count("main"_yulstring) == 0, OptimizerException, ""); assertThrow(NameCollector(_block).names().count("main"_yulstring) == 0, OptimizerException, "");
Block& block = boost::get<Block>(_block.statements[0]); Block& block = std::get<Block>(_block.statements[0]);
FunctionDefinition main{ FunctionDefinition main{
block.location, block.location,
"main"_yulstring, "main"_yulstring,

View File

@ -65,23 +65,23 @@ size_t CodeSize::codeSizeIncludingFunctions(Block const& _block)
void CodeSize::visit(Statement const& _statement) void CodeSize::visit(Statement const& _statement)
{ {
if (_statement.type() == typeid(FunctionDefinition) && m_ignoreFunctions) if (holds_alternative<FunctionDefinition>(_statement) && m_ignoreFunctions)
return; return;
else if ( else if (
_statement.type() == typeid(If) || holds_alternative<If>(_statement) ||
_statement.type() == typeid(Break) || holds_alternative<Break>(_statement) ||
_statement.type() == typeid(Continue) holds_alternative<Continue>(_statement)
) )
m_size += 2; m_size += 2;
else if (_statement.type() == typeid(ForLoop)) else if (holds_alternative<ForLoop>(_statement))
m_size += 3; m_size += 3;
else if (_statement.type() == typeid(Switch)) else if (holds_alternative<Switch>(_statement))
m_size += 1 + 2 * boost::get<Switch>(_statement).cases.size(); m_size += 1 + 2 * std::get<Switch>(_statement).cases.size();
else if (!( else if (!(
_statement.type() == typeid(Block) || holds_alternative<Block>(_statement) ||
_statement.type() == typeid(ExpressionStatement) || holds_alternative<ExpressionStatement>(_statement) ||
_statement.type() == typeid(Assignment) || holds_alternative<Assignment>(_statement) ||
_statement.type() == typeid(VariableDeclaration) holds_alternative<VariableDeclaration>(_statement)
)) ))
++m_size; ++m_size;
@ -90,7 +90,7 @@ void CodeSize::visit(Statement const& _statement)
void CodeSize::visit(Expression const& _expression) void CodeSize::visit(Expression const& _expression)
{ {
if (_expression.type() != typeid(Identifier)) if (!holds_alternative<Identifier>(_expression))
++m_size; ++m_size;
ASTWalker::visit(_expression); ASTWalker::visit(_expression);
} }

View File

@ -64,8 +64,8 @@ void NameDisplacer::operator()(Block& _block)
// First replace all the names of function definitions // First replace all the names of function definitions
// because of scoping. // because of scoping.
for (auto& st: _block.statements) for (auto& st: _block.statements)
if (st.type() == typeid(FunctionDefinition)) if (holds_alternative<FunctionDefinition>(st))
checkAndReplaceNew(boost::get<FunctionDefinition>(st).name); checkAndReplaceNew(std::get<FunctionDefinition>(st).name);
ASTModifier::operator()(_block); ASTModifier::operator()(_block);
} }

View File

@ -33,7 +33,7 @@ using namespace yul;
void yul::removeEmptyBlocks(Block& _block) void yul::removeEmptyBlocks(Block& _block)
{ {
auto isEmptyBlock = [](Statement const& _st) -> bool { auto isEmptyBlock = [](Statement const& _st) -> bool {
return _st.type() == typeid(Block) && boost::get<Block>(_st).statements.empty(); return holds_alternative<Block>(_st) && std::get<Block>(_st).statements.empty();
}; };
boost::range::remove_erase_if(_block.statements, isEmptyBlock); boost::range::remove_erase_if(_block.statements, isEmptyBlock);
} }

View File

@ -296,7 +296,7 @@ void RedundantAssignEliminator::finalize(
void AssignmentRemover::operator()(Block& _block) void AssignmentRemover::operator()(Block& _block)
{ {
boost::range::remove_erase_if(_block.statements, [=](Statement const& _statement) -> bool { boost::range::remove_erase_if(_block.statements, [=](Statement const& _statement) -> bool {
return _statement.type() == typeid(Assignment) && m_toRemove.count(&boost::get<Assignment>(_statement)); return holds_alternative<Assignment>(_statement) && m_toRemove.count(&std::get<Assignment>(_statement));
}); });
ASTModifier::operator()(_block); ASTModifier::operator()(_block);

View File

@ -68,9 +68,9 @@ Rematerialiser::Rematerialiser(
void Rematerialiser::visit(Expression& _e) void Rematerialiser::visit(Expression& _e)
{ {
if (_e.type() == typeid(Identifier)) if (holds_alternative<Identifier>(_e))
{ {
Identifier& identifier = boost::get<Identifier>(_e); Identifier& identifier = std::get<Identifier>(_e);
YulString name = identifier.name; YulString name = identifier.name;
if (m_value.count(name)) if (m_value.count(name))
{ {
@ -96,15 +96,15 @@ void Rematerialiser::visit(Expression& _e)
void LiteralRematerialiser::visit(Expression& _e) void LiteralRematerialiser::visit(Expression& _e)
{ {
if (_e.type() == typeid(Identifier)) if (holds_alternative<Identifier>(_e))
{ {
Identifier& identifier = boost::get<Identifier>(_e); Identifier& identifier = std::get<Identifier>(_e);
YulString name = identifier.name; YulString name = identifier.name;
if (m_value.count(name)) if (m_value.count(name))
{ {
Expression const* value = m_value.at(name); Expression const* value = m_value.at(name);
assertThrow(value, OptimizerException, ""); assertThrow(value, OptimizerException, "");
if (value->type() == typeid(Literal)) if (holds_alternative<Literal>(*value))
_e = *value; _e = *value;
} }
} }

View File

@ -19,6 +19,8 @@
#include <libyul/AsmData.h> #include <libyul/AsmData.h>
#include <libdevcore/CommonData.h> #include <libdevcore/CommonData.h>
#include <variant>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
using namespace yul; using namespace yul;
@ -37,7 +39,7 @@ void SSAReverser::operator()(Block& _block)
_block.statements, _block.statements,
[&](Statement& _stmt1, Statement& _stmt2) -> std::optional<vector<Statement>> [&](Statement& _stmt1, Statement& _stmt2) -> std::optional<vector<Statement>>
{ {
auto* varDecl = boost::get<VariableDeclaration>(&_stmt1); auto* varDecl = std::get_if<VariableDeclaration>(&_stmt1);
if (!varDecl || varDecl->variables.size() != 1 || !varDecl->value) if (!varDecl || varDecl->variables.size() != 1 || !varDecl->value)
return {}; return {};
@ -48,9 +50,9 @@ void SSAReverser::operator()(Block& _block)
// with // with
// a := E // a := E
// let a_1 := a // let a_1 := a
if (auto* assignment = boost::get<Assignment>(&_stmt2)) if (auto* assignment = std::get_if<Assignment>(&_stmt2))
{ {
auto* identifier = boost::get<Identifier>(assignment->value.get()); auto* identifier = std::get_if<Identifier>(assignment->value.get());
if ( if (
assignment->variableNames.size() == 1 && assignment->variableNames.size() == 1 &&
identifier && identifier &&
@ -81,9 +83,9 @@ void SSAReverser::operator()(Block& _block)
// with // with
// let a := E // let a := E
// let a_1 := a // let a_1 := a
else if (auto* varDecl2 = boost::get<VariableDeclaration>(&_stmt2)) else if (auto* varDecl2 = std::get_if<VariableDeclaration>(&_stmt2))
{ {
auto* identifier = boost::get<Identifier>(varDecl2->value.get()); auto* identifier = std::get_if<Identifier>(varDecl2->value.get());
if ( if (
varDecl2->variables.size() == 1 && varDecl2->variables.size() == 1 &&
identifier && identifier &&

View File

@ -60,9 +60,9 @@ void IntroduceSSA::operator()(Block& _block)
_block.statements, _block.statements,
[&](Statement& _s) -> std::optional<vector<Statement>> [&](Statement& _s) -> std::optional<vector<Statement>>
{ {
if (_s.type() == typeid(VariableDeclaration)) if (holds_alternative<VariableDeclaration>(_s))
{ {
VariableDeclaration& varDecl = boost::get<VariableDeclaration>(_s); VariableDeclaration& varDecl = std::get<VariableDeclaration>(_s);
if (varDecl.value) if (varDecl.value)
visit(*varDecl.value); visit(*varDecl.value);
@ -90,12 +90,12 @@ void IntroduceSSA::operator()(Block& _block)
make_unique<Expression>(Identifier{loc, newName}) make_unique<Expression>(Identifier{loc, newName})
}); });
} }
boost::get<VariableDeclaration>(statements.front()).variables = std::move(newVariables); std::get<VariableDeclaration>(statements.front()).variables = std::move(newVariables);
return { std::move(statements) }; return { std::move(statements) };
} }
else if (_s.type() == typeid(Assignment)) else if (holds_alternative<Assignment>(_s))
{ {
Assignment& assignment = boost::get<Assignment>(_s); Assignment& assignment = std::get<Assignment>(_s);
visit(*assignment.value); visit(*assignment.value);
for (auto const& var: assignment.variableNames) for (auto const& var: assignment.variableNames)
assertThrow(m_variablesToReplace.count(var.name), OptimizerException, ""); assertThrow(m_variablesToReplace.count(var.name), OptimizerException, "");
@ -117,7 +117,7 @@ void IntroduceSSA::operator()(Block& _block)
make_unique<Expression>(Identifier{loc, newName}) make_unique<Expression>(Identifier{loc, newName})
}); });
} }
boost::get<VariableDeclaration>(statements.front()).variables = std::move(newVariables); std::get<VariableDeclaration>(statements.front()).variables = std::move(newVariables);
return { std::move(statements) }; return { std::move(statements) };
} }
else else
@ -228,9 +228,9 @@ void IntroduceControlFlowSSA::operator()(Block& _block)
} }
m_variablesToReassign.clear(); m_variablesToReassign.clear();
if (_s.type() == typeid(VariableDeclaration)) if (holds_alternative<VariableDeclaration>(_s))
{ {
VariableDeclaration& varDecl = boost::get<VariableDeclaration>(_s); VariableDeclaration& varDecl = std::get<VariableDeclaration>(_s);
for (auto const& var: varDecl.variables) for (auto const& var: varDecl.variables)
if (m_variablesToReplace.count(var.name)) if (m_variablesToReplace.count(var.name))
{ {
@ -238,9 +238,9 @@ void IntroduceControlFlowSSA::operator()(Block& _block)
m_variablesInScope.insert(var.name); m_variablesInScope.insert(var.name);
} }
} }
else if (_s.type() == typeid(Assignment)) else if (holds_alternative<Assignment>(_s))
{ {
Assignment& assignment = boost::get<Assignment>(_s); Assignment& assignment = std::get<Assignment>(_s);
for (auto const& var: assignment.variableNames) for (auto const& var: assignment.variableNames)
if (m_variablesToReplace.count(var.name)) if (m_variablesToReplace.count(var.name))
assignedVariables.insert(var.name); assignedVariables.insert(var.name);
@ -304,14 +304,14 @@ void PropagateValues::operator()(VariableDeclaration& _varDecl)
if (m_variablesToReplace.count(variable)) if (m_variablesToReplace.count(variable))
{ {
// `let a := a_1` - regular declaration of non-SSA variable // `let a := a_1` - regular declaration of non-SSA variable
yulAssert(_varDecl.value->type() == typeid(Identifier), ""); yulAssert(holds_alternative<Identifier>(*_varDecl.value), "");
m_currentVariableValues[variable] = boost::get<Identifier>(*_varDecl.value).name; m_currentVariableValues[variable] = std::get<Identifier>(*_varDecl.value).name;
m_clearAtEndOfBlock.insert(variable); m_clearAtEndOfBlock.insert(variable);
} }
else if (_varDecl.value && _varDecl.value->type() == typeid(Identifier)) else if (_varDecl.value && holds_alternative<Identifier>(*_varDecl.value))
{ {
// `let a_1 := a` - assignment to SSA variable after a branch. // `let a_1 := a` - assignment to SSA variable after a branch.
YulString value = boost::get<Identifier>(*_varDecl.value).name; YulString value = std::get<Identifier>(*_varDecl.value).name;
if (m_variablesToReplace.count(value)) if (m_variablesToReplace.count(value))
{ {
// This is safe because `a_1` is not a "variable to replace" and thus // This is safe because `a_1` is not a "variable to replace" and thus
@ -333,8 +333,8 @@ void PropagateValues::operator()(Assignment& _assignment)
if (!m_variablesToReplace.count(name)) if (!m_variablesToReplace.count(name))
return; return;
yulAssert(_assignment.value && _assignment.value->type() == typeid(Identifier), ""); yulAssert(_assignment.value && holds_alternative<Identifier>(*_assignment.value), "");
m_currentVariableValues[name] = boost::get<Identifier>(*_assignment.value).name; m_currentVariableValues[name] = std::get<Identifier>(*_assignment.value).name;
m_clearAtEndOfBlock.insert(name); m_clearAtEndOfBlock.insert(name);
} }

View File

@ -165,13 +165,13 @@ pair<TerminationFinder::ControlFlow, size_t> TerminationFinder::firstUncondition
TerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement const& _statement) TerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement const& _statement)
{ {
if ( if (
_statement.type() == typeid(ExpressionStatement) && holds_alternative<ExpressionStatement>(_statement) &&
isTerminatingBuiltin(boost::get<ExpressionStatement>(_statement)) isTerminatingBuiltin(std::get<ExpressionStatement>(_statement))
) )
return ControlFlow::Terminate; return ControlFlow::Terminate;
else if (_statement.type() == typeid(Break)) else if (holds_alternative<Break>(_statement))
return ControlFlow::Break; return ControlFlow::Break;
else if (_statement.type() == typeid(Continue)) else if (holds_alternative<Continue>(_statement))
return ControlFlow::Continue; return ControlFlow::Continue;
else else
return ControlFlow::FlowOut; return ControlFlow::FlowOut;
@ -179,13 +179,13 @@ TerminationFinder::ControlFlow TerminationFinder::controlFlowKind(Statement cons
bool TerminationFinder::isTerminatingBuiltin(ExpressionStatement const& _exprStmnt) bool TerminationFinder::isTerminatingBuiltin(ExpressionStatement const& _exprStmnt)
{ {
if (_exprStmnt.expression.type() == typeid(FunctionalInstruction)) if (holds_alternative<FunctionalInstruction>(_exprStmnt.expression))
return eth::SemanticInformation::terminatesControlFlow( return eth::SemanticInformation::terminatesControlFlow(
boost::get<FunctionalInstruction>(_exprStmnt.expression).instruction std::get<FunctionalInstruction>(_exprStmnt.expression).instruction
); );
else if (_exprStmnt.expression.type() == typeid(FunctionCall)) else if (holds_alternative<FunctionCall>(_exprStmnt.expression))
if (auto const* dialect = dynamic_cast<EVMDialect const*>(&m_dialect)) if (auto const* dialect = dynamic_cast<EVMDialect const*>(&m_dialect))
if (auto const* builtin = dialect->builtin(boost::get<FunctionCall>(_exprStmnt.expression).functionName.name)) if (auto const* builtin = dialect->builtin(std::get<FunctionCall>(_exprStmnt.expression).functionName.name))
if (builtin->instruction) if (builtin->instruction)
return eth::SemanticInformation::terminatesControlFlow(*builtin->instruction); return eth::SemanticInformation::terminatesControlFlow(*builtin->instruction);
return false; return false;

View File

@ -67,13 +67,13 @@ bool SimplificationRules::isInitialized() const
std::optional<std::pair<dev::eth::Instruction, vector<Expression> const*>> std::optional<std::pair<dev::eth::Instruction, vector<Expression> const*>>
SimplificationRules::instructionAndArguments(Dialect const& _dialect, Expression const& _expr) SimplificationRules::instructionAndArguments(Dialect const& _dialect, Expression const& _expr)
{ {
if (_expr.type() == typeid(FunctionalInstruction)) if (holds_alternative<FunctionalInstruction>(_expr))
return make_pair(boost::get<FunctionalInstruction>(_expr).instruction, &boost::get<FunctionalInstruction>(_expr).arguments); return make_pair(std::get<FunctionalInstruction>(_expr).instruction, &std::get<FunctionalInstruction>(_expr).arguments);
else if (_expr.type() == typeid(FunctionCall)) else if (holds_alternative<FunctionCall>(_expr))
if (auto const* dialect = dynamic_cast<EVMDialect const*>(&_dialect)) if (auto const* dialect = dynamic_cast<EVMDialect const*>(&_dialect))
if (auto const* builtin = dialect->builtin(boost::get<FunctionCall>(_expr).functionName.name)) if (auto const* builtin = dialect->builtin(std::get<FunctionCall>(_expr).functionName.name))
if (builtin->instruction) if (builtin->instruction)
return make_pair(*builtin->instruction, &boost::get<FunctionCall>(_expr).arguments); return make_pair(*builtin->instruction, &std::get<FunctionCall>(_expr).arguments);
return {}; return {};
} }
@ -136,9 +136,9 @@ bool Pattern::matches(
// Resolve the variable if possible. // Resolve the variable if possible.
// Do not do it for "Any" because we can check identity better for variables. // Do not do it for "Any" because we can check identity better for variables.
if (m_kind != PatternKind::Any && _expr.type() == typeid(Identifier)) if (m_kind != PatternKind::Any && holds_alternative<Identifier>(_expr))
{ {
YulString varName = boost::get<Identifier>(_expr).name; YulString varName = std::get<Identifier>(_expr).name;
if (_ssaValues.count(varName)) if (_ssaValues.count(varName))
if (Expression const* new_expr = _ssaValues.at(varName)) if (Expression const* new_expr = _ssaValues.at(varName))
expr = new_expr; expr = new_expr;
@ -147,9 +147,9 @@ bool Pattern::matches(
if (m_kind == PatternKind::Constant) if (m_kind == PatternKind::Constant)
{ {
if (expr->type() != typeid(Literal)) if (!holds_alternative<Literal>(*expr))
return false; return false;
Literal const& literal = boost::get<Literal>(*expr); Literal const& literal = std::get<Literal>(*expr);
if (literal.kind != LiteralKind::Number) if (literal.kind != LiteralKind::Number)
return false; return false;
if (m_data && *m_data != u256(literal.value.str())) if (m_data && *m_data != u256(literal.value.str()))
@ -233,7 +233,7 @@ Expression Pattern::toExpression(SourceLocation const& _location) const
u256 Pattern::d() const u256 Pattern::d() const
{ {
return valueOfNumberLiteral(boost::get<Literal>(matchGroupValue())); return valueOfNumberLiteral(std::get<Literal>(matchGroupValue()));
} }
Expression const& Pattern::matchGroupValue() const Expression const& Pattern::matchGroupValue() const

View File

@ -85,9 +85,9 @@ public:
// get called on left-hand-sides of assignments. // get called on left-hand-sides of assignments.
void visit(Expression& _e) override void visit(Expression& _e) override
{ {
if (_e.type() == typeid(Identifier)) if (holds_alternative<Identifier>(_e))
{ {
YulString name = boost::get<Identifier>(_e).name; YulString name = std::get<Identifier>(_e).name;
if (m_expressionCodeCost.count(name)) if (m_expressionCodeCost.count(name))
{ {
if (!m_value.count(name)) if (!m_value.count(name))
@ -162,7 +162,7 @@ bool StackCompressor::run(
{ {
yulAssert( yulAssert(
_object.code && _object.code &&
_object.code->statements.size() > 0 && _object.code->statements.at(0).type() == typeid(Block), _object.code->statements.size() > 0 && holds_alternative<Block>(_object.code->statements.at(0)),
"Need to run the function grouper before the stack compressor." "Need to run the function grouper before the stack compressor."
); );
bool allowMSizeOptimzation = !MSizeFinder::containsMSize(_dialect, *_object.code); bool allowMSizeOptimzation = !MSizeFinder::containsMSize(_dialect, *_object.code);
@ -177,7 +177,7 @@ bool StackCompressor::run(
yulAssert(stackSurplus.at({}) > 0, "Invalid surplus value."); yulAssert(stackSurplus.at({}) > 0, "Invalid surplus value.");
eliminateVariables( eliminateVariables(
_dialect, _dialect,
boost::get<Block>(_object.code->statements.at(0)), std::get<Block>(_object.code->statements.at(0)),
stackSurplus.at({}), stackSurplus.at({}),
allowMSizeOptimzation allowMSizeOptimzation
); );
@ -185,7 +185,7 @@ bool StackCompressor::run(
for (size_t i = 1; i < _object.code->statements.size(); ++i) for (size_t i = 1; i < _object.code->statements.size(); ++i)
{ {
FunctionDefinition& fun = boost::get<FunctionDefinition>(_object.code->statements[i]); FunctionDefinition& fun = std::get<FunctionDefinition>(_object.code->statements[i]);
if (!stackSurplus.count(fun.name)) if (!stackSurplus.count(fun.name))
continue; continue;

View File

@ -95,7 +95,7 @@ void StructuralSimplifier::simplify(std::vector<yul::Statement>& _statements)
_statements, _statements,
[&](Statement& _stmt) -> OptionalStatements [&](Statement& _stmt) -> OptionalStatements
{ {
OptionalStatements result = boost::apply_visitor(visitor, _stmt); OptionalStatements result = std::visit(visitor, _stmt);
if (result) if (result)
simplify(*result); simplify(*result);
else else
@ -123,8 +123,8 @@ bool StructuralSimplifier::expressionAlwaysFalse(Expression const& _expression)
std::optional<dev::u256> StructuralSimplifier::hasLiteralValue(Expression const& _expression) const std::optional<dev::u256> StructuralSimplifier::hasLiteralValue(Expression const& _expression) const
{ {
if (_expression.type() == typeid(Literal)) if (holds_alternative<Literal>(_expression))
return valueOfLiteral(boost::get<Literal>(_expression)); return valueOfLiteral(std::get<Literal>(_expression));
else else
return std::optional<u256>(); return std::optional<u256>();
} }

View File

@ -28,9 +28,9 @@ using namespace yul;
Expression Substitution::translate(Expression const& _expression) Expression Substitution::translate(Expression const& _expression)
{ {
if (_expression.type() == typeid(Identifier)) if (holds_alternative<Identifier>(_expression))
{ {
YulString name = boost::get<Identifier>(_expression).name; YulString name = std::get<Identifier>(_expression).name;
if (m_substitutions.count(name)) if (m_substitutions.count(name))
// No recursive substitution // No recursive substitution
return ASTCopier().translate(*m_substitutions.at(name)); return ASTCopier().translate(*m_substitutions.at(name));

View File

@ -80,7 +80,7 @@ void OptimiserSuite::run(
set<YulString> reservedIdentifiers = _externallyUsedIdentifiers; set<YulString> reservedIdentifiers = _externallyUsedIdentifiers;
reservedIdentifiers += _dialect.fixedFunctionNames(); reservedIdentifiers += _dialect.fixedFunctionNames();
*_object.code = boost::get<Block>(Disambiguator( *_object.code = std::get<Block>(Disambiguator(
_dialect, _dialect,
*_object.analysisInfo, *_object.analysisInfo,
reservedIdentifiers reservedIdentifiers
@ -291,7 +291,7 @@ void OptimiserSuite::run(
{ {
// If the first statement is an empty block, remove it. // If the first statement is an empty block, remove it.
// We should only have function definitions after that. // We should only have function definitions after that.
if (ast.statements.size() > 1 && boost::get<Block>(ast.statements.front()).statements.empty()) if (ast.statements.size() > 1 && std::get<Block>(ast.statements.front()).statements.empty())
ast.statements.erase(ast.statements.begin()); ast.statements.erase(ast.statements.begin());
} }
suite.runSequence({ suite.runSequence({
@ -361,7 +361,7 @@ void OptimiserSuite::runSequence(std::vector<string> const& _steps, Block& _ast)
{ {
unique_ptr<Block> copy; unique_ptr<Block> copy;
if (m_debug == Debug::PrintChanges) if (m_debug == Debug::PrintChanges)
copy = make_unique<Block>(boost::get<Block>(ASTCopier{}(_ast))); copy = make_unique<Block>(std::get<Block>(ASTCopier{}(_ast)));
for (string const& step: _steps) for (string const& step: _steps)
{ {
if (m_debug == Debug::PrintStep) if (m_debug == Debug::PrintStep)
@ -376,7 +376,7 @@ void OptimiserSuite::runSequence(std::vector<string> const& _steps, Block& _ast)
{ {
cout << "== Running " << step << " changed the AST." << endl; cout << "== Running " << step << " changed the AST." << endl;
cout << AsmPrinter{}(_ast) << endl; cout << AsmPrinter{}(_ast) << endl;
copy = make_unique<Block>(boost::get<Block>(ASTCopier{}(_ast))); copy = make_unique<Block>(std::get<Block>(ASTCopier{}(_ast)));
} }
} }
} }

View File

@ -32,7 +32,7 @@ using namespace yul;
bool SyntacticallyEqual::operator()(Expression const& _lhs, Expression const& _rhs) bool SyntacticallyEqual::operator()(Expression const& _lhs, Expression const& _rhs)
{ {
return boost::apply_visitor([this](auto&& _lhsExpr, auto&& _rhsExpr) -> bool { return std::visit([this](auto&& _lhsExpr, auto&& _rhsExpr) -> bool {
// ``this->`` is redundant, but required to work around a bug present in gcc 6.x. // ``this->`` is redundant, but required to work around a bug present in gcc 6.x.
return this->expressionEqual(_lhsExpr, _rhsExpr); return this->expressionEqual(_lhsExpr, _rhsExpr);
}, _lhs, _rhs); }, _lhs, _rhs);
@ -40,7 +40,7 @@ bool SyntacticallyEqual::operator()(Expression const& _lhs, Expression const& _r
bool SyntacticallyEqual::operator()(Statement const& _lhs, Statement const& _rhs) bool SyntacticallyEqual::operator()(Statement const& _lhs, Statement const& _rhs)
{ {
return boost::apply_visitor([this](auto&& _lhsStmt, auto&& _rhsStmt) -> bool { return std::visit([this](auto&& _lhsStmt, auto&& _rhsStmt) -> bool {
// ``this->`` is redundant, but required to work around a bug present in gcc 6.x. // ``this->`` is redundant, but required to work around a bug present in gcc 6.x.
return this->statementEqual(_lhsStmt, _rhsStmt); return this->statementEqual(_lhsStmt, _rhsStmt);
}, _lhs, _rhs); }, _lhs, _rhs);

View File

@ -68,18 +68,18 @@ UnusedPruner::UnusedPruner(
void UnusedPruner::operator()(Block& _block) void UnusedPruner::operator()(Block& _block)
{ {
for (auto&& statement: _block.statements) for (auto&& statement: _block.statements)
if (statement.type() == typeid(FunctionDefinition)) if (holds_alternative<FunctionDefinition>(statement))
{ {
FunctionDefinition& funDef = boost::get<FunctionDefinition>(statement); FunctionDefinition& funDef = std::get<FunctionDefinition>(statement);
if (!used(funDef.name)) if (!used(funDef.name))
{ {
subtractReferences(ReferencesCounter::countReferences(funDef.body)); subtractReferences(ReferencesCounter::countReferences(funDef.body));
statement = Block{std::move(funDef.location), {}}; statement = Block{std::move(funDef.location), {}};
} }
} }
else if (statement.type() == typeid(VariableDeclaration)) else if (holds_alternative<VariableDeclaration>(statement))
{ {
VariableDeclaration& varDecl = boost::get<VariableDeclaration>(statement); VariableDeclaration& varDecl = std::get<VariableDeclaration>(statement);
// Multi-variable declarations are special. We can only remove it // Multi-variable declarations are special. We can only remove it
// if all variables are unused and the right-hand-side is either // if all variables are unused and the right-hand-side is either
// movable or it returns a single value. In the latter case, we // movable or it returns a single value. In the latter case, we
@ -108,9 +108,9 @@ void UnusedPruner::operator()(Block& _block)
}}; }};
} }
} }
else if (statement.type() == typeid(ExpressionStatement)) else if (holds_alternative<ExpressionStatement>(statement))
{ {
ExpressionStatement& exprStmt = boost::get<ExpressionStatement>(statement); ExpressionStatement& exprStmt = std::get<ExpressionStatement>(statement);
if ( if (
SideEffectsCollector(m_dialect, exprStmt.expression, m_functionSideEffects). SideEffectsCollector(m_dialect, exprStmt.expression, m_functionSideEffects).
sideEffectFree(m_allowMSizeOptimization) sideEffectFree(m_allowMSizeOptimization)

View File

@ -51,5 +51,5 @@ void VarDeclInitializer::operator()(Block& _block)
} }
} }
}; };
iterateReplacing(_block.statements, boost::apply_visitor(visitor)); iterateReplacing(_block.statements, [&](auto&& _statement) { return std::visit(visitor, _statement); });
} }

View File

@ -40,8 +40,8 @@ VarNameCleaner::VarNameCleaner(
m_translatedNames{} m_translatedNames{}
{ {
for (auto const& statement: _ast.statements) for (auto const& statement: _ast.statements)
if (statement.type() == typeid(FunctionDefinition)) if (holds_alternative<FunctionDefinition>(statement))
m_blacklist.insert(boost::get<FunctionDefinition>(statement).name); m_blacklist.insert(std::get<FunctionDefinition>(statement).name);
m_usedNames = m_blacklist; m_usedNames = m_blacklist;
} }

View File

@ -37,6 +37,8 @@
#include <boost/test/unit_test.hpp> #include <boost/test/unit_test.hpp>
#include <variant>
using namespace std; using namespace std;
using namespace langutil; using namespace langutil;
using namespace yul; using namespace yul;
@ -75,7 +77,7 @@ pair<shared_ptr<Block>, shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(strin
yul::Block yul::test::disambiguate(string const& _source, bool _yul) yul::Block yul::test::disambiguate(string const& _source, bool _yul)
{ {
auto result = parse(_source, _yul); auto result = parse(_source, _yul);
return boost::get<Block>(Disambiguator(defaultDialect(_yul), *result.second, {})(*result.first)); return std::get<Block>(Disambiguator(defaultDialect(_yul), *result.second, {})(*result.first));
} }
string yul::test::format(string const& _source, bool _yul) string yul::test::format(string const& _source, bool _yul)

View File

@ -74,6 +74,7 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <fstream> #include <fstream>
#include <variant>
using namespace dev; using namespace dev;
using namespace langutil; using namespace langutil;
@ -415,7 +416,7 @@ bool YulOptimizerTest::parse(ostream& _stream, string const& _linePrefix, bool c
void YulOptimizerTest::disambiguate() void YulOptimizerTest::disambiguate()
{ {
*m_ast = boost::get<Block>(Disambiguator(*m_dialect, *m_analysisInfo)(*m_ast)); *m_ast = std::get<Block>(Disambiguator(*m_dialect, *m_analysisInfo)(*m_ast));
m_analysisInfo.reset(); m_analysisInfo.reset();
updateContext(); updateContext();
} }

View File

@ -35,6 +35,7 @@
#include <boost/algorithm/cxx11/all_of.hpp> #include <boost/algorithm/cxx11/all_of.hpp>
#include <ostream> #include <ostream>
#include <variant>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -161,9 +162,9 @@ void Interpreter::operator()(Block const& _block)
openScope(); openScope();
// Register functions. // Register functions.
for (auto const& statement: _block.statements) for (auto const& statement: _block.statements)
if (statement.type() == typeid(FunctionDefinition)) if (holds_alternative<FunctionDefinition>(statement))
{ {
FunctionDefinition const& funDef = boost::get<FunctionDefinition>(statement); FunctionDefinition const& funDef = std::get<FunctionDefinition>(statement);
solAssert(!m_scopes.back().count(funDef.name), ""); solAssert(!m_scopes.back().count(funDef.name), "");
m_scopes.back().emplace(funDef.name, &funDef); m_scopes.back().emplace(funDef.name, &funDef);
} }

View File

@ -72,6 +72,7 @@
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <iostream> #include <iostream>
#include <variant>
using namespace std; using namespace std;
using namespace dev; using namespace dev;
@ -131,7 +132,7 @@ public:
set<YulString> reservedIdentifiers; set<YulString> reservedIdentifiers;
if (!disambiguated) if (!disambiguated)
{ {
*m_ast = boost::get<yul::Block>(Disambiguator(m_dialect, *m_analysisInfo)(*m_ast)); *m_ast = std::get<yul::Block>(Disambiguator(m_dialect, *m_analysisInfo)(*m_ast));
m_analysisInfo.reset(); m_analysisInfo.reset();
m_nameDispenser = make_shared<NameDispenser>(m_dialect, *m_ast, reservedIdentifiers); m_nameDispenser = make_shared<NameDispenser>(m_dialect, *m_ast, reservedIdentifiers);
disambiguated = true; disambiguated = true;