Purge using namespace std from libyul/backends

Signed-off-by: Jun Zhang <jun@junz.org>
This commit is contained in:
Jun Zhang 2023-08-23 10:24:09 +08:00
parent 37e18612c5
commit 1ebdab43d8
12 changed files with 152 additions and 161 deletions

View File

@ -28,7 +28,6 @@
#include <libsolutil/StackTooDeepString.h>
using namespace std;
using namespace solidity;
using namespace solidity::yul;
using namespace solidity::util;

View File

@ -30,7 +30,6 @@
#include <variant>
using namespace std;
using namespace solidity;
using namespace solidity::yul;
using namespace solidity::util;
@ -48,9 +47,9 @@ struct MiniEVMInterpreter
return std::visit(*this, _expr);
}
u256 eval(evmasm::Instruction _instr, vector<Expression> const& _arguments)
u256 eval(evmasm::Instruction _instr, std::vector<Expression> const& _arguments)
{
vector<u256> args;
std::vector<u256> args;
for (auto const& arg: _arguments)
args.emplace_back(eval(arg));
switch (_instr)
@ -92,7 +91,7 @@ struct MiniEVMInterpreter
void ConstantOptimiser::visit(Expression& _e)
{
if (holds_alternative<Literal>(_e))
if (std::holds_alternative<Literal>(_e))
{
Literal const& literal = std::get<Literal>(_e);
if (literal.kind != LiteralKind::Number)
@ -115,7 +114,7 @@ Expression const* RepresentationFinder::tryFindRepresentation(u256 const& _value
return nullptr;
Representation const& repr = findRepresentation(_value);
if (holds_alternative<Literal>(*repr.expression))
if (std::holds_alternative<Literal>(*repr.expression))
return nullptr;
else
return repr.expression.get();
@ -180,7 +179,7 @@ Representation const& RepresentationFinder::findRepresentation(u256 const& _valu
Representation RepresentationFinder::represent(u256 const& _value) const
{
Representation repr;
repr.expression = make_unique<Expression>(Literal{m_debugData, LiteralKind::Number, YulString{formatNumber(_value)}, {}});
repr.expression = std::make_unique<Expression>(Literal{m_debugData, LiteralKind::Number, YulString{formatNumber(_value)}, {}});
repr.cost = m_meter.costs(*repr.expression);
return repr;
}
@ -191,7 +190,7 @@ Representation RepresentationFinder::represent(
) const
{
Representation repr;
repr.expression = make_unique<Expression>(FunctionCall{
repr.expression = std::make_unique<Expression>(FunctionCall{
m_debugData,
Identifier{m_debugData, _instruction},
{ASTCopier{}.translate(*_argument.expression)}
@ -207,7 +206,7 @@ Representation RepresentationFinder::represent(
) const
{
Representation repr;
repr.expression = make_unique<Expression>(FunctionCall{
repr.expression = std::make_unique<Expression>(FunctionCall{
m_debugData,
Identifier{m_debugData, _instruction},
{ASTCopier{}.translate(*_arg1.expression), ASTCopier{}.translate(*_arg2.expression)}

View File

@ -45,7 +45,6 @@
using namespace solidity;
using namespace solidity::yul;
using namespace std;
namespace
{
@ -82,15 +81,15 @@ void cleanUnreachable(CFG& _cfg)
/// Sets the ``recursive`` member to ``true`` for all recursive function calls.
void markRecursiveCalls(CFG& _cfg)
{
map<CFG::BasicBlock*, vector<CFG::FunctionCall*>> callsPerBlock;
std::map<CFG::BasicBlock*, std::vector<CFG::FunctionCall*>> callsPerBlock;
auto const& findCalls = [&](CFG::BasicBlock* _block)
{
if (auto* calls = util::valueOrNullptr(callsPerBlock, _block))
return *calls;
vector<CFG::FunctionCall*>& calls = callsPerBlock[_block];
std::vector<CFG::FunctionCall*>& calls = callsPerBlock[_block];
util::BreadthFirstSearch<CFG::BasicBlock*>{{_block}}.run([&](CFG::BasicBlock* _block, auto _addChild) {
for (auto& operation: _block->operations)
if (auto* functionCall = get_if<CFG::FunctionCall>(&operation.operation))
if (auto* functionCall = std::get_if<CFG::FunctionCall>(&operation.operation))
calls.emplace_back(functionCall);
std::visit(util::GenericVisitor{
[&](CFG::BasicBlock::MainExit const&) {},
@ -131,7 +130,7 @@ void markRecursiveCalls(CFG& _cfg)
/// Entering such a block means that control flow will never return to a previously visited block.
void markStartsOfSubGraphs(CFG& _cfg)
{
vector<CFG::BasicBlock*> entries;
std::vector<CFG::BasicBlock*> entries;
entries.emplace_back(_cfg.entry);
for (auto&& functionInfo: _cfg.functionInfo | ranges::views::values)
entries.emplace_back(functionInfo.entry);
@ -141,17 +140,17 @@ void markStartsOfSubGraphs(CFG& _cfg)
* Detect bridges following Algorithm 1 in https://arxiv.org/pdf/2108.07346.pdf
* and mark the bridge targets as starts of sub-graphs.
*/
set<CFG::BasicBlock*> visited;
map<CFG::BasicBlock*, size_t> disc;
map<CFG::BasicBlock*, size_t> low;
map<CFG::BasicBlock*, CFG::BasicBlock*> parent;
std::set<CFG::BasicBlock*> visited;
std::map<CFG::BasicBlock*, size_t> disc;
std::map<CFG::BasicBlock*, size_t> low;
std::map<CFG::BasicBlock*, CFG::BasicBlock*> parent;
size_t time = 0;
auto dfs = [&](CFG::BasicBlock* _u, auto _recurse) -> void {
visited.insert(_u);
disc[_u] = low[_u] = time;
time++;
vector<CFG::BasicBlock*> children = _u->entries;
std::vector<CFG::BasicBlock*> children = _u->entries;
visit(util::GenericVisitor{
[&](CFG::BasicBlock::Jump const& _jump) {
children.emplace_back(_jump.target);
@ -171,7 +170,7 @@ void markStartsOfSubGraphs(CFG& _cfg)
{
parent[v] = _u;
_recurse(v, _recurse);
low[_u] = min(low[_u], low[v]);
low[_u] = std::min(low[_u], low[v]);
if (low[v] > disc[_u])
{
// _u <-> v is a cut edge in the undirected graph
@ -186,7 +185,7 @@ void markStartsOfSubGraphs(CFG& _cfg)
}
}
else if (v != parent[_u])
low[_u] = min(low[_u], disc[v]);
low[_u] = std::min(low[_u], disc[v]);
};
dfs(entry, dfs);
}
@ -234,7 +233,7 @@ std::unique_ptr<CFG> ControlFlowGraphBuilder::build(
ControlFlowGraphBuilder::ControlFlowGraphBuilder(
CFG& _graph,
AsmAnalysisInfo const& _analysisInfo,
map<FunctionDefinition const*, ControlFlowSideEffects> const& _functionSideEffects,
std::map<FunctionDefinition const*, ControlFlowSideEffects> const& _functionSideEffects,
Dialect const& _dialect
):
m_graph(_graph),
@ -271,7 +270,7 @@ void ControlFlowGraphBuilder::operator()(VariableDeclaration const& _varDecl)
yulAssert(m_currentBlock, "");
auto declaredVariables = _varDecl.variables | ranges::views::transform([&](TypedName const& _var) {
return VariableSlot{lookupVariable(_var.name), _var.debugData};
}) | ranges::to<vector<VariableSlot>>;
}) | ranges::to<std::vector<VariableSlot>>;
Stack input;
if (_varDecl.value)
input = visitAssignmentRightHandSide(*_varDecl.value, declaredVariables.size());
@ -287,7 +286,7 @@ void ControlFlowGraphBuilder::operator()(Assignment const& _assignment)
{
auto assignedVariables = _assignment.variableNames | ranges::views::transform([&](Identifier const& _var) {
return VariableSlot{lookupVariable(_var.name), _var.debugData};
}) | ranges::to<vector<VariableSlot>>;
}) | ranges::to<std::vector<VariableSlot>>;
Stack input = visitAssignmentRightHandSide(*_assignment.value, assignedVariables.size());
yulAssert(m_currentBlock);
@ -314,7 +313,7 @@ void ControlFlowGraphBuilder::operator()(Block const& _block)
{
ScopedSaveAndRestore saveScope(m_scope, m_info.scopes.at(&_block).get());
for (auto const& statement: _block.statements)
if (auto const* function = get_if<FunctionDefinition>(&statement))
if (auto const* function = std::get_if<FunctionDefinition>(&statement))
registerFunction(*function);
for (auto const& statement: _block.statements)
std::visit(*this, statement);
@ -334,10 +333,10 @@ void ControlFlowGraphBuilder::operator()(If const& _if)
void ControlFlowGraphBuilder::operator()(Switch const& _switch)
{
yulAssert(m_currentBlock, "");
shared_ptr<DebugData const> preSwitchDebugData = debugDataOf(_switch);
std::shared_ptr<DebugData const> preSwitchDebugData = debugDataOf(_switch);
auto ghostVariableId = m_graph.ghostVariables.size();
YulString ghostVariableName("GHOST[" + to_string(ghostVariableId) + "]");
YulString ghostVariableName("GHOST[" + std::to_string(ghostVariableId) + "]");
auto& ghostVar = m_graph.ghostVariables.emplace_back(Scope::Variable{""_yulstring, ghostVariableName});
// Artificially generate:
@ -394,12 +393,12 @@ void ControlFlowGraphBuilder::operator()(Switch const& _switch)
void ControlFlowGraphBuilder::operator()(ForLoop const& _loop)
{
shared_ptr<DebugData const> preLoopDebugData = debugDataOf(_loop);
std::shared_ptr<DebugData const> preLoopDebugData = debugDataOf(_loop);
ScopedSaveAndRestore scopeRestore(m_scope, m_info.scopes.at(&_loop.pre).get());
(*this)(_loop.pre);
std::optional<bool> constantCondition;
if (auto const* literalCondition = get_if<yul::Literal>(_loop.condition.get()))
if (auto const* literalCondition = std::get_if<yul::Literal>(_loop.condition.get()))
constantCondition = valueOfLiteral(*literalCondition) != 0;
CFG::BasicBlock& loopCondition = m_graph.makeBlock(debugDataOf(*_loop.condition));
@ -497,13 +496,13 @@ void ControlFlowGraphBuilder::registerFunction(FunctionDefinition const& _functi
std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(_param.name)),
_param.debugData
};
}) | ranges::to<vector>,
}) | ranges::to<std::vector>,
_functionDefinition.returnVariables | ranges::views::transform([&](auto const& _retVar) {
return VariableSlot{
std::get<Scope::Variable>(virtualFunctionScope->identifiers.at(_retVar.name)),
_retVar.debugData
};
}) | ranges::to<vector>,
}) | ranges::to<std::vector>,
{},
m_functionSideEffects.at(&_functionDefinition).canContinue
})).second;
@ -609,7 +608,7 @@ Scope::Variable const& ControlFlowGraphBuilder::lookupVariable(YulString _name)
}
void ControlFlowGraphBuilder::makeConditionalJump(
shared_ptr<DebugData const> _debugData,
std::shared_ptr<DebugData const> _debugData,
StackSlot _condition,
CFG::BasicBlock& _nonZero,
CFG::BasicBlock& _zero
@ -628,7 +627,7 @@ void ControlFlowGraphBuilder::makeConditionalJump(
}
void ControlFlowGraphBuilder::jump(
shared_ptr<DebugData const> _debugData,
std::shared_ptr<DebugData const> _debugData,
CFG::BasicBlock& _target,
bool backwards
)

View File

@ -42,7 +42,6 @@
#include <utility>
#include <variant>
using namespace std;
using namespace solidity;
using namespace solidity::yul;
using namespace solidity::util;
@ -56,9 +55,9 @@ CodeTransform::CodeTransform(
BuiltinContext& _builtinContext,
ExternalIdentifierAccess::CodeGenerator _identifierAccessCodeGen,
UseNamedLabels _useNamedLabelsForFunctions,
shared_ptr<Context> _context,
vector<TypedName> _delayedReturnVariables,
optional<AbstractAssembly::LabelID> _functionExitLabel
std::shared_ptr<Context> _context,
std::vector<TypedName> _delayedReturnVariables,
std::optional<AbstractAssembly::LabelID> _functionExitLabel
):
m_assembly(_assembly),
m_info(_analysisInfo),
@ -74,7 +73,7 @@ CodeTransform::CodeTransform(
if (!m_context)
{
// initialize
m_context = make_shared<Context>();
m_context = std::make_shared<Context>();
if (m_allowStackOpt)
m_context->variableReferences = VariableReferenceCounter::run(m_info, _block);
}
@ -103,7 +102,7 @@ void CodeTransform::freeUnusedVariables(bool _popUnusedSlotsAtStackTop)
return;
for (auto const& identifier: m_scope->identifiers)
if (Scope::Variable const* var = get_if<Scope::Variable>(&identifier.second))
if (Scope::Variable const* var = std::get_if<Scope::Variable>(&identifier.second))
if (m_variablesScheduledForDeletion.count(var))
deleteVariable(*var);
// Directly in a function body block, we can also delete the function arguments,
@ -112,7 +111,7 @@ void CodeTransform::freeUnusedVariables(bool _popUnusedSlotsAtStackTop)
// effect, so we only do it before that.
if (!returnVariablesAndFunctionExitAreSetup() && !m_scope->functionScope && m_scope->superScope && m_scope->superScope->functionScope)
for (auto const& identifier: m_scope->superScope->identifiers)
if (Scope::Variable const* var = get_if<Scope::Variable>(&identifier.second))
if (Scope::Variable const* var = std::get_if<Scope::Variable>(&identifier.second))
if (m_variablesScheduledForDeletion.count(var))
deleteVariable(*var);
@ -317,7 +316,7 @@ void CodeTransform::operator()(Switch const& _switch)
{
visitExpression(*_switch.expression);
int expressionHeight = m_assembly.stackHeight();
map<Case const*, AbstractAssembly::LabelID> caseBodies;
std::map<Case const*, AbstractAssembly::LabelID> caseBodies;
AbstractAssembly::LabelID end = m_assembly.newLabelId();
for (Case const& c: _switch.cases)
{
@ -447,7 +446,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
// This vector holds the desired target positions of all stack slots and is
// modified parallel to the actual stack.
vector<int> stackLayout(static_cast<size_t>(m_assembly.stackHeight()), -1);
std::vector<int> stackLayout(static_cast<size_t>(m_assembly.stackHeight()), -1);
stackLayout[0] = static_cast<int>(_function.returnVariables.size()); // Move return label to the top
for (auto&& [n, returnVariable]: ranges::views::enumerate(_function.returnVariables))
stackLayout.at(m_context->variableStackHeights.at(
@ -463,7 +462,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
"The function " +
_function.name.str() +
" has " +
to_string(stackLayout.size() - 17) +
std::to_string(stackLayout.size() - 17) +
" parameters or return variables too many to fit the stack size."
);
stackError(std::move(error), m_assembly.stackHeight() - static_cast<int>(_function.parameters.size()));
@ -479,7 +478,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
else
{
m_assembly.appendInstruction(evmasm::swapInstruction(static_cast<unsigned>(stackLayout.size()) - static_cast<unsigned>(stackLayout.back()) - 1u));
swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back());
std::swap(stackLayout[static_cast<size_t>(stackLayout.back())], stackLayout.back());
}
for (size_t i = 0; i < stackLayout.size(); ++i)
yulAssert(i == static_cast<size_t>(stackLayout[i]), "Error reshuffling stack.");
@ -571,7 +570,7 @@ void CodeTransform::operator()(Block const& _block)
m_scope = m_info.scopes.at(&_block).get();
for (auto const& statement: _block.statements)
if (auto function = get_if<FunctionDefinition>(&statement))
if (auto function = std::get_if<FunctionDefinition>(&statement))
createFunctionEntryID(*function);
int blockStartStackHeight = m_assembly.stackHeight();
@ -579,7 +578,7 @@ void CodeTransform::operator()(Block const& _block)
bool isOutermostFunctionBodyBlock = m_scope && m_scope->superScope && m_scope->superScope->functionScope;
bool performValidation = !m_allowStackOpt || !isOutermostFunctionBodyBlock;
finalizeBlock(_block, performValidation ? make_optional(blockStartStackHeight) : nullopt);
finalizeBlock(_block, performValidation ? std::make_optional(blockStartStackHeight) : std::nullopt);
m_scope = originalScope;
}
@ -588,7 +587,7 @@ void CodeTransform::createFunctionEntryID(FunctionDefinition const& _function)
Scope::Function& scopeFunction = std::get<Scope::Function>(m_scope->identifiers.at(_function.name));
yulAssert(!m_context->functionEntryIDs.count(&scopeFunction), "");
optional<size_t> astID;
std::optional<size_t> astID;
if (_function.debugData)
astID = _function.debugData->astID;
@ -659,16 +658,16 @@ void CodeTransform::setupReturnVariablesAndFunctionExit()
namespace
{
bool statementNeedsReturnVariableSetup(Statement const& _statement, vector<TypedName> const& _returnVariables)
bool statementNeedsReturnVariableSetup(Statement const& _statement, std::vector<TypedName> const& _returnVariables)
{
if (holds_alternative<FunctionDefinition>(_statement))
if (std::holds_alternative<FunctionDefinition>(_statement))
return true;
if (
holds_alternative<ExpressionStatement>(_statement) ||
holds_alternative<Assignment>(_statement)
std::holds_alternative<ExpressionStatement>(_statement) ||
std::holds_alternative<Assignment>(_statement)
)
{
map<YulString, size_t> references = VariableReferencesCounter::countReferences(_statement);
std::map<YulString, size_t> references = VariableReferencesCounter::countReferences(_statement);
auto isReferenced = [&references](TypedName const& _returnVariable) {
return references.count(_returnVariable.name);
};
@ -680,7 +679,7 @@ bool statementNeedsReturnVariableSetup(Statement const& _statement, vector<Typed
}
void CodeTransform::visitStatements(vector<Statement> const& _statements)
void CodeTransform::visitStatements(std::vector<Statement> const& _statements)
{
std::optional<AbstractAssembly::LabelID> jumpTarget = std::nullopt;
@ -716,7 +715,7 @@ void CodeTransform::visitStatements(vector<Statement> const& _statements)
freeUnusedVariables();
}
void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartStackHeight)
void CodeTransform::finalizeBlock(Block const& _block, std::optional<int> blockStartStackHeight)
{
m_assembly.setSourceLocation(originLocationOf(_block));
@ -725,7 +724,7 @@ void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartS
// pop variables
yulAssert(m_info.scopes.at(&_block).get() == m_scope, "");
for (auto const& id: m_scope->identifiers)
if (holds_alternative<Scope::Variable>(id.second))
if (std::holds_alternative<Scope::Variable>(id.second))
{
Scope::Variable const& var = std::get<Scope::Variable>(id.second);
if (m_allowStackOpt)
@ -740,11 +739,11 @@ void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartS
if (blockStartStackHeight)
{
int deposit = m_assembly.stackHeight() - *blockStartStackHeight;
yulAssert(deposit == 0, "Invalid stack height at end of block: " + to_string(deposit));
yulAssert(deposit == 0, "Invalid stack height at end of block: " + std::to_string(deposit));
}
}
void CodeTransform::generateMultiAssignment(vector<Identifier> const& _variableNames)
void CodeTransform::generateMultiAssignment(std::vector<Identifier> const& _variableNames)
{
yulAssert(m_scope, "");
for (auto const& variableName: _variableNames | ranges::views::reverse)
@ -786,7 +785,7 @@ size_t CodeTransform::variableHeightDiff(Scope::Variable const& _var, YulString
"Variable " +
_varName.str() +
" is " +
to_string(heightDiff - limit) +
std::to_string(heightDiff - limit) +
" slot(s) too deep inside the stack. " +
stackTooDeepString
);
@ -798,7 +797,7 @@ size_t CodeTransform::variableHeightDiff(Scope::Variable const& _var, YulString
int CodeTransform::variableStackHeight(YulString _name) const
{
Scope::Variable const* var = get_if<Scope::Variable>(m_scope->lookup(_name));
Scope::Variable const* var = std::get_if<Scope::Variable>(m_scope->lookup(_name));
yulAssert(var, "");
return static_cast<int>(m_context->variableStackHeights.at(var));
}

View File

@ -38,7 +38,7 @@
#include <regex>
using namespace std;
using namespace std::string_literals;
using namespace solidity;
using namespace solidity::yul;
using namespace solidity::util;
@ -46,9 +46,9 @@ using namespace solidity::util;
namespace
{
pair<YulString, BuiltinFunctionForEVM> createEVMFunction(
std::pair<YulString, BuiltinFunctionForEVM> createEVMFunction(
langutil::EVMVersion _evmVersion,
string const& _name,
std::string const& _name,
evmasm::Instruction _instruction
)
{
@ -87,12 +87,12 @@ pair<YulString, BuiltinFunctionForEVM> createEVMFunction(
return {name, std::move(f)};
}
pair<YulString, BuiltinFunctionForEVM> createFunction(
string _name,
std::pair<YulString, BuiltinFunctionForEVM> createFunction(
std::string _name,
size_t _params,
size_t _returns,
SideEffects _sideEffects,
vector<optional<LiteralKind>> _literalArguments,
std::vector<std::optional<LiteralKind>> _literalArguments,
std::function<void(FunctionCall const&, AbstractAssembly&, BuiltinContext&)> _generateCode
)
{
@ -111,7 +111,7 @@ pair<YulString, BuiltinFunctionForEVM> createFunction(
return {name, f};
}
set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion)
std::set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion)
{
// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name
// basefee for VMs before london.
@ -122,20 +122,20 @@ set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion)
// TODO remove this in 0.9.0. We allow creating functions or identifiers in Yul with the name
// prevrandao for VMs before paris.
auto prevRandaoException = [&](string const& _instrName) -> bool
auto prevRandaoException = [&](std::string const& _instrName) -> bool
{
// Using string comparison as the opcode is the same as for "difficulty"
return _instrName == "prevrandao" && _evmVersion < langutil::EVMVersion::paris();
};
set<YulString> reserved;
std::set<YulString> reserved;
for (auto const& instr: evmasm::c_instructions)
{
string name = toLower(instr.first);
std::string name = toLower(instr.first);
if (!baseFeeException(instr.second) && !prevRandaoException(name))
reserved.emplace(name);
}
reserved += vector<YulString>{
reserved += std::vector<YulString>{
"linkersymbol"_yulstring,
"datasize"_yulstring,
"dataoffset"_yulstring,
@ -146,19 +146,19 @@ set<YulString> createReservedIdentifiers(langutil::EVMVersion _evmVersion)
return reserved;
}
map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVersion, bool _objectAccess)
std::map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVersion, bool _objectAccess)
{
// Exclude prevrandao as builtin for VMs before paris and difficulty for VMs after paris.
auto prevRandaoException = [&](string const& _instrName) -> bool
auto prevRandaoException = [&](std::string const& _instrName) -> bool
{
return (_instrName == "prevrandao" && _evmVersion < langutil::EVMVersion::paris()) || (_instrName == "difficulty" && _evmVersion >= langutil::EVMVersion::paris());
};
map<YulString, BuiltinFunctionForEVM> builtins;
std::map<YulString, BuiltinFunctionForEVM> builtins;
for (auto const& instr: evmasm::c_instructions)
{
string name = toLower(instr.first);
std::string name = toLower(instr.first);
auto const opcode = instr.second;
if (
@ -198,7 +198,7 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe
BuiltinContext&
) {
yulAssert(_call.arguments.size() == 1, "");
Literal const* literal = get_if<Literal>(&_call.arguments.front());
Literal const* literal = std::get_if<Literal>(&_call.arguments.front());
yulAssert(literal, "");
_assembly.appendConstant(valueOfLiteral(*literal));
})
@ -217,10 +217,10 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe
_assembly.appendAssemblySize();
else
{
vector<size_t> subIdPath =
std::vector<size_t> subIdPath =
_context.subIDs.count(dataName) == 0 ?
_context.currentObject->pathToSubObject(dataName) :
vector<size_t>{_context.subIDs.at(dataName)};
std::vector<size_t>{_context.subIDs.at(dataName)};
yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">.");
_assembly.appendDataSize(subIdPath);
}
@ -238,10 +238,10 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe
_assembly.appendConstant(0);
else
{
vector<size_t> subIdPath =
std::vector<size_t> subIdPath =
_context.subIDs.count(dataName) == 0 ?
_context.currentObject->pathToSubObject(dataName) :
vector<size_t>{_context.subIDs.at(dataName)};
std::vector<size_t>{_context.subIDs.at(dataName)};
yulAssert(!subIdPath.empty(), "Could not find assembly object <" + dataName.str() + ">.");
_assembly.appendDataOffset(subIdPath);
}
@ -295,9 +295,9 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe
return builtins;
}
regex const& verbatimPattern()
std::regex const& verbatimPattern()
{
regex static const pattern{"verbatim_([1-9]?[0-9])i_([1-9]?[0-9])o"};
std::regex static const pattern{"verbatim_([1-9]?[0-9])i_([1-9]?[0-9])o"};
return pattern;
}
@ -316,7 +316,7 @@ BuiltinFunctionForEVM const* EVMDialect::builtin(YulString _name) const
{
if (m_objectAccess)
{
smatch match;
std::smatch match;
if (regex_match(_name.str(), match, verbatimPattern()))
return verbatimFunction(stoul(match[1]), stoul(match[2]));
}
@ -337,19 +337,19 @@ bool EVMDialect::reservedIdentifier(YulString _name) const
EVMDialect const& EVMDialect::strictAssemblyForEVM(langutil::EVMVersion _version)
{
static map<langutil::EVMVersion, unique_ptr<EVMDialect const>> dialects;
static std::map<langutil::EVMVersion, std::unique_ptr<EVMDialect const>> dialects;
static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }};
if (!dialects[_version])
dialects[_version] = make_unique<EVMDialect>(_version, false);
dialects[_version] = std::make_unique<EVMDialect>(_version, false);
return *dialects[_version];
}
EVMDialect const& EVMDialect::strictAssemblyForEVMObjects(langutil::EVMVersion _version)
{
static map<langutil::EVMVersion, unique_ptr<EVMDialect const>> dialects;
static std::map<langutil::EVMVersion, std::unique_ptr<EVMDialect const>> dialects;
static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }};
if (!dialects[_version])
dialects[_version] = make_unique<EVMDialect>(_version, true);
dialects[_version] = std::make_unique<EVMDialect>(_version, true);
return *dialects[_version];
}
@ -374,16 +374,16 @@ SideEffects EVMDialect::sideEffectsOfInstruction(evmasm::Instruction _instructio
BuiltinFunctionForEVM const* EVMDialect::verbatimFunction(size_t _arguments, size_t _returnVariables) const
{
pair<size_t, size_t> key{_arguments, _returnVariables};
shared_ptr<BuiltinFunctionForEVM const>& function = m_verbatimFunctions[key];
std::pair<size_t, size_t> key{_arguments, _returnVariables};
std::shared_ptr<BuiltinFunctionForEVM const>& function = m_verbatimFunctions[key];
if (!function)
{
BuiltinFunctionForEVM builtinFunction = createFunction(
"verbatim_" + to_string(_arguments) + "i_" + to_string(_returnVariables) + "o",
"verbatim_" + std::to_string(_arguments) + "i_" + std::to_string(_returnVariables) + "o",
1 + _arguments,
_returnVariables,
SideEffects::worst(),
vector<optional<LiteralKind>>{LiteralKind::String} + vector<optional<LiteralKind>>(_arguments),
std::vector<std::optional<LiteralKind>>{LiteralKind::String} + std::vector<std::optional<LiteralKind>>(_arguments),
[=](
FunctionCall const& _call,
AbstractAssembly& _assembly,
@ -400,7 +400,7 @@ BuiltinFunctionForEVM const* EVMDialect::verbatimFunction(size_t _arguments, siz
}
).second;
builtinFunction.isMSize = true;
function = make_shared<BuiltinFunctionForEVM const>(std::move(builtinFunction));
function = std::make_shared<BuiltinFunctionForEVM const>(std::move(builtinFunction));
}
return function.get();
}
@ -501,9 +501,9 @@ BuiltinFunctionForEVM const* EVMDialectTyped::equalityFunction(YulString _type)
EVMDialectTyped const& EVMDialectTyped::instance(langutil::EVMVersion _version)
{
static map<langutil::EVMVersion, unique_ptr<EVMDialectTyped const>> dialects;
static std::map<langutil::EVMVersion, std::unique_ptr<EVMDialectTyped const>> dialects;
static YulStringRepository::ResetCallback callback{[&] { dialects.clear(); }};
if (!dialects[_version])
dialects[_version] = make_unique<EVMDialectTyped>(_version, true);
dialects[_version] = std::make_unique<EVMDialectTyped>(_version, true);
return *dialects[_version];
}

View File

@ -31,7 +31,6 @@
#include <libsolutil/CommonData.h>
using namespace std;
using namespace solidity;
using namespace solidity::yul;
using namespace solidity::util;
@ -52,7 +51,7 @@ bigint GasMeter::combineCosts(std::pair<bigint, bigint> _costs) const
}
pair<bigint, bigint> GasMeterVisitor::costs(
std::pair<bigint, bigint> GasMeterVisitor::costs(
Expression const& _expression,
EVMDialect const& _dialect,
bool _isCreation
@ -63,7 +62,7 @@ pair<bigint, bigint> GasMeterVisitor::costs(
return {gmv.m_runGas, gmv.m_dataGas};
}
pair<bigint, bigint> GasMeterVisitor::instructionCosts(
std::pair<bigint, bigint> GasMeterVisitor::instructionCosts(
evmasm::Instruction _instruction,
EVMDialect const& _dialect,
bool _isCreation

View File

@ -33,7 +33,6 @@
#include <boost/algorithm/string.hpp>
using namespace solidity::yul;
using namespace std;
void EVMObjectCompiler::compile(
Object& _object,
@ -91,12 +90,12 @@ void EVMObjectCompiler::run(Object& _object, bool _optimize)
);
if (!stackErrors.empty())
{
vector<FunctionCall*> memoryGuardCalls = FunctionCallFinder::run(
std::vector<FunctionCall*> memoryGuardCalls = FunctionCallFinder::run(
*_object.code,
"memoryguard"_yulstring
);
auto stackError = stackErrors.front();
string msg = stackError.comment() ? *stackError.comment() : "";
std::string msg = stackError.comment() ? *stackError.comment() : "";
if (memoryGuardCalls.empty())
msg += "\nNo memoryguard was present. "
"Consider using memory-safe assembly only and annotating it via "

View File

@ -33,7 +33,6 @@
#include <memory>
#include <functional>
using namespace std;
using namespace solidity;
using namespace solidity::yul;
using namespace solidity::util;
@ -122,14 +121,14 @@ void EthAssemblyAdapter::appendAssemblySize()
m_assembly.appendProgramSize();
}
pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EthAssemblyAdapter::createSubAssembly(bool _creation, string _name)
std::pair<std::shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> EthAssemblyAdapter::createSubAssembly(bool _creation, std::string _name)
{
shared_ptr<evmasm::Assembly> assembly{make_shared<evmasm::Assembly>(m_assembly.evmVersion(), _creation, std::move(_name))};
std::shared_ptr<evmasm::Assembly> assembly{std::make_shared<evmasm::Assembly>(m_assembly.evmVersion(), _creation, std::move(_name))};
auto sub = m_assembly.newSub(assembly);
return {make_shared<EthAssemblyAdapter>(*assembly), static_cast<size_t>(sub.data())};
return {std::make_shared<EthAssemblyAdapter>(*assembly), static_cast<size_t>(sub.data())};
}
void EthAssemblyAdapter::appendDataOffset(vector<AbstractAssembly::SubID> const& _subPath)
void EthAssemblyAdapter::appendDataOffset(std::vector<AbstractAssembly::SubID> const& _subPath)
{
if (auto it = m_dataHashBySubId.find(_subPath[0]); it != m_dataHashBySubId.end())
{
@ -141,7 +140,7 @@ void EthAssemblyAdapter::appendDataOffset(vector<AbstractAssembly::SubID> const&
m_assembly.pushSubroutineOffset(m_assembly.encodeSubPath(_subPath));
}
void EthAssemblyAdapter::appendDataSize(vector<AbstractAssembly::SubID> const& _subPath)
void EthAssemblyAdapter::appendDataSize(std::vector<AbstractAssembly::SubID> const& _subPath)
{
if (auto it = m_dataHashBySubId.find(_subPath[0]); it != m_dataHashBySubId.end())
{

View File

@ -28,7 +28,6 @@
#include <range/v3/view/iota.hpp>
using namespace std;
using namespace solidity;
using namespace solidity::yul;
using namespace solidity::util;
@ -60,12 +59,12 @@ NoOutputAssembly::LabelID NoOutputAssembly::newLabelId()
return 1;
}
AbstractAssembly::LabelID NoOutputAssembly::namedLabel(string const&, size_t, size_t, optional<size_t>)
AbstractAssembly::LabelID NoOutputAssembly::namedLabel(std::string const&, size_t, size_t, std::optional<size_t>)
{
return 1;
}
void NoOutputAssembly::appendLinkerSymbol(string const&)
void NoOutputAssembly::appendLinkerSymbol(std::string const&)
{
yulAssert(false, "Linker symbols not yet implemented.");
}
@ -98,7 +97,7 @@ void NoOutputAssembly::appendAssemblySize()
appendInstruction(evmasm::Instruction::PUSH1);
}
pair<shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> NoOutputAssembly::createSubAssembly(bool, std::string)
std::pair<std::shared_ptr<AbstractAssembly>, AbstractAssembly::SubID> NoOutputAssembly::createSubAssembly(bool, std::string)
{
yulAssert(false, "Sub assemblies not implemented.");
return {};

View File

@ -38,9 +38,8 @@
using namespace solidity;
using namespace solidity::yul;
using namespace std;
vector<StackTooDeepError> OptimizedEVMCodeTransform::run(
std::vector<StackTooDeepError> OptimizedEVMCodeTransform::run(
AbstractAssembly& _assembly,
AsmAnalysisInfo& _analysisInfo,
Block const& _block,
@ -81,7 +80,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call)
// Assert that we got the correct return label on stack.
if (_call.canContinue)
{
auto const* returnLabelSlot = get_if<FunctionCallReturnLabelSlot>(
auto const* returnLabelSlot = std::get_if<FunctionCallReturnLabelSlot>(
&m_stack.at(m_stack.size() - _call.functionCall.get().arguments.size() - 1)
);
yulAssert(returnLabelSlot && &returnLabelSlot->call.get() == &_call.functionCall.get(), "");
@ -160,7 +159,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::Assignment const& _assignment)
// Invalidate occurrences of the assigned variables.
for (auto& currentSlot: m_stack)
if (VariableSlot const* varSlot = get_if<VariableSlot>(&currentSlot))
if (VariableSlot const* varSlot = std::get_if<VariableSlot>(&currentSlot))
if (util::contains(_assignment.variables, *varSlot))
currentSlot = JunkSlot{};
@ -185,8 +184,8 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform(
m_dfg(_dfg),
m_stackLayout(_stackLayout),
m_functionLabels([&](){
map<CFG::FunctionInfo const*, AbstractAssembly::LabelID> functionLabels;
set<YulString> assignedFunctionNames;
std::map<CFG::FunctionInfo const*, AbstractAssembly::LabelID> functionLabels;
std::set<YulString> assignedFunctionNames;
for (Scope::Function const* function: m_dfg.functions)
{
CFG::FunctionInfo const& functionInfo = m_dfg.functionInfo.at(function);
@ -199,7 +198,7 @@ OptimizedEVMCodeTransform::OptimizedEVMCodeTransform(
function->name.str(),
function->arguments.size(),
function->returns.size(),
functionInfo.debugData ? functionInfo.debugData->astID : nullopt
functionInfo.debugData ? functionInfo.debugData->astID : std::nullopt
) :
m_assembly.newLabelId();
}
@ -212,7 +211,7 @@ void OptimizedEVMCodeTransform::assertLayoutCompatibility(Stack const& _currentS
{
yulAssert(_currentStack.size() == _desiredStack.size(), "");
for (auto&& [currentSlot, desiredSlot]: ranges::zip_view(_currentStack, _desiredStack))
yulAssert(holds_alternative<JunkSlot>(desiredSlot) || currentSlot == desiredSlot, "");
yulAssert(std::holds_alternative<JunkSlot>(desiredSlot) || currentSlot == desiredSlot, "");
}
AbstractAssembly::LabelID OptimizedEVMCodeTransform::getFunctionLabel(Scope::Function const& _function)
@ -224,15 +223,15 @@ void OptimizedEVMCodeTransform::validateSlot(StackSlot const& _slot, Expression
{
std::visit(util::GenericVisitor{
[&](yul::Literal const& _literal) {
auto* literalSlot = get_if<LiteralSlot>(&_slot);
auto* literalSlot = std::get_if<LiteralSlot>(&_slot);
yulAssert(literalSlot && valueOfLiteral(_literal) == literalSlot->value, "");
},
[&](yul::Identifier const& _identifier) {
auto* variableSlot = get_if<VariableSlot>(&_slot);
auto* variableSlot = std::get_if<VariableSlot>(&_slot);
yulAssert(variableSlot && variableSlot->variable.get().name == _identifier.name, "");
},
[&](yul::FunctionCall const& _call) {
auto* temporarySlot = get_if<TemporarySlot>(&_slot);
auto* temporarySlot = std::get_if<TemporarySlot>(&_slot);
yulAssert(temporarySlot && &temporarySlot->call.get() == &_call && temporarySlot->index == 0, "");
}
}, _expression);
@ -267,10 +266,10 @@ void OptimizedEVMCodeTransform::createStackLayout(std::shared_ptr<DebugData cons
StackSlot const& deepSlot = m_stack.at(m_stack.size() - _i - 1);
YulString varNameDeep = slotVariableName(deepSlot);
YulString varNameTop = slotVariableName(m_stack.back());
string msg =
std::string msg =
"Cannot swap " + (varNameDeep.empty() ? "Slot " + stackSlotToString(deepSlot) : "Variable " + varNameDeep.str()) +
" with " + (varNameTop.empty() ? "Slot " + stackSlotToString(m_stack.back()) : "Variable " + varNameTop.str()) +
": too deep in the stack by " + to_string(deficit) + " slots in " + stackToString(m_stack);
": too deep in the stack by " + std::to_string(deficit) + " slots in " + stackToString(m_stack);
m_stackErrors.emplace_back(StackTooDeepError(
m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulString{},
varNameDeep.empty() ? varNameTop : varNameDeep,
@ -297,9 +296,9 @@ void OptimizedEVMCodeTransform::createStackLayout(std::shared_ptr<DebugData cons
{
int deficit = static_cast<int>(*depth - 15);
YulString varName = slotVariableName(_slot);
string msg =
std::string msg =
(varName.empty() ? "Slot " + stackSlotToString(_slot) : "Variable " + varName.str())
+ " is " + to_string(*depth - 15) + " too deep in the stack " + stackToString(m_stack);
+ " is " + std::to_string(*depth - 15) + " too deep in the stack " + stackToString(m_stack);
m_stackErrors.emplace_back(StackTooDeepError(
m_currentFunctionInfo ? m_currentFunctionInfo->function.name : YulString{},
varName,
@ -503,9 +502,9 @@ void OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block)
[&](CFG::BasicBlock::Terminated const&)
{
yulAssert(!_block.operations.empty());
if (CFG::BuiltinCall const* builtinCall = get_if<CFG::BuiltinCall>(&_block.operations.back().operation))
if (CFG::BuiltinCall const* builtinCall = std::get_if<CFG::BuiltinCall>(&_block.operations.back().operation))
yulAssert(builtinCall->builtin.get().controlFlowSideEffects.terminatesOrReverts(), "");
else if (CFG::FunctionCall const* functionCall = get_if<CFG::FunctionCall>(&_block.operations.back().operation))
else if (CFG::FunctionCall const* functionCall = std::get_if<CFG::FunctionCall>(&_block.operations.back().operation))
yulAssert(!functionCall->canContinue);
else
yulAssert(false);

View File

@ -46,7 +46,6 @@
using namespace solidity;
using namespace solidity::yul;
using namespace std;
StackLayout StackLayoutGenerator::run(CFG const& _cfg)
{
@ -59,9 +58,9 @@ StackLayout StackLayoutGenerator::run(CFG const& _cfg)
return stackLayout;
}
map<YulString, vector<StackLayoutGenerator::StackTooDeep>> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg)
std::map<YulString, std::vector<StackLayoutGenerator::StackTooDeep>> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg)
{
map<YulString, vector<StackLayoutGenerator::StackTooDeep>> stackTooDeepErrors;
std::map<YulString, std::vector<StackLayoutGenerator::StackTooDeep>> stackTooDeepErrors;
stackTooDeepErrors[YulString{}] = reportStackTooDeep(_cfg, YulString{});
for (auto const& function: _cfg.functions)
if (auto errors = reportStackTooDeep(_cfg, function->name); !errors.empty())
@ -69,7 +68,7 @@ map<YulString, vector<StackLayoutGenerator::StackTooDeep>> StackLayoutGenerator:
return stackTooDeepErrors;
}
vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, YulString _functionName)
std::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG const& _cfg, YulString _functionName)
{
StackLayout stackLayout;
CFG::FunctionInfo const* functionInfo = nullptr;
@ -98,14 +97,14 @@ StackLayoutGenerator::StackLayoutGenerator(StackLayout& _layout, CFG::FunctionIn
namespace
{
/// @returns all stack too deep errors that would occur when shuffling @a _source to @a _target.
vector<StackLayoutGenerator::StackTooDeep> findStackTooDeep(Stack const& _source, Stack const& _target)
std::vector<StackLayoutGenerator::StackTooDeep> findStackTooDeep(Stack const& _source, Stack const& _target)
{
Stack currentStack = _source;
vector<StackLayoutGenerator::StackTooDeep> stackTooDeepErrors;
std::vector<StackLayoutGenerator::StackTooDeep> stackTooDeepErrors;
auto getVariableChoices = [](auto&& _range) {
vector<YulString> result;
std::vector<YulString> result;
for (auto const& slot: _range)
if (auto const* variableSlot = get_if<VariableSlot>(&slot))
if (auto const* variableSlot = std::get_if<VariableSlot>(&slot))
if (!util::contains(result, variableSlot->variable.get().name))
result.push_back(variableSlot->variable.get().name);
return result;
@ -160,7 +159,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla
// PreviousSlot{0}, ..., PreviousSlot{n}, [output<0>], ..., [output<m>]
auto layout = ranges::views::iota(0u, preOperationLayoutSize) |
ranges::views::transform([](size_t _index) { return PreviousSlot{_index}; }) |
ranges::to<vector<variant<PreviousSlot, StackSlot>>>;
ranges::to<std::vector<std::variant<PreviousSlot, StackSlot>>>;
layout += _operationOutput;
// Shortcut for trivial case.
@ -171,23 +170,23 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla
// that are aware of PreviousSlot's.
struct ShuffleOperations
{
vector<variant<PreviousSlot, StackSlot>>& layout;
std::vector<std::variant<PreviousSlot, StackSlot>>& layout;
Stack const& post;
std::set<StackSlot> outputs;
Multiplicity multiplicity;
Callable generateSlotOnTheFly;
ShuffleOperations(
vector<variant<PreviousSlot, StackSlot>>& _layout,
std::vector<std::variant<PreviousSlot, StackSlot>>& _layout,
Stack const& _post,
Callable _generateSlotOnTheFly
): layout(_layout), post(_post), generateSlotOnTheFly(_generateSlotOnTheFly)
{
for (auto const& layoutSlot: layout)
if (StackSlot const* slot = get_if<StackSlot>(&layoutSlot))
if (StackSlot const* slot = std::get_if<StackSlot>(&layoutSlot))
outputs.insert(*slot);
for (auto const& layoutSlot: layout)
if (StackSlot const* slot = get_if<StackSlot>(&layoutSlot))
if (StackSlot const* slot = std::get_if<StackSlot>(&layoutSlot))
--multiplicity[*slot];
for (auto&& slot: post)
if (outputs.count(slot) || generateSlotOnTheFly(slot))
@ -235,7 +234,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla
}
void swap(size_t _i)
{
yulAssert(!holds_alternative<PreviousSlot>(layout.at(layout.size() - _i - 1)) || !holds_alternative<PreviousSlot>(layout.back()), "");
yulAssert(!std::holds_alternative<PreviousSlot>(layout.at(layout.size() - _i - 1)) || !std::holds_alternative<PreviousSlot>(layout.back()), "");
std::swap(layout.at(layout.size() - _i - 1), layout.back());
}
size_t sourceSize() { return layout.size(); }
@ -250,7 +249,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla
// output in place. The resulting permutation of the PreviousSlot yields the ideal positions of slots
// before the operation, i.e. if PreviousSlot{2} is at a position at which _post contains VariableSlot{"tmp"},
// then we want the variable tmp in the slot at offset 2 in the layout before the operation.
vector<optional<StackSlot>> idealLayout(_post.size(), nullopt);
std::vector<std::optional<StackSlot>> idealLayout(_post.size(), std::nullopt);
for (auto&& [slot, idealPosition]: ranges::zip_view(_post, layout))
if (PreviousSlot* previousSlot = std::get_if<PreviousSlot>(&idealPosition))
idealLayout.at(previousSlot->slot) = slot;
@ -261,7 +260,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla
yulAssert(idealLayout.size() == preOperationLayoutSize, "");
return idealLayout | ranges::views::transform([](optional<StackSlot> s) {
return idealLayout | ranges::views::transform([](std::optional<StackSlot> s) {
yulAssert(s, "");
return *s;
}) | ranges::to<Stack>;
@ -271,7 +270,7 @@ Stack createIdealLayout(Stack const& _operationOutput, Stack const& _post, Calla
Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG::Operation const& _operation, bool _aggressiveStackCompression)
{
// Enable aggressive stack compression for recursive calls.
if (auto const* functionCall = get_if<CFG::FunctionCall>(&_operation.operation))
if (auto const* functionCall = std::get_if<CFG::FunctionCall>(&_operation.operation))
if (functionCall->recursive)
_aggressiveStackCompression = true;
@ -285,9 +284,9 @@ Stack StackLayoutGenerator::propagateStackThroughOperation(Stack _exitStack, CFG
Stack stack = createIdealLayout(_operation.output, _exitStack, generateSlotOnTheFly);
// Make sure the resulting previous slots do not overlap with any assignmed variables.
if (auto const* assignment = get_if<CFG::Assignment>(&_operation.operation))
if (auto const* assignment = std::get_if<CFG::Assignment>(&_operation.operation))
for (auto& stackSlot: stack)
if (auto const* varSlot = get_if<VariableSlot>(&stackSlot))
if (auto const* varSlot = std::get_if<VariableSlot>(&stackSlot))
yulAssert(!util::contains(assignment->variables, *varSlot), "");
// Since stack+_operation.output can be easily shuffled to _exitLayout, the desired layout before the operation
@ -335,11 +334,11 @@ Stack StackLayoutGenerator::propagateStackThroughBlock(Stack _exitStack, CFG::Ba
void StackLayoutGenerator::processEntryPoint(CFG::BasicBlock const& _entry, CFG::FunctionInfo const* _functionInfo)
{
list<CFG::BasicBlock const*> toVisit{&_entry};
set<CFG::BasicBlock const*> visited;
std::list<CFG::BasicBlock const*> toVisit{&_entry};
std::set<CFG::BasicBlock const*> visited;
// TODO: check whether visiting only a subset of these in the outer iteration below is enough.
list<pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps = collectBackwardsJumps(_entry);
std::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps = collectBackwardsJumps(_entry);
while (!toVisit.empty())
{
@ -407,10 +406,10 @@ void StackLayoutGenerator::processEntryPoint(CFG::BasicBlock const& _entry, CFG:
fillInJunk(_entry, _functionInfo);
}
optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies(
std::optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies(
CFG::BasicBlock const& _block,
set<CFG::BasicBlock const*> const& _visited,
list<CFG::BasicBlock const*>& _toVisit
std::set<CFG::BasicBlock const*> const& _visited,
std::list<CFG::BasicBlock const*>& _toVisit
) const
{
return std::visit(util::GenericVisitor{
@ -434,7 +433,7 @@ optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies(
return m_layout.blockInfos.at(_jump.target).entryLayout;
// Otherwise stage the jump target for visit and defer the current block.
_toVisit.emplace_front(_jump.target);
return nullopt;
return std::nullopt;
},
[&](CFG::BasicBlock::ConditionalJump const& _conditionalJump) -> std::optional<Stack>
{
@ -456,7 +455,7 @@ optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies(
_toVisit.emplace_front(_conditionalJump.zero);
if (!nonZeroVisited)
_toVisit.emplace_front(_conditionalJump.nonZero);
return nullopt;
return std::nullopt;
},
[&](CFG::BasicBlock::FunctionReturn const& _functionReturn) -> std::optional<Stack>
{
@ -476,9 +475,9 @@ optional<Stack> StackLayoutGenerator::getExitLayoutOrStageDependencies(
}, _block.exit);
}
list<pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> StackLayoutGenerator::collectBackwardsJumps(CFG::BasicBlock const& _entry) const
std::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> StackLayoutGenerator::collectBackwardsJumps(CFG::BasicBlock const& _entry) const
{
list<pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps;
std::list<std::pair<CFG::BasicBlock const*, CFG::BasicBlock const*>> backwardsJumps;
util::BreadthFirstSearch<CFG::BasicBlock const*>{{&_entry}}.run([&](CFG::BasicBlock const* _block, auto _addChild) {
std::visit(util::GenericVisitor{
[&](CFG::BasicBlock::MainExit const&) {},
@ -576,7 +575,7 @@ Stack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _sta
if (!util::contains(candidate, slot))
candidate.emplace_back(slot);
cxx20::erase_if(candidate, [](StackSlot const& slot) {
return holds_alternative<LiteralSlot>(slot) || holds_alternative<FunctionCallReturnLabelSlot>(slot);
return std::holds_alternative<LiteralSlot>(slot) || std::holds_alternative<FunctionCallReturnLabelSlot>(slot);
});
auto evaluate = [&](Stack const& _candidate) -> size_t {
@ -633,9 +632,9 @@ Stack StackLayoutGenerator::combineStack(Stack const& _stack1, Stack const& _sta
return commonPrefix + bestCandidate;
}
vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG::BasicBlock const& _entry) const
std::vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooDeep(CFG::BasicBlock const& _entry) const
{
vector<StackTooDeep> stackTooDeepErrors;
std::vector<StackTooDeep> stackTooDeepErrors;
util::BreadthFirstSearch<CFG::BasicBlock const*> breadthFirstSearch{{&_entry}};
breadthFirstSearch.run([&](CFG::BasicBlock const* _block, auto _addChild) {
Stack currentStack = m_layout.blockInfos.at(_block).entryLayout;
@ -683,7 +682,7 @@ vector<StackLayoutGenerator::StackTooDeep> StackLayoutGenerator::reportStackTooD
Stack StackLayoutGenerator::compressStack(Stack _stack)
{
optional<size_t> firstDupOffset;
std::optional<size_t> firstDupOffset;
do
{
if (firstDupOffset)
@ -768,8 +767,8 @@ void StackLayoutGenerator::fillInJunk(CFG::BasicBlock const& _block, CFG::Functi
{
// This has to be a previously unassigned return variable.
// We at least sanity-check that it is among the return variables at all.
yulAssert(m_currentFunctionInfo && holds_alternative<VariableSlot>(_slot));
yulAssert(util::contains(m_currentFunctionInfo->returnVariables, get<VariableSlot>(_slot)));
yulAssert(m_currentFunctionInfo && std::holds_alternative<VariableSlot>(_slot));
yulAssert(util::contains(m_currentFunctionInfo->returnVariables, std::get<VariableSlot>(_slot)));
// Strictly speaking the cost of the PUSH0 depends on the targeted EVM version, but the difference
// will not matter here.
opGas += evmasm::GasMeter::runGas(evmasm::pushInstruction(0), langutil::EVMVersion());;

View File

@ -34,6 +34,7 @@ NAMESPACE_STD_FREE_FILES=(
libsolidity/lsp/*
libsolidity/parsing/*
libsolutil/*
libyul/backends/evm/*
solc/*
)