mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	Replace boost::variant by std::variant in libyul
This commit is contained in:
		
							parent
							
								
									6d85b63f87
								
							
						
					
					
						commit
						be849b3c47
					
				| @ -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: | ||||||
|  | |||||||
| @ -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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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, | ||||||
|  | |||||||
| @ -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( | ||||||
|  | |||||||
| @ -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); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -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>; | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
|  | |||||||
| @ -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) | ||||||
| 		{ | 		{ | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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) | ||||||
|  | |||||||
| @ -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) {} | ||||||
|  | |||||||
| @ -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; | ||||||
| } | } | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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(); | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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.
 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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) | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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) | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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--) | ||||||
| 		{ | 		{ | ||||||
|  | |||||||
| @ -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) | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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 {}; | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -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}; | ||||||
| 			} | 			} | ||||||
|  | |||||||
| @ -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), | ||||||
|  | |||||||
| @ -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))}; | ||||||
| 					} | 					} | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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); | ||||||
| 					} | 					} | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -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() | ||||||
| 		); | 		); | ||||||
|  | |||||||
| @ -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> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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, ""); | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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, | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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) | ||||||
|  | |||||||
| @ -29,8 +29,6 @@ | |||||||
| 
 | 
 | ||||||
| #include <liblangutil/SourceLocation.h> | #include <liblangutil/SourceLocation.h> | ||||||
| 
 | 
 | ||||||
| #include <boost/variant.hpp> |  | ||||||
| 
 |  | ||||||
| #include <optional> | #include <optional> | ||||||
| #include <set> | #include <set> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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; | ||||||
| } | } | ||||||
|  | |||||||
| @ -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, {}}; | ||||||
|  | |||||||
| @ -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(); | ||||||
|  | |||||||
| @ -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)) | ||||||
|  | |||||||
| @ -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) | ||||||
|  | |||||||
| @ -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, | ||||||
|  | |||||||
| @ -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); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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; | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -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 && | ||||||
|  | |||||||
| @ -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); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
| @ -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 | ||||||
|  | |||||||
| @ -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; | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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>(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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)); | ||||||
|  | |||||||
| @ -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))); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | |||||||
| @ -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); | ||||||
|  | |||||||
| @ -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) | ||||||
|  | |||||||
| @ -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); }); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -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) | ||||||
|  | |||||||
| @ -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(); | ||||||
| } | } | ||||||
|  | |||||||
| @ -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); | ||||||
| 		} | 		} | ||||||
|  | |||||||
| @ -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; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user