mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge pull request #14522 from junaire/purge-using-namespace-std-in-libyul
Purge using namespace std in libyul
This commit is contained in:
commit
df03f1412d
@ -44,7 +44,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std::string_literals;
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
@ -52,7 +52,7 @@ using namespace solidity::langutil;
|
|||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
inline string to_string(LiteralKind _kind)
|
inline std::string to_string(LiteralKind _kind)
|
||||||
{
|
{
|
||||||
switch (_kind)
|
switch (_kind)
|
||||||
{
|
{
|
||||||
@ -98,14 +98,14 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect,
|
|||||||
return analysisInfo;
|
return analysisInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<YulString> AsmAnalyzer::operator()(Literal const& _literal)
|
std::vector<YulString> AsmAnalyzer::operator()(Literal const& _literal)
|
||||||
{
|
{
|
||||||
expectValidType(_literal.type, nativeLocationOf(_literal));
|
expectValidType(_literal.type, nativeLocationOf(_literal));
|
||||||
if (_literal.kind == LiteralKind::String && _literal.value.str().size() > 32)
|
if (_literal.kind == LiteralKind::String && _literal.value.str().size() > 32)
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
3069_error,
|
3069_error,
|
||||||
nativeLocationOf(_literal),
|
nativeLocationOf(_literal),
|
||||||
"String literal too long (" + to_string(_literal.value.str().size()) + " > 32)"
|
"String literal too long (" + std::to_string(_literal.value.str().size()) + " > 32)"
|
||||||
);
|
);
|
||||||
else if (_literal.kind == LiteralKind::Number && bigint(_literal.value.str()) > u256(-1))
|
else if (_literal.kind == LiteralKind::Number && bigint(_literal.value.str()) > u256(-1))
|
||||||
m_errorReporter.typeError(6708_error, nativeLocationOf(_literal), "Number literal too large (> 256 bits)");
|
m_errorReporter.typeError(6708_error, nativeLocationOf(_literal), "Number literal too large (> 256 bits)");
|
||||||
@ -122,7 +122,7 @@ vector<YulString> AsmAnalyzer::operator()(Literal const& _literal)
|
|||||||
return {_literal.type};
|
return {_literal.type};
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<YulString> AsmAnalyzer::operator()(Identifier const& _identifier)
|
std::vector<YulString> AsmAnalyzer::operator()(Identifier const& _identifier)
|
||||||
{
|
{
|
||||||
yulAssert(!_identifier.name.empty(), "");
|
yulAssert(!_identifier.name.empty(), "");
|
||||||
auto watcher = m_errorReporter.errorWatcher();
|
auto watcher = m_errorReporter.errorWatcher();
|
||||||
@ -180,13 +180,13 @@ vector<YulString> AsmAnalyzer::operator()(Identifier const& _identifier)
|
|||||||
void AsmAnalyzer::operator()(ExpressionStatement const& _statement)
|
void AsmAnalyzer::operator()(ExpressionStatement const& _statement)
|
||||||
{
|
{
|
||||||
auto watcher = m_errorReporter.errorWatcher();
|
auto watcher = m_errorReporter.errorWatcher();
|
||||||
vector<YulString> types = std::visit(*this, _statement.expression);
|
std::vector<YulString> types = std::visit(*this, _statement.expression);
|
||||||
if (watcher.ok() && !types.empty())
|
if (watcher.ok() && !types.empty())
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
3083_error,
|
3083_error,
|
||||||
nativeLocationOf(_statement),
|
nativeLocationOf(_statement),
|
||||||
"Top-level expressions are not supposed to return values (this expression returns " +
|
"Top-level expressions are not supposed to return values (this expression returns " +
|
||||||
to_string(types.size()) +
|
std::to_string(types.size()) +
|
||||||
" value" +
|
" value" +
|
||||||
(types.size() == 1 ? "" : "s") +
|
(types.size() == 1 ? "" : "s") +
|
||||||
"). Use ``pop()`` or assign them."
|
"). Use ``pop()`` or assign them."
|
||||||
@ -199,7 +199,7 @@ void AsmAnalyzer::operator()(Assignment const& _assignment)
|
|||||||
size_t const numVariables = _assignment.variableNames.size();
|
size_t const numVariables = _assignment.variableNames.size();
|
||||||
yulAssert(numVariables >= 1, "");
|
yulAssert(numVariables >= 1, "");
|
||||||
|
|
||||||
set<YulString> variables;
|
std::set<YulString> variables;
|
||||||
for (auto const& _variableName: _assignment.variableNames)
|
for (auto const& _variableName: _assignment.variableNames)
|
||||||
if (!variables.insert(_variableName.name).second)
|
if (!variables.insert(_variableName.name).second)
|
||||||
m_errorReporter.declarationError(
|
m_errorReporter.declarationError(
|
||||||
@ -210,7 +210,7 @@ void AsmAnalyzer::operator()(Assignment const& _assignment)
|
|||||||
" occurs multiple times on the left-hand side of the assignment."
|
" occurs multiple times on the left-hand side of the assignment."
|
||||||
);
|
);
|
||||||
|
|
||||||
vector<YulString> types = std::visit(*this, *_assignment.value);
|
std::vector<YulString> types = std::visit(*this, *_assignment.value);
|
||||||
|
|
||||||
if (types.size() != numVariables)
|
if (types.size() != numVariables)
|
||||||
m_errorReporter.declarationError(
|
m_errorReporter.declarationError(
|
||||||
@ -219,9 +219,9 @@ void AsmAnalyzer::operator()(Assignment const& _assignment)
|
|||||||
"Variable count for assignment to \"" +
|
"Variable count for assignment to \"" +
|
||||||
joinHumanReadable(applyMap(_assignment.variableNames, [](auto const& _identifier){ return _identifier.name.str(); })) +
|
joinHumanReadable(applyMap(_assignment.variableNames, [](auto const& _identifier){ return _identifier.name.str(); })) +
|
||||||
"\" does not match number of values (" +
|
"\" does not match number of values (" +
|
||||||
to_string(numVariables) +
|
std::to_string(numVariables) +
|
||||||
" vs. " +
|
" vs. " +
|
||||||
to_string(types.size()) +
|
std::to_string(types.size()) +
|
||||||
")"
|
")"
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -249,7 +249,7 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
|
|||||||
|
|
||||||
if (_varDecl.value)
|
if (_varDecl.value)
|
||||||
{
|
{
|
||||||
vector<YulString> types = std::visit(*this, *_varDecl.value);
|
std::vector<YulString> types = std::visit(*this, *_varDecl.value);
|
||||||
if (types.size() != numVariables)
|
if (types.size() != numVariables)
|
||||||
m_errorReporter.declarationError(
|
m_errorReporter.declarationError(
|
||||||
3812_error,
|
3812_error,
|
||||||
@ -257,9 +257,9 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
|
|||||||
"Variable count mismatch for declaration of \"" +
|
"Variable count mismatch for declaration of \"" +
|
||||||
joinHumanReadable(applyMap(_varDecl.variables, [](auto const& _identifier){ return _identifier.name.str(); })) +
|
joinHumanReadable(applyMap(_varDecl.variables, [](auto const& _identifier){ return _identifier.name.str(); })) +
|
||||||
+ "\": " +
|
+ "\": " +
|
||||||
to_string(numVariables) +
|
std::to_string(numVariables) +
|
||||||
" variables and " +
|
" variables and " +
|
||||||
to_string(types.size()) +
|
std::to_string(types.size()) +
|
||||||
" values."
|
" values."
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -301,13 +301,13 @@ void AsmAnalyzer::operator()(FunctionDefinition const& _funDef)
|
|||||||
(*this)(_funDef.body);
|
(*this)(_funDef.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
std::vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
||||||
{
|
{
|
||||||
yulAssert(!_funCall.functionName.name.empty(), "");
|
yulAssert(!_funCall.functionName.name.empty(), "");
|
||||||
auto watcher = m_errorReporter.errorWatcher();
|
auto watcher = m_errorReporter.errorWatcher();
|
||||||
vector<YulString> const* parameterTypes = nullptr;
|
std::vector<YulString> const* parameterTypes = nullptr;
|
||||||
vector<YulString> const* returnTypes = nullptr;
|
std::vector<YulString> const* returnTypes = nullptr;
|
||||||
vector<optional<LiteralKind>> const* literalArguments = nullptr;
|
std::vector<std::optional<LiteralKind>> const* literalArguments = nullptr;
|
||||||
|
|
||||||
if (BuiltinFunction const* f = m_dialect.builtin(_funCall.functionName.name))
|
if (BuiltinFunction const* f = m_dialect.builtin(_funCall.functionName.name))
|
||||||
{
|
{
|
||||||
@ -367,12 +367,12 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
|||||||
7000_error,
|
7000_error,
|
||||||
nativeLocationOf(_funCall.functionName),
|
nativeLocationOf(_funCall.functionName),
|
||||||
"Function \"" + _funCall.functionName.name.str() + "\" expects " +
|
"Function \"" + _funCall.functionName.name.str() + "\" expects " +
|
||||||
to_string(parameterTypes->size()) +
|
std::to_string(parameterTypes->size()) +
|
||||||
" arguments but got " +
|
" arguments but got " +
|
||||||
to_string(_funCall.arguments.size()) + "."
|
std::to_string(_funCall.arguments.size()) + "."
|
||||||
);
|
);
|
||||||
|
|
||||||
vector<YulString> argTypes;
|
std::vector<YulString> argTypes;
|
||||||
for (size_t i = _funCall.arguments.size(); i > 0; i--)
|
for (size_t i = _funCall.arguments.size(); i > 0; i--)
|
||||||
{
|
{
|
||||||
Expression const& arg = _funCall.arguments[i - 1];
|
Expression const& arg = _funCall.arguments[i - 1];
|
||||||
@ -382,13 +382,13 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
|||||||
std::nullopt
|
std::nullopt
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (!holds_alternative<Literal>(arg))
|
if (!std::holds_alternative<Literal>(arg))
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
9114_error,
|
9114_error,
|
||||||
nativeLocationOf(_funCall.functionName),
|
nativeLocationOf(_funCall.functionName),
|
||||||
"Function expects direct literals as arguments."
|
"Function expects direct literals as arguments."
|
||||||
);
|
);
|
||||||
else if (*literalArgumentKind != get<Literal>(arg).kind)
|
else if (*literalArgumentKind != std::get<Literal>(arg).kind)
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
5859_error,
|
5859_error,
|
||||||
nativeLocationOf(arg),
|
nativeLocationOf(arg),
|
||||||
@ -396,10 +396,10 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
|||||||
);
|
);
|
||||||
else if (*literalArgumentKind == LiteralKind::String)
|
else if (*literalArgumentKind == LiteralKind::String)
|
||||||
{
|
{
|
||||||
string functionName = _funCall.functionName.name.str();
|
std::string functionName = _funCall.functionName.name.str();
|
||||||
if (functionName == "datasize" || functionName == "dataoffset")
|
if (functionName == "datasize" || functionName == "dataoffset")
|
||||||
{
|
{
|
||||||
if (!m_dataNames.count(get<Literal>(arg).value))
|
if (!m_dataNames.count(std::get<Literal>(arg).value))
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
3517_error,
|
3517_error,
|
||||||
nativeLocationOf(arg),
|
nativeLocationOf(arg),
|
||||||
@ -408,7 +408,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
|||||||
}
|
}
|
||||||
else if (functionName.substr(0, "verbatim_"s.size()) == "verbatim_")
|
else if (functionName.substr(0, "verbatim_"s.size()) == "verbatim_")
|
||||||
{
|
{
|
||||||
if (get<Literal>(arg).value.empty())
|
if (std::get<Literal>(arg).value.empty())
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
1844_error,
|
1844_error,
|
||||||
nativeLocationOf(arg),
|
nativeLocationOf(arg),
|
||||||
@ -416,7 +416,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
argTypes.emplace_back(expectUnlimitedStringLiteral(get<Literal>(arg)));
|
argTypes.emplace_back(expectUnlimitedStringLiteral(std::get<Literal>(arg)));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -435,7 +435,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
|
|||||||
return *returnTypes;
|
return *returnTypes;
|
||||||
}
|
}
|
||||||
else if (returnTypes)
|
else if (returnTypes)
|
||||||
return vector<YulString>(returnTypes->size(), m_dialect.defaultType);
|
return std::vector<YulString>(returnTypes->size(), m_dialect.defaultType);
|
||||||
else
|
else
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@ -460,7 +460,7 @@ void AsmAnalyzer::operator()(Switch const& _switch)
|
|||||||
|
|
||||||
YulString valueType = expectExpression(*_switch.expression);
|
YulString valueType = expectExpression(*_switch.expression);
|
||||||
|
|
||||||
set<u256> cases;
|
std::set<u256> cases;
|
||||||
for (auto const& _case: _switch.cases)
|
for (auto const& _case: _switch.cases)
|
||||||
{
|
{
|
||||||
if (_case.value)
|
if (_case.value)
|
||||||
@ -525,13 +525,13 @@ void AsmAnalyzer::operator()(Block const& _block)
|
|||||||
|
|
||||||
YulString AsmAnalyzer::expectExpression(Expression const& _expr)
|
YulString AsmAnalyzer::expectExpression(Expression const& _expr)
|
||||||
{
|
{
|
||||||
vector<YulString> types = std::visit(*this, _expr);
|
std::vector<YulString> types = std::visit(*this, _expr);
|
||||||
if (types.size() != 1)
|
if (types.size() != 1)
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
3950_error,
|
3950_error,
|
||||||
nativeLocationOf(_expr),
|
nativeLocationOf(_expr),
|
||||||
"Expected expression to evaluate to one value, but got " +
|
"Expected expression to evaluate to one value, but got " +
|
||||||
to_string(types.size()) +
|
std::to_string(types.size()) +
|
||||||
" values instead."
|
" values instead."
|
||||||
);
|
);
|
||||||
return types.empty() ? m_dialect.defaultType : types.front();
|
return types.empty() ? m_dialect.defaultType : types.front();
|
||||||
@ -576,7 +576,7 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulString _valueT
|
|||||||
m_currentScope->insideFunction()
|
m_currentScope->insideFunction()
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!holds_alternative<Scope::Variable>(*var))
|
if (!std::holds_alternative<Scope::Variable>(*var))
|
||||||
m_errorReporter.typeError(2657_error, nativeLocationOf(_variable), "Assignment requires variable.");
|
m_errorReporter.typeError(2657_error, nativeLocationOf(_variable), "Assignment requires variable.");
|
||||||
else if (!m_activeVariables.count(&std::get<Scope::Variable>(*var)))
|
else if (!m_activeVariables.count(&std::get<Scope::Variable>(*var)))
|
||||||
m_errorReporter.declarationError(
|
m_errorReporter.declarationError(
|
||||||
@ -692,7 +692,7 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio
|
|||||||
_instr != evmasm::Instruction::JUMPDEST,
|
_instr != evmasm::Instruction::JUMPDEST,
|
||||||
"");
|
"");
|
||||||
|
|
||||||
auto errorForVM = [&](ErrorId _errorId, string const& vmKindMessage) {
|
auto errorForVM = [&](ErrorId _errorId, std::string const& vmKindMessage) {
|
||||||
m_errorReporter.typeError(
|
m_errorReporter.typeError(
|
||||||
_errorId,
|
_errorId,
|
||||||
_location,
|
_location,
|
||||||
|
@ -26,8 +26,6 @@
|
|||||||
#include <libsolutil/CommonData.h>
|
#include <libsolutil/CommonData.h>
|
||||||
#include <libsolutil/UTF8.h>
|
#include <libsolutil/UTF8.h>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
|
|
||||||
namespace solidity::yul
|
namespace solidity::yul
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -183,14 +181,14 @@ Json::Value AsmJsonConverter::operator()(Leave const& _node) const
|
|||||||
return createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulLeave");
|
return createAstNode(originLocationOf(_node), nativeLocationOf(_node), "YulLeave");
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value AsmJsonConverter::createAstNode(langutil::SourceLocation const& _originLocation, langutil::SourceLocation const& _nativeLocation, string _nodeType) const
|
Json::Value AsmJsonConverter::createAstNode(langutil::SourceLocation const& _originLocation, langutil::SourceLocation const& _nativeLocation, std::string _nodeType) const
|
||||||
{
|
{
|
||||||
Json::Value ret{Json::objectValue};
|
Json::Value ret{Json::objectValue};
|
||||||
ret["nodeType"] = std::move(_nodeType);
|
ret["nodeType"] = std::move(_nodeType);
|
||||||
auto srcLocation = [&](int start, int end) -> string
|
auto srcLocation = [&](int start, int end) -> std::string
|
||||||
{
|
{
|
||||||
int length = (start >= 0 && end >= 0 && end >= start) ? end - start : -1;
|
int length = (start >= 0 && end >= 0 && end >= start) ? end - start : -1;
|
||||||
return to_string(start) + ":" + to_string(length) + ":" + (m_sourceIndex.has_value() ? to_string(m_sourceIndex.value()) : "-1");
|
return std::to_string(start) + ":" + std::to_string(length) + ":" + (m_sourceIndex.has_value() ? std::to_string(m_sourceIndex.value()) : "-1");
|
||||||
};
|
};
|
||||||
ret["src"] = srcLocation(_originLocation.start, _originLocation.end);
|
ret["src"] = srcLocation(_originLocation.start, _originLocation.end);
|
||||||
ret["nativeSrc"] = srcLocation(_nativeLocation.start, _nativeLocation.end);
|
ret["nativeSrc"] = srcLocation(_nativeLocation.start, _nativeLocation.end);
|
||||||
@ -198,7 +196,7 @@ Json::Value AsmJsonConverter::createAstNode(langutil::SourceLocation const& _ori
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
Json::Value AsmJsonConverter::vectorOfVariantsToJson(vector<T> const& _vec) const
|
Json::Value AsmJsonConverter::vectorOfVariantsToJson(std::vector<T> const& _vec) const
|
||||||
{
|
{
|
||||||
Json::Value ret{Json::arrayValue};
|
Json::Value ret{Json::arrayValue};
|
||||||
for (auto const& var: _vec)
|
for (auto const& var: _vec)
|
||||||
|
@ -34,7 +34,6 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity::langutil;
|
using namespace solidity::langutil;
|
||||||
|
|
||||||
namespace solidity::yul
|
namespace solidity::yul
|
||||||
@ -62,7 +61,7 @@ T AsmJsonImporter::createAsmNode(Json::Value const& _node)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
Json::Value AsmJsonImporter::member(Json::Value const& _node, string const& _name)
|
Json::Value AsmJsonImporter::member(Json::Value const& _node, std::string const& _name)
|
||||||
{
|
{
|
||||||
if (!_node.isMember(_name))
|
if (!_node.isMember(_name))
|
||||||
return Json::nullValue;
|
return Json::nullValue;
|
||||||
@ -81,7 +80,7 @@ Statement AsmJsonImporter::createStatement(Json::Value const& _node)
|
|||||||
{
|
{
|
||||||
Json::Value jsonNodeType = member(_node, "nodeType");
|
Json::Value jsonNodeType = member(_node, "nodeType");
|
||||||
yulAssert(jsonNodeType.isString(), "Expected \"nodeType\" to be of type string!");
|
yulAssert(jsonNodeType.isString(), "Expected \"nodeType\" to be of type string!");
|
||||||
string nodeType = jsonNodeType.asString();
|
std::string nodeType = jsonNodeType.asString();
|
||||||
|
|
||||||
yulAssert(nodeType.substr(0, 3) == "Yul", "Invalid nodeType prefix");
|
yulAssert(nodeType.substr(0, 3) == "Yul", "Invalid nodeType prefix");
|
||||||
nodeType = nodeType.substr(3);
|
nodeType = nodeType.substr(3);
|
||||||
@ -119,7 +118,7 @@ Expression AsmJsonImporter::createExpression(Json::Value const& _node)
|
|||||||
{
|
{
|
||||||
Json::Value jsonNodeType = member(_node, "nodeType");
|
Json::Value jsonNodeType = member(_node, "nodeType");
|
||||||
yulAssert(jsonNodeType.isString(), "Expected \"nodeType\" to be of type string!");
|
yulAssert(jsonNodeType.isString(), "Expected \"nodeType\" to be of type string!");
|
||||||
string nodeType = jsonNodeType.asString();
|
std::string nodeType = jsonNodeType.asString();
|
||||||
|
|
||||||
yulAssert(nodeType.substr(0, 3) == "Yul", "Invalid nodeType prefix");
|
yulAssert(nodeType.substr(0, 3) == "Yul", "Invalid nodeType prefix");
|
||||||
nodeType = nodeType.substr(3);
|
nodeType = nodeType.substr(3);
|
||||||
@ -137,17 +136,17 @@ Expression AsmJsonImporter::createExpression(Json::Value const& _node)
|
|||||||
util::unreachable();
|
util::unreachable();
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Expression> AsmJsonImporter::createExpressionVector(Json::Value const& _array)
|
std::vector<Expression> AsmJsonImporter::createExpressionVector(Json::Value const& _array)
|
||||||
{
|
{
|
||||||
vector<Expression> ret;
|
std::vector<Expression> ret;
|
||||||
for (auto& var: _array)
|
for (auto& var: _array)
|
||||||
ret.emplace_back(createExpression(var));
|
ret.emplace_back(createExpression(var));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Statement> AsmJsonImporter::createStatementVector(Json::Value const& _array)
|
std::vector<Statement> AsmJsonImporter::createStatementVector(Json::Value const& _array)
|
||||||
{
|
{
|
||||||
vector<Statement> ret;
|
std::vector<Statement> ret;
|
||||||
for (auto& var: _array)
|
for (auto& var: _array)
|
||||||
ret.emplace_back(createStatement(var));
|
ret.emplace_back(createStatement(var));
|
||||||
return ret;
|
return ret;
|
||||||
@ -163,7 +162,7 @@ Block AsmJsonImporter::createBlock(Json::Value const& _node)
|
|||||||
Literal AsmJsonImporter::createLiteral(Json::Value const& _node)
|
Literal AsmJsonImporter::createLiteral(Json::Value const& _node)
|
||||||
{
|
{
|
||||||
auto lit = createAsmNode<Literal>(_node);
|
auto lit = createAsmNode<Literal>(_node);
|
||||||
string kind = member(_node, "kind").asString();
|
std::string kind = member(_node, "kind").asString();
|
||||||
|
|
||||||
solAssert(member(_node, "hexValue").isString() || member(_node, "value").isString(), "");
|
solAssert(member(_node, "hexValue").isString() || member(_node, "value").isString(), "");
|
||||||
if (_node.isMember("hexValue"))
|
if (_node.isMember("hexValue"))
|
||||||
@ -180,7 +179,7 @@ Literal AsmJsonImporter::createLiteral(Json::Value const& _node)
|
|||||||
lit.kind = LiteralKind::Number;
|
lit.kind = LiteralKind::Number;
|
||||||
yulAssert(
|
yulAssert(
|
||||||
scanner.currentToken() == Token::Number,
|
scanner.currentToken() == Token::Number,
|
||||||
"Expected number but got " + langutil::TokenTraits::friendlyName(scanner.currentToken()) + string(" while scanning ") + lit.value.str()
|
"Expected number but got " + langutil::TokenTraits::friendlyName(scanner.currentToken()) + std::string(" while scanning ") + lit.value.str()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else if (kind == "bool")
|
else if (kind == "bool")
|
||||||
@ -199,7 +198,7 @@ Literal AsmJsonImporter::createLiteral(Json::Value const& _node)
|
|||||||
lit.kind = LiteralKind::String;
|
lit.kind = LiteralKind::String;
|
||||||
yulAssert(
|
yulAssert(
|
||||||
lit.value.str().size() <= 32,
|
lit.value.str().size() <= 32,
|
||||||
"String literal too long (" + to_string(lit.value.str().size()) + " > 32)"
|
"String literal too long (" + std::to_string(lit.value.str().size()) + " > 32)"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -228,7 +227,7 @@ Assignment AsmJsonImporter::createAssignment(Json::Value const& _node)
|
|||||||
for (auto const& var: member(_node, "variableNames"))
|
for (auto const& var: member(_node, "variableNames"))
|
||||||
assignment.variableNames.emplace_back(createIdentifier(var));
|
assignment.variableNames.emplace_back(createIdentifier(var));
|
||||||
|
|
||||||
assignment.value = make_unique<Expression>(createExpression(member(_node, "value")));
|
assignment.value = std::make_unique<Expression>(createExpression(member(_node, "value")));
|
||||||
return assignment;
|
return assignment;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +255,7 @@ VariableDeclaration AsmJsonImporter::createVariableDeclaration(Json::Value const
|
|||||||
auto varDec = createAsmNode<VariableDeclaration>(_node);
|
auto varDec = createAsmNode<VariableDeclaration>(_node);
|
||||||
for (auto const& var: member(_node, "variables"))
|
for (auto const& var: member(_node, "variables"))
|
||||||
varDec.variables.emplace_back(createTypedName(var));
|
varDec.variables.emplace_back(createTypedName(var));
|
||||||
varDec.value = make_unique<Expression>(createExpression(member(_node, "value")));
|
varDec.value = std::make_unique<Expression>(createExpression(member(_node, "value")));
|
||||||
return varDec;
|
return varDec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +279,7 @@ FunctionDefinition AsmJsonImporter::createFunctionDefinition(Json::Value const&
|
|||||||
If AsmJsonImporter::createIf(Json::Value const& _node)
|
If AsmJsonImporter::createIf(Json::Value const& _node)
|
||||||
{
|
{
|
||||||
auto ifStatement = createAsmNode<If>(_node);
|
auto ifStatement = createAsmNode<If>(_node);
|
||||||
ifStatement.condition = make_unique<Expression>(createExpression(member(_node, "condition")));
|
ifStatement.condition = std::make_unique<Expression>(createExpression(member(_node, "condition")));
|
||||||
ifStatement.body = createBlock(member(_node, "body"));
|
ifStatement.body = createBlock(member(_node, "body"));
|
||||||
return ifStatement;
|
return ifStatement;
|
||||||
}
|
}
|
||||||
@ -292,7 +291,7 @@ Case AsmJsonImporter::createCase(Json::Value const& _node)
|
|||||||
if (value.isString())
|
if (value.isString())
|
||||||
yulAssert(value.asString() == "default", "Expected default case");
|
yulAssert(value.asString() == "default", "Expected default case");
|
||||||
else
|
else
|
||||||
caseStatement.value = make_unique<Literal>(createLiteral(value));
|
caseStatement.value = std::make_unique<Literal>(createLiteral(value));
|
||||||
caseStatement.body = createBlock(member(_node, "body"));
|
caseStatement.body = createBlock(member(_node, "body"));
|
||||||
return caseStatement;
|
return caseStatement;
|
||||||
}
|
}
|
||||||
@ -300,7 +299,7 @@ Case AsmJsonImporter::createCase(Json::Value const& _node)
|
|||||||
Switch AsmJsonImporter::createSwitch(Json::Value const& _node)
|
Switch AsmJsonImporter::createSwitch(Json::Value const& _node)
|
||||||
{
|
{
|
||||||
auto switchStatement = createAsmNode<Switch>(_node);
|
auto switchStatement = createAsmNode<Switch>(_node);
|
||||||
switchStatement.expression = make_unique<Expression>(createExpression(member(_node, "expression")));
|
switchStatement.expression = std::make_unique<Expression>(createExpression(member(_node, "expression")));
|
||||||
for (auto const& var: member(_node, "cases"))
|
for (auto const& var: member(_node, "cases"))
|
||||||
switchStatement.cases.emplace_back(createCase(var));
|
switchStatement.cases.emplace_back(createCase(var));
|
||||||
return switchStatement;
|
return switchStatement;
|
||||||
@ -310,7 +309,7 @@ ForLoop AsmJsonImporter::createForLoop(Json::Value const& _node)
|
|||||||
{
|
{
|
||||||
auto forLoop = createAsmNode<ForLoop>(_node);
|
auto forLoop = createAsmNode<ForLoop>(_node);
|
||||||
forLoop.pre = createBlock(member(_node, "pre"));
|
forLoop.pre = createBlock(member(_node, "pre"));
|
||||||
forLoop.condition = make_unique<Expression>(createExpression(member(_node, "condition")));
|
forLoop.condition = std::make_unique<Expression>(createExpression(member(_node, "condition")));
|
||||||
forLoop.post = createBlock(member(_node, "post"));
|
forLoop.post = createBlock(member(_node, "post"));
|
||||||
forLoop.body = createBlock(member(_node, "body"));
|
forLoop.body = createBlock(member(_node, "body"));
|
||||||
return forLoop;
|
return forLoop;
|
||||||
|
@ -37,7 +37,6 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
using namespace solidity::langutil;
|
using namespace solidity::langutil;
|
||||||
@ -46,7 +45,7 @@ using namespace solidity::yul;
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
optional<int> toInt(string const& _value)
|
std::optional<int> toInt(std::string const& _value)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -54,7 +53,7 @@ optional<int> toInt(string const& _value)
|
|||||||
}
|
}
|
||||||
catch (...)
|
catch (...)
|
||||||
{
|
{
|
||||||
return nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +74,7 @@ std::shared_ptr<DebugData const> Parser::createDebugData() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Parser::updateLocationEndFrom(
|
void Parser::updateLocationEndFrom(
|
||||||
shared_ptr<DebugData const>& _debugData,
|
std::shared_ptr<DebugData const>& _debugData,
|
||||||
SourceLocation const& _location
|
SourceLocation const& _location
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
@ -88,7 +87,7 @@ void Parser::updateLocationEndFrom(
|
|||||||
DebugData updatedDebugData = *_debugData;
|
DebugData updatedDebugData = *_debugData;
|
||||||
updatedDebugData.nativeLocation.end = _location.end;
|
updatedDebugData.nativeLocation.end = _location.end;
|
||||||
updatedDebugData.originLocation.end = _location.end;
|
updatedDebugData.originLocation.end = _location.end;
|
||||||
_debugData = make_shared<DebugData const>(std::move(updatedDebugData));
|
_debugData = std::make_shared<DebugData const>(std::move(updatedDebugData));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UseSourceLocationFrom::LocationOverride:
|
case UseSourceLocationFrom::LocationOverride:
|
||||||
@ -98,21 +97,21 @@ void Parser::updateLocationEndFrom(
|
|||||||
{
|
{
|
||||||
DebugData updatedDebugData = *_debugData;
|
DebugData updatedDebugData = *_debugData;
|
||||||
updatedDebugData.nativeLocation.end = _location.end;
|
updatedDebugData.nativeLocation.end = _location.end;
|
||||||
_debugData = make_shared<DebugData const>(std::move(updatedDebugData));
|
_debugData = std::make_shared<DebugData const>(std::move(updatedDebugData));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<Block> Parser::parse(CharStream& _charStream)
|
std::unique_ptr<Block> Parser::parse(CharStream& _charStream)
|
||||||
{
|
{
|
||||||
m_scanner = make_shared<Scanner>(_charStream);
|
m_scanner = std::make_shared<Scanner>(_charStream);
|
||||||
unique_ptr<Block> block = parseInline(m_scanner);
|
std::unique_ptr<Block> block = parseInline(m_scanner);
|
||||||
expectToken(Token::EOS);
|
expectToken(Token::EOS);
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_ptr<Block> Parser::parseInline(std::shared_ptr<Scanner> const& _scanner)
|
std::unique_ptr<Block> Parser::parseInline(std::shared_ptr<Scanner> const& _scanner)
|
||||||
{
|
{
|
||||||
m_recursionDepth = 0;
|
m_recursionDepth = 0;
|
||||||
|
|
||||||
@ -124,7 +123,7 @@ unique_ptr<Block> Parser::parseInline(std::shared_ptr<Scanner> const& _scanner)
|
|||||||
m_scanner = _scanner;
|
m_scanner = _scanner;
|
||||||
if (m_useSourceLocationFrom == UseSourceLocationFrom::Comments)
|
if (m_useSourceLocationFrom == UseSourceLocationFrom::Comments)
|
||||||
fetchDebugDataFromComment();
|
fetchDebugDataFromComment();
|
||||||
return make_unique<Block>(parseBlock());
|
return std::make_unique<Block>(parseBlock());
|
||||||
}
|
}
|
||||||
catch (FatalError const&)
|
catch (FatalError const&)
|
||||||
{
|
{
|
||||||
@ -146,17 +145,17 @@ void Parser::fetchDebugDataFromComment()
|
|||||||
{
|
{
|
||||||
solAssert(m_sourceNames.has_value(), "");
|
solAssert(m_sourceNames.has_value(), "");
|
||||||
|
|
||||||
static regex const tagRegex = regex(
|
static std::regex const tagRegex = std::regex(
|
||||||
R"~~((?:^|\s+)(@[a-zA-Z0-9\-_]+)(?:\s+|$))~~", // tag, e.g: @src
|
R"~~((?:^|\s+)(@[a-zA-Z0-9\-_]+)(?:\s+|$))~~", // tag, e.g: @src
|
||||||
regex_constants::ECMAScript | regex_constants::optimize
|
std::regex_constants::ECMAScript | std::regex_constants::optimize
|
||||||
);
|
);
|
||||||
|
|
||||||
string_view commentLiteral = m_scanner->currentCommentLiteral();
|
std::string_view commentLiteral = m_scanner->currentCommentLiteral();
|
||||||
match_results<string_view::const_iterator> match;
|
std::match_results<std::string_view::const_iterator> match;
|
||||||
|
|
||||||
langutil::SourceLocation originLocation = m_locationFromComment;
|
langutil::SourceLocation originLocation = m_locationFromComment;
|
||||||
// Empty for each new node.
|
// Empty for each new node.
|
||||||
optional<int> astID;
|
std::optional<int> astID;
|
||||||
|
|
||||||
while (regex_search(commentLiteral.cbegin(), commentLiteral.cend(), match, tagRegex))
|
while (regex_search(commentLiteral.cbegin(), commentLiteral.cend(), match, tagRegex))
|
||||||
{
|
{
|
||||||
@ -186,17 +185,17 @@ void Parser::fetchDebugDataFromComment()
|
|||||||
m_astIDFromComment = astID;
|
m_astIDFromComment = astID;
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<pair<string_view, SourceLocation>> Parser::parseSrcComment(
|
std::optional<std::pair<std::string_view, SourceLocation>> Parser::parseSrcComment(
|
||||||
string_view const _arguments,
|
std::string_view const _arguments,
|
||||||
langutil::SourceLocation const& _commentLocation
|
langutil::SourceLocation const& _commentLocation
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
static regex const argsRegex = regex(
|
static std::regex const argsRegex = std::regex(
|
||||||
R"~~(^(-1|\d+):(-1|\d+):(-1|\d+)(?:\s+|$))~~" // index and location, e.g.: 1:234:-1
|
R"~~(^(-1|\d+):(-1|\d+):(-1|\d+)(?:\s+|$))~~" // index and location, e.g.: 1:234:-1
|
||||||
R"~~(("(?:[^"\\]|\\.)*"?)?)~~", // optional code snippet, e.g.: "string memory s = \"abc\";..."
|
R"~~(("(?:[^"\\]|\\.)*"?)?)~~", // optional code snippet, e.g.: "string memory s = \"abc\";..."
|
||||||
regex_constants::ECMAScript | regex_constants::optimize
|
std::regex_constants::ECMAScript | std::regex_constants::optimize
|
||||||
);
|
);
|
||||||
match_results<string_view::const_iterator> match;
|
std::match_results<std::string_view::const_iterator> match;
|
||||||
if (!regex_search(_arguments.cbegin(), _arguments.cend(), match, argsRegex))
|
if (!regex_search(_arguments.cbegin(), _arguments.cend(), match, argsRegex))
|
||||||
{
|
{
|
||||||
m_errorReporter.syntaxError(
|
m_errorReporter.syntaxError(
|
||||||
@ -204,11 +203,11 @@ optional<pair<string_view, SourceLocation>> Parser::parseSrcComment(
|
|||||||
_commentLocation,
|
_commentLocation,
|
||||||
"Invalid values in source location mapping. Could not parse location specification."
|
"Invalid values in source location mapping. Could not parse location specification."
|
||||||
);
|
);
|
||||||
return nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
solAssert(match.size() == 5, "");
|
solAssert(match.size() == 5, "");
|
||||||
string_view tail = _arguments.substr(static_cast<size_t>(match.position() + match.length()));
|
std::string_view tail = _arguments.substr(static_cast<size_t>(match.position() + match.length()));
|
||||||
|
|
||||||
if (match[4].matched && (
|
if (match[4].matched && (
|
||||||
!boost::algorithm::ends_with(match[4].str(), "\"") ||
|
!boost::algorithm::ends_with(match[4].str(), "\"") ||
|
||||||
@ -223,9 +222,9 @@ optional<pair<string_view, SourceLocation>> Parser::parseSrcComment(
|
|||||||
return {{tail, SourceLocation{}}};
|
return {{tail, SourceLocation{}}};
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<int> const sourceIndex = toInt(match[1].str());
|
std::optional<int> const sourceIndex = toInt(match[1].str());
|
||||||
optional<int> const start = toInt(match[2].str());
|
std::optional<int> const start = toInt(match[2].str());
|
||||||
optional<int> const end = toInt(match[3].str());
|
std::optional<int> const end = toInt(match[3].str());
|
||||||
|
|
||||||
if (!sourceIndex.has_value() || !start.has_value() || !end.has_value())
|
if (!sourceIndex.has_value() || !start.has_value() || !end.has_value())
|
||||||
m_errorReporter.syntaxError(
|
m_errorReporter.syntaxError(
|
||||||
@ -244,26 +243,26 @@ optional<pair<string_view, SourceLocation>> Parser::parseSrcComment(
|
|||||||
);
|
);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
shared_ptr<string const> sourceName = m_sourceNames->at(static_cast<unsigned>(sourceIndex.value()));
|
std::shared_ptr<std::string const> sourceName = m_sourceNames->at(static_cast<unsigned>(sourceIndex.value()));
|
||||||
solAssert(sourceName, "");
|
solAssert(sourceName, "");
|
||||||
return {{tail, SourceLocation{start.value(), end.value(), std::move(sourceName)}}};
|
return {{tail, SourceLocation{start.value(), end.value(), std::move(sourceName)}}};
|
||||||
}
|
}
|
||||||
return {{tail, SourceLocation{}}};
|
return {{tail, SourceLocation{}}};
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<pair<string_view, optional<int>>> Parser::parseASTIDComment(
|
std::optional<std::pair<std::string_view, std::optional<int>>> Parser::parseASTIDComment(
|
||||||
string_view _arguments,
|
std::string_view _arguments,
|
||||||
langutil::SourceLocation const& _commentLocation
|
langutil::SourceLocation const& _commentLocation
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
static regex const argRegex = regex(
|
static std::regex const argRegex = std::regex(
|
||||||
R"~~(^(\d+)(?:\s|$))~~",
|
R"~~(^(\d+)(?:\s|$))~~",
|
||||||
regex_constants::ECMAScript | regex_constants::optimize
|
std::regex_constants::ECMAScript | std::regex_constants::optimize
|
||||||
);
|
);
|
||||||
match_results<string_view::const_iterator> match;
|
std::match_results<std::string_view::const_iterator> match;
|
||||||
optional<int> astID;
|
std::optional<int> astID;
|
||||||
bool matched = regex_search(_arguments.cbegin(), _arguments.cend(), match, argRegex);
|
bool matched = regex_search(_arguments.cbegin(), _arguments.cend(), match, argRegex);
|
||||||
string_view tail = _arguments;
|
std::string_view tail = _arguments;
|
||||||
if (matched)
|
if (matched)
|
||||||
{
|
{
|
||||||
solAssert(match.size() == 2, "");
|
solAssert(match.size() == 2, "");
|
||||||
@ -275,12 +274,12 @@ optional<pair<string_view, optional<int>>> Parser::parseASTIDComment(
|
|||||||
if (!matched || !astID || *astID < 0 || static_cast<int64_t>(*astID) != *astID)
|
if (!matched || !astID || *astID < 0 || static_cast<int64_t>(*astID) != *astID)
|
||||||
{
|
{
|
||||||
m_errorReporter.syntaxError(1749_error, _commentLocation, "Invalid argument for @ast-id.");
|
m_errorReporter.syntaxError(1749_error, _commentLocation, "Invalid argument for @ast-id.");
|
||||||
astID = nullopt;
|
astID = std::nullopt;
|
||||||
}
|
}
|
||||||
if (matched)
|
if (matched)
|
||||||
return {{_arguments, astID}};
|
return {{_arguments, astID}};
|
||||||
else
|
else
|
||||||
return nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
Block Parser::parseBlock()
|
Block Parser::parseBlock()
|
||||||
@ -310,7 +309,7 @@ Statement Parser::parseStatement()
|
|||||||
{
|
{
|
||||||
If _if = createWithLocation<If>();
|
If _if = createWithLocation<If>();
|
||||||
advance();
|
advance();
|
||||||
_if.condition = make_unique<Expression>(parseExpression());
|
_if.condition = std::make_unique<Expression>(parseExpression());
|
||||||
_if.body = parseBlock();
|
_if.body = parseBlock();
|
||||||
updateLocationEndFrom(_if.debugData, nativeLocationOf(_if.body));
|
updateLocationEndFrom(_if.debugData, nativeLocationOf(_if.body));
|
||||||
return Statement{std::move(_if)};
|
return Statement{std::move(_if)};
|
||||||
@ -319,7 +318,7 @@ Statement Parser::parseStatement()
|
|||||||
{
|
{
|
||||||
Switch _switch = createWithLocation<Switch>();
|
Switch _switch = createWithLocation<Switch>();
|
||||||
advance();
|
advance();
|
||||||
_switch.expression = make_unique<Expression>(parseExpression());
|
_switch.expression = std::make_unique<Expression>(parseExpression());
|
||||||
while (currentToken() == Token::Case)
|
while (currentToken() == Token::Case)
|
||||||
_switch.cases.emplace_back(parseCase());
|
_switch.cases.emplace_back(parseCase());
|
||||||
if (currentToken() == Token::Default)
|
if (currentToken() == Token::Default)
|
||||||
@ -364,7 +363,7 @@ Statement Parser::parseStatement()
|
|||||||
// Options left:
|
// Options left:
|
||||||
// Expression/FunctionCall
|
// Expression/FunctionCall
|
||||||
// Assignment
|
// Assignment
|
||||||
variant<Literal, Identifier> elementary(parseLiteralOrIdentifier());
|
std::variant<Literal, Identifier> elementary(parseLiteralOrIdentifier());
|
||||||
|
|
||||||
switch (currentToken())
|
switch (currentToken())
|
||||||
{
|
{
|
||||||
@ -381,7 +380,7 @@ Statement Parser::parseStatement()
|
|||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
if (!holds_alternative<Identifier>(elementary))
|
if (!std::holds_alternative<Identifier>(elementary))
|
||||||
{
|
{
|
||||||
auto const token = currentToken() == Token::Comma ? "," : ":=";
|
auto const token = currentToken() == Token::Comma ? "," : ":=";
|
||||||
|
|
||||||
@ -411,7 +410,7 @@ Statement Parser::parseStatement()
|
|||||||
|
|
||||||
expectToken(Token::AssemblyAssign);
|
expectToken(Token::AssemblyAssign);
|
||||||
|
|
||||||
assignment.value = make_unique<Expression>(parseExpression());
|
assignment.value = std::make_unique<Expression>(parseExpression());
|
||||||
updateLocationEndFrom(assignment.debugData, nativeLocationOf(*assignment.value));
|
updateLocationEndFrom(assignment.debugData, nativeLocationOf(*assignment.value));
|
||||||
|
|
||||||
return Statement{std::move(assignment)};
|
return Statement{std::move(assignment)};
|
||||||
@ -434,10 +433,10 @@ Case Parser::parseCase()
|
|||||||
else if (currentToken() == Token::Case)
|
else if (currentToken() == Token::Case)
|
||||||
{
|
{
|
||||||
advance();
|
advance();
|
||||||
variant<Literal, Identifier> literal = parseLiteralOrIdentifier();
|
std::variant<Literal, Identifier> literal = parseLiteralOrIdentifier();
|
||||||
if (!holds_alternative<Literal>(literal))
|
if (!std::holds_alternative<Literal>(literal))
|
||||||
fatalParserError(4805_error, "Literal expected.");
|
fatalParserError(4805_error, "Literal expected.");
|
||||||
_case.value = make_unique<Literal>(std::get<Literal>(std::move(literal)));
|
_case.value = std::make_unique<Literal>(std::get<Literal>(std::move(literal)));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
yulAssert(false, "Case or default case expected.");
|
yulAssert(false, "Case or default case expected.");
|
||||||
@ -457,7 +456,7 @@ ForLoop Parser::parseForLoop()
|
|||||||
m_currentForLoopComponent = ForLoopComponent::ForLoopPre;
|
m_currentForLoopComponent = ForLoopComponent::ForLoopPre;
|
||||||
forLoop.pre = parseBlock();
|
forLoop.pre = parseBlock();
|
||||||
m_currentForLoopComponent = ForLoopComponent::None;
|
m_currentForLoopComponent = ForLoopComponent::None;
|
||||||
forLoop.condition = make_unique<Expression>(parseExpression());
|
forLoop.condition = std::make_unique<Expression>(parseExpression());
|
||||||
m_currentForLoopComponent = ForLoopComponent::ForLoopPost;
|
m_currentForLoopComponent = ForLoopComponent::ForLoopPost;
|
||||||
forLoop.post = parseBlock();
|
forLoop.post = parseBlock();
|
||||||
m_currentForLoopComponent = ForLoopComponent::ForLoopBody;
|
m_currentForLoopComponent = ForLoopComponent::ForLoopBody;
|
||||||
@ -473,7 +472,7 @@ Expression Parser::parseExpression()
|
|||||||
{
|
{
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
|
|
||||||
variant<Literal, Identifier> operation = parseLiteralOrIdentifier();
|
std::variant<Literal, Identifier> operation = parseLiteralOrIdentifier();
|
||||||
return visit(GenericVisitor{
|
return visit(GenericVisitor{
|
||||||
[&](Identifier& _identifier) -> Expression
|
[&](Identifier& _identifier) -> Expression
|
||||||
{
|
{
|
||||||
@ -494,7 +493,7 @@ Expression Parser::parseExpression()
|
|||||||
}, operation);
|
}, operation);
|
||||||
}
|
}
|
||||||
|
|
||||||
variant<Literal, Identifier> Parser::parseLiteralOrIdentifier()
|
std::variant<Literal, Identifier> Parser::parseLiteralOrIdentifier()
|
||||||
{
|
{
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
switch (currentToken())
|
switch (currentToken())
|
||||||
@ -572,7 +571,7 @@ VariableDeclaration Parser::parseVariableDeclaration()
|
|||||||
if (currentToken() == Token::AssemblyAssign)
|
if (currentToken() == Token::AssemblyAssign)
|
||||||
{
|
{
|
||||||
expectToken(Token::AssemblyAssign);
|
expectToken(Token::AssemblyAssign);
|
||||||
varDecl.value = make_unique<Expression>(parseExpression());
|
varDecl.value = std::make_unique<Expression>(parseExpression());
|
||||||
updateLocationEndFrom(varDecl.debugData, nativeLocationOf(*varDecl.value));
|
updateLocationEndFrom(varDecl.debugData, nativeLocationOf(*varDecl.value));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -628,11 +627,11 @@ FunctionDefinition Parser::parseFunctionDefinition()
|
|||||||
return funDef;
|
return funDef;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionCall Parser::parseCall(variant<Literal, Identifier>&& _initialOp)
|
FunctionCall Parser::parseCall(std::variant<Literal, Identifier>&& _initialOp)
|
||||||
{
|
{
|
||||||
RecursionGuard recursionGuard(*this);
|
RecursionGuard recursionGuard(*this);
|
||||||
|
|
||||||
if (!holds_alternative<Identifier>(_initialOp))
|
if (!std::holds_alternative<Identifier>(_initialOp))
|
||||||
fatalParserError(9980_error, "Function name expected.");
|
fatalParserError(9980_error, "Function name expected.");
|
||||||
|
|
||||||
FunctionCall ret;
|
FunctionCall ret;
|
||||||
@ -681,7 +680,7 @@ YulString Parser::expectAsmIdentifier()
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::checkBreakContinuePosition(string const& _which)
|
void Parser::checkBreakContinuePosition(std::string const& _which)
|
||||||
{
|
{
|
||||||
switch (m_currentForLoopComponent)
|
switch (m_currentForLoopComponent)
|
||||||
{
|
{
|
||||||
@ -699,7 +698,7 @@ void Parser::checkBreakContinuePosition(string const& _which)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Parser::isValidNumberLiteral(string const& _literal)
|
bool Parser::isValidNumberLiteral(std::string const& _literal)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -713,5 +712,5 @@ bool Parser::isValidNumberLiteral(string const& _literal)
|
|||||||
if (boost::starts_with(_literal, "0x"))
|
if (boost::starts_with(_literal, "0x"))
|
||||||
return true;
|
return true;
|
||||||
else
|
else
|
||||||
return _literal.find_first_not_of("0123456789") == string::npos;
|
return _literal.find_first_not_of("0123456789") == std::string::npos;
|
||||||
}
|
}
|
||||||
|
@ -37,15 +37,14 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::langutil;
|
using namespace solidity::langutil;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
|
|
||||||
string AsmPrinter::operator()(Literal const& _literal)
|
std::string AsmPrinter::operator()(Literal const& _literal)
|
||||||
{
|
{
|
||||||
string const locationComment = formatDebugData(_literal);
|
std::string const locationComment = formatDebugData(_literal);
|
||||||
|
|
||||||
switch (_literal.kind)
|
switch (_literal.kind)
|
||||||
{
|
{
|
||||||
@ -62,34 +61,34 @@ string AsmPrinter::operator()(Literal const& _literal)
|
|||||||
return locationComment + escapeAndQuoteString(_literal.value.str()) + appendTypeName(_literal.type);
|
return locationComment + escapeAndQuoteString(_literal.value.str()) + appendTypeName(_literal.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(Identifier const& _identifier)
|
std::string AsmPrinter::operator()(Identifier const& _identifier)
|
||||||
{
|
{
|
||||||
yulAssert(!_identifier.name.empty(), "Invalid identifier.");
|
yulAssert(!_identifier.name.empty(), "Invalid identifier.");
|
||||||
return formatDebugData(_identifier) + _identifier.name.str();
|
return formatDebugData(_identifier) + _identifier.name.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(ExpressionStatement const& _statement)
|
std::string AsmPrinter::operator()(ExpressionStatement const& _statement)
|
||||||
{
|
{
|
||||||
string const locationComment = formatDebugData(_statement);
|
std::string const locationComment = formatDebugData(_statement);
|
||||||
|
|
||||||
return locationComment + std::visit(*this, _statement.expression);
|
return locationComment + std::visit(*this, _statement.expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(Assignment const& _assignment)
|
std::string AsmPrinter::operator()(Assignment const& _assignment)
|
||||||
{
|
{
|
||||||
string const locationComment = formatDebugData(_assignment);
|
std::string const locationComment = formatDebugData(_assignment);
|
||||||
|
|
||||||
yulAssert(_assignment.variableNames.size() >= 1, "");
|
yulAssert(_assignment.variableNames.size() >= 1, "");
|
||||||
string variables = (*this)(_assignment.variableNames.front());
|
std::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 locationComment + variables + " := " + std::visit(*this, *_assignment.value);
|
return locationComment + variables + " := " + std::visit(*this, *_assignment.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(VariableDeclaration const& _variableDeclaration)
|
std::string AsmPrinter::operator()(VariableDeclaration const& _variableDeclaration)
|
||||||
{
|
{
|
||||||
string out = formatDebugData(_variableDeclaration);
|
std::string out = formatDebugData(_variableDeclaration);
|
||||||
|
|
||||||
out += "let ";
|
out += "let ";
|
||||||
out += boost::algorithm::join(
|
out += boost::algorithm::join(
|
||||||
@ -106,11 +105,11 @@ string AsmPrinter::operator()(VariableDeclaration const& _variableDeclaration)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(FunctionDefinition const& _functionDefinition)
|
std::string AsmPrinter::operator()(FunctionDefinition const& _functionDefinition)
|
||||||
{
|
{
|
||||||
yulAssert(!_functionDefinition.name.empty(), "Invalid function name.");
|
yulAssert(!_functionDefinition.name.empty(), "Invalid function name.");
|
||||||
|
|
||||||
string out = formatDebugData(_functionDefinition);
|
std::string out = formatDebugData(_functionDefinition);
|
||||||
out += "function " + _functionDefinition.name.str() + "(";
|
out += "function " + _functionDefinition.name.str() + "(";
|
||||||
out += boost::algorithm::join(
|
out += boost::algorithm::join(
|
||||||
_functionDefinition.parameters | ranges::views::transform(
|
_functionDefinition.parameters | ranges::views::transform(
|
||||||
@ -133,10 +132,10 @@ string AsmPrinter::operator()(FunctionDefinition const& _functionDefinition)
|
|||||||
return out + "\n" + (*this)(_functionDefinition.body);
|
return out + "\n" + (*this)(_functionDefinition.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(FunctionCall const& _functionCall)
|
std::string AsmPrinter::operator()(FunctionCall const& _functionCall)
|
||||||
{
|
{
|
||||||
string const locationComment = formatDebugData(_functionCall);
|
std::string const locationComment = formatDebugData(_functionCall);
|
||||||
string const functionName = (*this)(_functionCall.functionName);
|
std::string const functionName = (*this)(_functionCall.functionName);
|
||||||
return
|
return
|
||||||
locationComment +
|
locationComment +
|
||||||
functionName + "(" +
|
functionName + "(" +
|
||||||
@ -146,26 +145,26 @@ string AsmPrinter::operator()(FunctionCall const& _functionCall)
|
|||||||
")";
|
")";
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(If const& _if)
|
std::string AsmPrinter::operator()(If const& _if)
|
||||||
{
|
{
|
||||||
yulAssert(_if.condition, "Invalid if condition.");
|
yulAssert(_if.condition, "Invalid if condition.");
|
||||||
|
|
||||||
string out = formatDebugData(_if);
|
std::string out = formatDebugData(_if);
|
||||||
out += "if " + std::visit(*this, *_if.condition);
|
out += "if " + std::visit(*this, *_if.condition);
|
||||||
|
|
||||||
string body = (*this)(_if.body);
|
std::string body = (*this)(_if.body);
|
||||||
char delim = '\n';
|
char delim = '\n';
|
||||||
if (body.find('\n') == string::npos)
|
if (body.find('\n') == std::string::npos)
|
||||||
delim = ' ';
|
delim = ' ';
|
||||||
|
|
||||||
return out + delim + body;
|
return out + delim + body;
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(Switch const& _switch)
|
std::string AsmPrinter::operator()(Switch const& _switch)
|
||||||
{
|
{
|
||||||
yulAssert(_switch.expression, "Invalid expression pointer.");
|
yulAssert(_switch.expression, "Invalid expression pointer.");
|
||||||
|
|
||||||
string out = formatDebugData(_switch);
|
std::string out = formatDebugData(_switch);
|
||||||
out += "switch " + std::visit(*this, *_switch.expression);
|
out += "switch " + std::visit(*this, *_switch.expression);
|
||||||
|
|
||||||
for (auto const& _case: _switch.cases)
|
for (auto const& _case: _switch.cases)
|
||||||
@ -179,20 +178,20 @@ string AsmPrinter::operator()(Switch const& _switch)
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(ForLoop const& _forLoop)
|
std::string AsmPrinter::operator()(ForLoop const& _forLoop)
|
||||||
{
|
{
|
||||||
yulAssert(_forLoop.condition, "Invalid for loop condition.");
|
yulAssert(_forLoop.condition, "Invalid for loop condition.");
|
||||||
string const locationComment = formatDebugData(_forLoop);
|
std::string const locationComment = formatDebugData(_forLoop);
|
||||||
|
|
||||||
string pre = (*this)(_forLoop.pre);
|
std::string pre = (*this)(_forLoop.pre);
|
||||||
string condition = std::visit(*this, *_forLoop.condition);
|
std::string condition = std::visit(*this, *_forLoop.condition);
|
||||||
string post = (*this)(_forLoop.post);
|
std::string post = (*this)(_forLoop.post);
|
||||||
|
|
||||||
char delim = '\n';
|
char delim = '\n';
|
||||||
if (
|
if (
|
||||||
pre.size() + condition.size() + post.size() < 60 &&
|
pre.size() + condition.size() + post.size() < 60 &&
|
||||||
pre.find('\n') == string::npos &&
|
pre.find('\n') == std::string::npos &&
|
||||||
post.find('\n') == string::npos
|
post.find('\n') == std::string::npos
|
||||||
)
|
)
|
||||||
delim = ' ';
|
delim = ' ';
|
||||||
return
|
return
|
||||||
@ -201,33 +200,33 @@ string AsmPrinter::operator()(ForLoop const& _forLoop)
|
|||||||
(*this)(_forLoop.body);
|
(*this)(_forLoop.body);
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(Break const& _break)
|
std::string AsmPrinter::operator()(Break const& _break)
|
||||||
{
|
{
|
||||||
return formatDebugData(_break) + "break";
|
return formatDebugData(_break) + "break";
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(Continue const& _continue)
|
std::string AsmPrinter::operator()(Continue const& _continue)
|
||||||
{
|
{
|
||||||
return formatDebugData(_continue) + "continue";
|
return formatDebugData(_continue) + "continue";
|
||||||
}
|
}
|
||||||
|
|
||||||
// '_leave' and '__leave' is reserved in VisualStudio
|
// '_leave' and '__leave' is reserved in VisualStudio
|
||||||
string AsmPrinter::operator()(Leave const& leave_)
|
std::string AsmPrinter::operator()(Leave const& leave_)
|
||||||
{
|
{
|
||||||
return formatDebugData(leave_) + "leave";
|
return formatDebugData(leave_) + "leave";
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::operator()(Block const& _block)
|
std::string AsmPrinter::operator()(Block const& _block)
|
||||||
{
|
{
|
||||||
string const locationComment = formatDebugData(_block);
|
std::string const locationComment = formatDebugData(_block);
|
||||||
|
|
||||||
if (_block.statements.empty())
|
if (_block.statements.empty())
|
||||||
return locationComment + "{ }";
|
return locationComment + "{ }";
|
||||||
string body = boost::algorithm::join(
|
std::string body = boost::algorithm::join(
|
||||||
_block.statements | ranges::views::transform([&](auto&& _node) { return std::visit(*this, _node); }),
|
_block.statements | ranges::views::transform([&](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') == std::string::npos)
|
||||||
return locationComment + "{ " + body + " }";
|
return locationComment + "{ " + body + " }";
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -236,13 +235,13 @@ string AsmPrinter::operator()(Block const& _block)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::formatTypedName(TypedName _variable)
|
std::string AsmPrinter::formatTypedName(TypedName _variable)
|
||||||
{
|
{
|
||||||
yulAssert(!_variable.name.empty(), "Invalid variable name.");
|
yulAssert(!_variable.name.empty(), "Invalid variable name.");
|
||||||
return formatDebugData(_variable) + _variable.name.str() + appendTypeName(_variable.type);
|
return formatDebugData(_variable) + _variable.name.str() + appendTypeName(_variable.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::appendTypeName(YulString _type, bool _isBoolLiteral) const
|
std::string AsmPrinter::appendTypeName(YulString _type, bool _isBoolLiteral) const
|
||||||
{
|
{
|
||||||
if (m_dialect && !_type.empty())
|
if (m_dialect && !_type.empty())
|
||||||
{
|
{
|
||||||
@ -258,9 +257,9 @@ string AsmPrinter::appendTypeName(YulString _type, bool _isBoolLiteral) const
|
|||||||
return ":" + _type.str();
|
return ":" + _type.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::formatSourceLocation(
|
std::string AsmPrinter::formatSourceLocation(
|
||||||
SourceLocation const& _location,
|
SourceLocation const& _location,
|
||||||
map<string, unsigned> const& _nameToSourceIndex,
|
std::map<std::string, unsigned> const& _nameToSourceIndex,
|
||||||
DebugInfoSelection const& _debugInfoSelection,
|
DebugInfoSelection const& _debugInfoSelection,
|
||||||
CharStreamProvider const* _soliditySourceProvider
|
CharStreamProvider const* _soliditySourceProvider
|
||||||
)
|
)
|
||||||
@ -272,11 +271,11 @@ string AsmPrinter::formatSourceLocation(
|
|||||||
if (_debugInfoSelection.none())
|
if (_debugInfoSelection.none())
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
string sourceIndex = "-1";
|
std::string sourceIndex = "-1";
|
||||||
string solidityCodeSnippet = "";
|
std::string solidityCodeSnippet = "";
|
||||||
if (_location.sourceName)
|
if (_location.sourceName)
|
||||||
{
|
{
|
||||||
sourceIndex = to_string(_nameToSourceIndex.at(*_location.sourceName));
|
sourceIndex = std::to_string(_nameToSourceIndex.at(*_location.sourceName));
|
||||||
|
|
||||||
if (
|
if (
|
||||||
_debugInfoSelection.snippet &&
|
_debugInfoSelection.snippet &&
|
||||||
@ -295,26 +294,26 @@ string AsmPrinter::formatSourceLocation(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string sourceLocation =
|
std::string sourceLocation =
|
||||||
"@src " +
|
"@src " +
|
||||||
sourceIndex +
|
sourceIndex +
|
||||||
":" +
|
":" +
|
||||||
to_string(_location.start) +
|
std::to_string(_location.start) +
|
||||||
":" +
|
":" +
|
||||||
to_string(_location.end);
|
std::to_string(_location.end);
|
||||||
|
|
||||||
return sourceLocation + (solidityCodeSnippet.empty() ? "" : " ") + solidityCodeSnippet;
|
return sourceLocation + (solidityCodeSnippet.empty() ? "" : " ") + solidityCodeSnippet;
|
||||||
}
|
}
|
||||||
|
|
||||||
string AsmPrinter::formatDebugData(shared_ptr<DebugData const> const& _debugData, bool _statement)
|
std::string AsmPrinter::formatDebugData(std::shared_ptr<DebugData const> const& _debugData, bool _statement)
|
||||||
{
|
{
|
||||||
if (!_debugData || m_debugInfoSelection.none())
|
if (!_debugData || m_debugInfoSelection.none())
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
vector<string> items;
|
std::vector<std::string> items;
|
||||||
if (auto id = _debugData->astID)
|
if (auto id = _debugData->astID)
|
||||||
if (m_debugInfoSelection.astID)
|
if (m_debugInfoSelection.astID)
|
||||||
items.emplace_back("@ast-id " + to_string(*id));
|
items.emplace_back("@ast-id " + std::to_string(*id));
|
||||||
|
|
||||||
if (
|
if (
|
||||||
m_lastLocation != _debugData->originLocation &&
|
m_lastLocation != _debugData->originLocation &&
|
||||||
@ -331,7 +330,7 @@ string AsmPrinter::formatDebugData(shared_ptr<DebugData const> const& _debugData
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
string commentBody = joinHumanReadable(items, " ");
|
std::string commentBody = joinHumanReadable(items, " ");
|
||||||
if (commentBody.empty())
|
if (commentBody.empty())
|
||||||
return "";
|
return "";
|
||||||
else
|
else
|
||||||
|
@ -26,7 +26,6 @@
|
|||||||
#include <libyul/backends/evm/EVMCodeTransform.h>
|
#include <libyul/backends/evm/EVMCodeTransform.h>
|
||||||
#include <libyul/backends/evm/NoOutputAssembly.h>
|
#include <libyul/backends/evm/NoOutputAssembly.h>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
|
@ -30,7 +30,6 @@
|
|||||||
#include <range/v3/view/reverse.hpp>
|
#include <range/v3/view/reverse.hpp>
|
||||||
#include <range/v3/algorithm/find_if.hpp>
|
#include <range/v3/algorithm/find_if.hpp>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
|
|
||||||
|
|
||||||
@ -162,7 +161,7 @@ void ControlFlowBuilder::newConnectedNode()
|
|||||||
|
|
||||||
ControlFlowNode* ControlFlowBuilder::newNode()
|
ControlFlowNode* ControlFlowBuilder::newNode()
|
||||||
{
|
{
|
||||||
m_nodes.emplace_back(make_shared<ControlFlowNode>());
|
m_nodes.emplace_back(std::make_shared<ControlFlowNode>());
|
||||||
return m_nodes.back().get();
|
return m_nodes.back().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,9 +229,9 @@ ControlFlowSideEffectsCollector::ControlFlowSideEffectsCollector(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
map<YulString, ControlFlowSideEffects> ControlFlowSideEffectsCollector::functionSideEffectsNamed() const
|
std::map<YulString, ControlFlowSideEffects> ControlFlowSideEffectsCollector::functionSideEffectsNamed() const
|
||||||
{
|
{
|
||||||
map<YulString, ControlFlowSideEffects> result;
|
std::map<YulString, ControlFlowSideEffects> result;
|
||||||
for (auto&& [function, sideEffects]: m_functionSideEffects)
|
for (auto&& [function, sideEffects]: m_functionSideEffects)
|
||||||
yulAssert(result.insert({function->name, sideEffects}).second);
|
yulAssert(result.insert({function->name, sideEffects}).second);
|
||||||
return result;
|
return result;
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include <libyul/AST.h>
|
#include <libyul/AST.h>
|
||||||
|
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
using namespace std;
|
|
||||||
using namespace solidity::langutil;
|
using namespace solidity::langutil;
|
||||||
|
|
||||||
Literal Dialect::zeroLiteralForType(solidity::yul::YulString _type) const
|
Literal Dialect::zeroLiteralForType(solidity::yul::YulString _type) const
|
||||||
@ -52,13 +51,13 @@ bool Dialect::validTypeForLiteral(LiteralKind _kind, YulString, YulString _type)
|
|||||||
|
|
||||||
Dialect const& Dialect::yulDeprecated()
|
Dialect const& Dialect::yulDeprecated()
|
||||||
{
|
{
|
||||||
static unique_ptr<Dialect> dialect;
|
static std::unique_ptr<Dialect> dialect;
|
||||||
static YulStringRepository::ResetCallback callback{[&] { dialect.reset(); }};
|
static YulStringRepository::ResetCallback callback{[&] { dialect.reset(); }};
|
||||||
|
|
||||||
if (!dialect)
|
if (!dialect)
|
||||||
{
|
{
|
||||||
// TODO will probably change, especially the list of types.
|
// TODO will probably change, especially the list of types.
|
||||||
dialect = make_unique<Dialect>();
|
dialect = std::make_unique<Dialect>();
|
||||||
dialect->defaultType = "u256"_yulstring;
|
dialect->defaultType = "u256"_yulstring;
|
||||||
dialect->boolType = "bool"_yulstring;
|
dialect->boolType = "bool"_yulstring;
|
||||||
dialect->types = {
|
dialect->types = {
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
|
|
||||||
#include <range/v3/view/reverse.hpp>
|
#include <range/v3/view/reverse.hpp>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
|
|
||||||
@ -51,7 +50,7 @@ void FunctionReferenceResolver::operator()(Block const& _block)
|
|||||||
{
|
{
|
||||||
m_scopes.emplace_back();
|
m_scopes.emplace_back();
|
||||||
for (auto const& statement: _block.statements)
|
for (auto const& statement: _block.statements)
|
||||||
if (auto const* function = get_if<FunctionDefinition>(&statement))
|
if (auto const* function = std::get_if<FunctionDefinition>(&statement))
|
||||||
m_scopes.back()[function->name] = function;
|
m_scopes.back()[function->name] = function;
|
||||||
|
|
||||||
ASTWalker::operator()(_block);
|
ASTWalker::operator()(_block);
|
||||||
|
@ -35,7 +35,6 @@
|
|||||||
|
|
||||||
#include <range/v3/view/transform.hpp>
|
#include <range/v3/view/transform.hpp>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::langutil;
|
using namespace solidity::langutil;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
@ -44,7 +43,7 @@ using namespace solidity::yul;
|
|||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
string indent(std::string const& _input)
|
std::string indent(std::string const& _input)
|
||||||
{
|
{
|
||||||
if (_input.empty())
|
if (_input.empty())
|
||||||
return _input;
|
return _input;
|
||||||
@ -53,12 +52,12 @@ string indent(std::string const& _input)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string Data::toString(Dialect const*, DebugInfoSelection const&, CharStreamProvider const*) const
|
std::string Data::toString(Dialect const*, DebugInfoSelection const&, CharStreamProvider const*) const
|
||||||
{
|
{
|
||||||
return "data \"" + name.str() + "\" hex\"" + util::toHex(data) + "\"";
|
return "data \"" + name.str() + "\" hex\"" + util::toHex(data) + "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
string Object::toString(
|
std::string Object::toString(
|
||||||
Dialect const* _dialect,
|
Dialect const* _dialect,
|
||||||
DebugInfoSelection const& _debugInfoSelection,
|
DebugInfoSelection const& _debugInfoSelection,
|
||||||
CharStreamProvider const* _soliditySourceProvider
|
CharStreamProvider const* _soliditySourceProvider
|
||||||
@ -67,17 +66,17 @@ string Object::toString(
|
|||||||
yulAssert(code, "No code");
|
yulAssert(code, "No code");
|
||||||
yulAssert(debugData, "No debug data");
|
yulAssert(debugData, "No debug data");
|
||||||
|
|
||||||
string useSrcComment;
|
std::string useSrcComment;
|
||||||
|
|
||||||
if (debugData->sourceNames)
|
if (debugData->sourceNames)
|
||||||
useSrcComment =
|
useSrcComment =
|
||||||
"/// @use-src " +
|
"/// @use-src " +
|
||||||
joinHumanReadable(ranges::views::transform(*debugData->sourceNames, [](auto&& _pair) {
|
joinHumanReadable(ranges::views::transform(*debugData->sourceNames, [](auto&& _pair) {
|
||||||
return to_string(_pair.first) + ":" + util::escapeAndQuoteString(*_pair.second);
|
return std::to_string(_pair.first) + ":" + util::escapeAndQuoteString(*_pair.second);
|
||||||
})) +
|
})) +
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
string inner = "code " + AsmPrinter(
|
std::string inner = "code " + AsmPrinter(
|
||||||
_dialect,
|
_dialect,
|
||||||
debugData->sourceNames,
|
debugData->sourceNames,
|
||||||
_debugInfoSelection,
|
_debugInfoSelection,
|
||||||
@ -107,7 +106,7 @@ Json::Value Object::toJson() const
|
|||||||
codeJson["block"] = AsmJsonConverter(0 /* sourceIndex */)(*code);
|
codeJson["block"] = AsmJsonConverter(0 /* sourceIndex */)(*code);
|
||||||
|
|
||||||
Json::Value subObjectsJson{Json::arrayValue};
|
Json::Value subObjectsJson{Json::arrayValue};
|
||||||
for (shared_ptr<ObjectNode> const& subObject: subObjects)
|
for (std::shared_ptr<ObjectNode> const& subObject: subObjects)
|
||||||
subObjectsJson.append(subObject->toJson());
|
subObjectsJson.append(subObject->toJson());
|
||||||
|
|
||||||
Json::Value ret{Json::objectValue};
|
Json::Value ret{Json::objectValue};
|
||||||
@ -118,13 +117,13 @@ Json::Value Object::toJson() const
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
set<YulString> Object::qualifiedDataNames() const
|
std::set<YulString> Object::qualifiedDataNames() const
|
||||||
{
|
{
|
||||||
set<YulString> qualifiedNames =
|
std::set<YulString> qualifiedNames =
|
||||||
name.empty() || util::contains(name.str(), '.') ?
|
name.empty() || util::contains(name.str(), '.') ?
|
||||||
set<YulString>{} :
|
std::set<YulString>{} :
|
||||||
set<YulString>{name};
|
std::set<YulString>{name};
|
||||||
for (shared_ptr<ObjectNode> const& subObjectNode: subObjects)
|
for (std::shared_ptr<ObjectNode> const& subObjectNode: subObjects)
|
||||||
{
|
{
|
||||||
yulAssert(qualifiedNames.count(subObjectNode->name) == 0, "");
|
yulAssert(qualifiedNames.count(subObjectNode->name) == 0, "");
|
||||||
if (util::contains(subObjectNode->name.str(), '.'))
|
if (util::contains(subObjectNode->name.str(), '.'))
|
||||||
@ -144,7 +143,7 @@ set<YulString> Object::qualifiedDataNames() const
|
|||||||
return qualifiedNames;
|
return qualifiedNames;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<size_t> Object::pathToSubObject(YulString _qualifiedName) const
|
std::vector<size_t> Object::pathToSubObject(YulString _qualifiedName) const
|
||||||
{
|
{
|
||||||
yulAssert(_qualifiedName != name, "");
|
yulAssert(_qualifiedName != name, "");
|
||||||
yulAssert(subIndexByName.count(name) == 0, "");
|
yulAssert(subIndexByName.count(name) == 0, "");
|
||||||
@ -153,12 +152,12 @@ vector<size_t> Object::pathToSubObject(YulString _qualifiedName) const
|
|||||||
_qualifiedName = YulString{_qualifiedName.str().substr(name.str().length() + 1)};
|
_qualifiedName = YulString{_qualifiedName.str().substr(name.str().length() + 1)};
|
||||||
yulAssert(!_qualifiedName.empty(), "");
|
yulAssert(!_qualifiedName.empty(), "");
|
||||||
|
|
||||||
vector<string> subObjectPathComponents;
|
std::vector<std::string> subObjectPathComponents;
|
||||||
boost::algorithm::split(subObjectPathComponents, _qualifiedName.str(), boost::is_any_of("."));
|
boost::algorithm::split(subObjectPathComponents, _qualifiedName.str(), boost::is_any_of("."));
|
||||||
|
|
||||||
vector<size_t> path;
|
std::vector<size_t> path;
|
||||||
Object const* object = this;
|
Object const* object = this;
|
||||||
for (string const& currentSubObjectName: subObjectPathComponents)
|
for (std::string const& currentSubObjectName: subObjectPathComponents)
|
||||||
{
|
{
|
||||||
yulAssert(!currentSubObjectName.empty(), "");
|
yulAssert(!currentSubObjectName.empty(), "");
|
||||||
auto subIndexIt = object->subIndexByName.find(YulString{currentSubObjectName});
|
auto subIndexIt = object->subIndexByName.find(YulString{currentSubObjectName});
|
||||||
@ -168,7 +167,7 @@ vector<size_t> Object::pathToSubObject(YulString _qualifiedName) const
|
|||||||
);
|
);
|
||||||
object = dynamic_cast<Object const*>(object->subObjects[subIndexIt->second].get());
|
object = dynamic_cast<Object const*>(object->subObjects[subIndexIt->second].get());
|
||||||
yulAssert(object, "Assembly object <" + _qualifiedName.str() + "> not found or does not contain code.");
|
yulAssert(object, "Assembly object <" + _qualifiedName.str() + "> not found or does not contain code.");
|
||||||
yulAssert(object->subId != numeric_limits<size_t>::max(), "");
|
yulAssert(object->subId != std::numeric_limits<size_t>::max(), "");
|
||||||
path.push_back({object->subId});
|
path.push_back({object->subId});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,27 +32,26 @@
|
|||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
using namespace solidity::langutil;
|
using namespace solidity::langutil;
|
||||||
|
|
||||||
shared_ptr<Object> ObjectParser::parse(shared_ptr<Scanner> const& _scanner, bool _reuseScanner)
|
std::shared_ptr<Object> ObjectParser::parse(std::shared_ptr<Scanner> const& _scanner, bool _reuseScanner)
|
||||||
{
|
{
|
||||||
m_recursionDepth = 0;
|
m_recursionDepth = 0;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
shared_ptr<Object> object;
|
std::shared_ptr<Object> object;
|
||||||
m_scanner = _scanner;
|
m_scanner = _scanner;
|
||||||
|
|
||||||
if (currentToken() == Token::LBrace)
|
if (currentToken() == Token::LBrace)
|
||||||
{
|
{
|
||||||
// Special case: Code-only form.
|
// Special case: Code-only form.
|
||||||
object = make_shared<Object>();
|
object = std::make_shared<Object>();
|
||||||
object->name = "object"_yulstring;
|
object->name = "object"_yulstring;
|
||||||
auto sourceNameMapping = tryParseSourceNameMapping();
|
auto sourceNameMapping = tryParseSourceNameMapping();
|
||||||
object->debugData = make_shared<ObjectDebugData>(ObjectDebugData{sourceNameMapping});
|
object->debugData = std::make_shared<ObjectDebugData>(ObjectDebugData{sourceNameMapping});
|
||||||
object->code = parseBlock(sourceNameMapping);
|
object->code = parseBlock(sourceNameMapping);
|
||||||
if (!object->code)
|
if (!object->code)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@ -71,14 +70,14 @@ shared_ptr<Object> ObjectParser::parse(shared_ptr<Scanner> const& _scanner, bool
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Object> ObjectParser::parseObject(Object* _containingObject)
|
std::shared_ptr<Object> ObjectParser::parseObject(Object* _containingObject)
|
||||||
{
|
{
|
||||||
RecursionGuard guard(*this);
|
RecursionGuard guard(*this);
|
||||||
|
|
||||||
shared_ptr<Object> ret = make_shared<Object>();
|
std::shared_ptr<Object> ret = std::make_shared<Object>();
|
||||||
|
|
||||||
auto sourceNameMapping = tryParseSourceNameMapping();
|
auto sourceNameMapping = tryParseSourceNameMapping();
|
||||||
ret->debugData = make_shared<ObjectDebugData>(ObjectDebugData{sourceNameMapping});
|
ret->debugData = std::make_shared<ObjectDebugData>(ObjectDebugData{sourceNameMapping});
|
||||||
|
|
||||||
if (currentToken() != Token::Identifier || currentLiteral() != "object")
|
if (currentToken() != Token::Identifier || currentLiteral() != "object")
|
||||||
fatalParserError(4294_error, "Expected keyword \"object\".");
|
fatalParserError(4294_error, "Expected keyword \"object\".");
|
||||||
@ -107,7 +106,7 @@ shared_ptr<Object> ObjectParser::parseObject(Object* _containingObject)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Block> ObjectParser::parseCode(optional<SourceNameMap> _sourceNames)
|
std::shared_ptr<Block> ObjectParser::parseCode(std::optional<SourceNameMap> _sourceNames)
|
||||||
{
|
{
|
||||||
if (currentToken() != Token::Identifier || currentLiteral() != "code")
|
if (currentToken() != Token::Identifier || currentLiteral() != "code")
|
||||||
fatalParserError(4846_error, "Expected keyword \"code\".");
|
fatalParserError(4846_error, "Expected keyword \"code\".");
|
||||||
@ -116,7 +115,7 @@ shared_ptr<Block> ObjectParser::parseCode(optional<SourceNameMap> _sourceNames)
|
|||||||
return parseBlock(std::move(_sourceNames));
|
return parseBlock(std::move(_sourceNames));
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<SourceNameMap> ObjectParser::tryParseSourceNameMapping() const
|
std::optional<SourceNameMap> ObjectParser::tryParseSourceNameMapping() const
|
||||||
{
|
{
|
||||||
// @use-src 0:"abc.sol", 1:"foo.sol", 2:"bar.sol"
|
// @use-src 0:"abc.sol", 1:"foo.sol", 2:"bar.sol"
|
||||||
//
|
//
|
||||||
@ -131,7 +130,7 @@ optional<SourceNameMap> ObjectParser::tryParseSourceNameMapping() const
|
|||||||
);
|
);
|
||||||
std::smatch sm;
|
std::smatch sm;
|
||||||
if (!std::regex_search(m_scanner->currentCommentLiteral(), sm, lineRE))
|
if (!std::regex_search(m_scanner->currentCommentLiteral(), sm, lineRE))
|
||||||
return nullopt;
|
return std::nullopt;
|
||||||
|
|
||||||
solAssert(sm.size() == 2, "");
|
solAssert(sm.size() == 2, "");
|
||||||
auto text = m_scanner->currentCommentLiteral().substr(static_cast<size_t>(sm.position() + sm.length()));
|
auto text = m_scanner->currentCommentLiteral().substr(static_cast<size_t>(sm.position() + sm.length()));
|
||||||
@ -152,7 +151,7 @@ optional<SourceNameMap> ObjectParser::tryParseSourceNameMapping() const
|
|||||||
break;
|
break;
|
||||||
if (scanner.next() != Token::StringLiteral)
|
if (scanner.next() != Token::StringLiteral)
|
||||||
break;
|
break;
|
||||||
sourceNames[*sourceIndex] = make_shared<string const>(scanner.currentLiteral());
|
sourceNames[*sourceIndex] = std::make_shared<std::string const>(scanner.currentLiteral());
|
||||||
|
|
||||||
Token const next = scanner.next();
|
Token const next = scanner.next();
|
||||||
if (next == Token::EOS)
|
if (next == Token::EOS)
|
||||||
@ -167,13 +166,13 @@ optional<SourceNameMap> ObjectParser::tryParseSourceNameMapping() const
|
|||||||
m_scanner->currentCommentLocation(),
|
m_scanner->currentCommentLocation(),
|
||||||
"Error parsing arguments to @use-src. Expected: <number> \":\" \"<filename>\", ..."
|
"Error parsing arguments to @use-src. Expected: <number> \":\" \"<filename>\", ..."
|
||||||
);
|
);
|
||||||
return nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Block> ObjectParser::parseBlock(optional<SourceNameMap> _sourceNames)
|
std::shared_ptr<Block> ObjectParser::parseBlock(std::optional<SourceNameMap> _sourceNames)
|
||||||
{
|
{
|
||||||
Parser parser(m_errorReporter, m_dialect, std::move(_sourceNames));
|
Parser parser(m_errorReporter, m_dialect, std::move(_sourceNames));
|
||||||
shared_ptr<Block> block = parser.parseInline(m_scanner);
|
std::shared_ptr<Block> block = parser.parseInline(m_scanner);
|
||||||
yulAssert(block || m_errorReporter.hasErrors(), "Invalid block but no error!");
|
yulAssert(block || m_errorReporter.hasErrors(), "Invalid block but no error!");
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
@ -192,7 +191,7 @@ void ObjectParser::parseData(Object& _containingObject)
|
|||||||
expectToken(Token::HexStringLiteral, false);
|
expectToken(Token::HexStringLiteral, false);
|
||||||
else
|
else
|
||||||
expectToken(Token::StringLiteral, false);
|
expectToken(Token::StringLiteral, false);
|
||||||
addNamedSubObject(_containingObject, name, make_shared<Data>(name, asBytes(currentLiteral())));
|
addNamedSubObject(_containingObject, name, std::make_shared<Data>(name, asBytes(currentLiteral())));
|
||||||
advance();
|
advance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -210,7 +209,7 @@ YulString ObjectParser::parseUniqueName(Object const* _containingObject)
|
|||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ObjectParser::addNamedSubObject(Object& _container, YulString _name, shared_ptr<ObjectNode> _subObject)
|
void ObjectParser::addNamedSubObject(Object& _container, YulString _name, std::shared_ptr<ObjectNode> _subObject)
|
||||||
{
|
{
|
||||||
_container.subIndexByName[_name] = _container.subObjects.size();
|
_container.subIndexByName[_name] = _container.subObjects.size();
|
||||||
_container.subObjects.emplace_back(std::move(_subObject));
|
_container.subObjects.emplace_back(std::move(_subObject));
|
||||||
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
#include <libyul/Scope.h>
|
#include <libyul/Scope.h>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
@ -53,7 +52,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 && holds_alternative<Scope::Variable>(id->second))
|
if (crossedFunctionBoundary && std::holds_alternative<Scope::Variable>(id->second))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
else
|
else
|
||||||
return &id->second;
|
return &id->second;
|
||||||
@ -79,7 +78,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 (holds_alternative<Scope::Variable>(identifier.second))
|
if (std::holds_alternative<Scope::Variable>(identifier.second))
|
||||||
count++;
|
count++;
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,6 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
@ -60,7 +59,7 @@ bool ScopeFiller::operator()(VariableDeclaration const& _varDecl)
|
|||||||
|
|
||||||
bool ScopeFiller::operator()(FunctionDefinition const& _funDef)
|
bool ScopeFiller::operator()(FunctionDefinition const& _funDef)
|
||||||
{
|
{
|
||||||
auto virtualBlock = m_info.virtualBlocks[&_funDef] = make_shared<Block>();
|
auto virtualBlock = m_info.virtualBlocks[&_funDef] = std::make_shared<Block>();
|
||||||
Scope& varScope = scope(virtualBlock.get());
|
Scope& varScope = scope(virtualBlock.get());
|
||||||
varScope.superScope = m_currentScope;
|
varScope.superScope = m_currentScope;
|
||||||
m_currentScope = &varScope;
|
m_currentScope = &varScope;
|
||||||
@ -123,7 +122,7 @@ 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 (holds_alternative<FunctionDefinition>(s))
|
if (std::holds_alternative<FunctionDefinition>(s))
|
||||||
if (!registerFunction(std::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)
|
||||||
@ -151,10 +150,10 @@ bool ScopeFiller::registerVariable(TypedName const& _name, SourceLocation const&
|
|||||||
|
|
||||||
bool ScopeFiller::registerFunction(FunctionDefinition const& _funDef)
|
bool ScopeFiller::registerFunction(FunctionDefinition const& _funDef)
|
||||||
{
|
{
|
||||||
vector<Scope::YulType> parameters;
|
std::vector<Scope::YulType> parameters;
|
||||||
for (auto const& parameter: _funDef.parameters)
|
for (auto const& parameter: _funDef.parameters)
|
||||||
parameters.emplace_back(parameter.type);
|
parameters.emplace_back(parameter.type);
|
||||||
vector<Scope::YulType> returns;
|
std::vector<Scope::YulType> returns;
|
||||||
for (auto const& returnVariable: _funDef.returnVariables)
|
for (auto const& returnVariable: _funDef.returnVariables)
|
||||||
returns.emplace_back(returnVariable.type);
|
returns.emplace_back(returnVariable.type);
|
||||||
if (!m_currentScope->registerFunction(_funDef.name, std::move(parameters), std::move(returns)))
|
if (!m_currentScope->registerFunction(_funDef.name, std::move(parameters), std::move(returns)))
|
||||||
@ -174,6 +173,6 @@ Scope& ScopeFiller::scope(Block const* _block)
|
|||||||
{
|
{
|
||||||
auto& scope = m_info.scopes[_block];
|
auto& scope = m_info.scopes[_block];
|
||||||
if (!scope)
|
if (!scope)
|
||||||
scope = make_shared<Scope>();
|
scope = std::make_shared<Scope>();
|
||||||
return *scope;
|
return *scope;
|
||||||
}
|
}
|
||||||
|
@ -33,16 +33,15 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
using namespace solidity::util;
|
using namespace solidity::util;
|
||||||
|
|
||||||
string solidity::yul::reindent(string const& _code)
|
std::string solidity::yul::reindent(std::string const& _code)
|
||||||
{
|
{
|
||||||
int constexpr indentationWidth = 4;
|
int constexpr indentationWidth = 4;
|
||||||
|
|
||||||
auto constexpr static countBraces = [](string const& _s) noexcept -> int
|
auto constexpr static countBraces = [](std::string const& _s) noexcept -> int
|
||||||
{
|
{
|
||||||
auto const i = _s.find("//");
|
auto const i = _s.find("//");
|
||||||
auto const e = i == _s.npos ? end(_s) : next(begin(_s), static_cast<ptrdiff_t>(i));
|
auto const e = i == _s.npos ? end(_s) : next(begin(_s), static_cast<ptrdiff_t>(i));
|
||||||
@ -51,22 +50,22 @@ string solidity::yul::reindent(string const& _code)
|
|||||||
return int(opening - closing);
|
return int(opening - closing);
|
||||||
};
|
};
|
||||||
|
|
||||||
vector<string> lines;
|
std::vector<std::string> lines;
|
||||||
boost::split(lines, _code, boost::is_any_of("\n"));
|
boost::split(lines, _code, boost::is_any_of("\n"));
|
||||||
for (string& line: lines)
|
for (std::string& line: lines)
|
||||||
boost::trim(line);
|
boost::trim(line);
|
||||||
|
|
||||||
// Reduce multiple consecutive empty lines.
|
// Reduce multiple consecutive empty lines.
|
||||||
lines = fold(lines, vector<string>{}, [](auto&& _lines, auto&& _line) {
|
lines = fold(lines, std::vector<std::string>{}, [](auto&& _lines, auto&& _line) {
|
||||||
if (!(_line.empty() && !_lines.empty() && _lines.back().empty()))
|
if (!(_line.empty() && !_lines.empty() && _lines.back().empty()))
|
||||||
_lines.emplace_back(std::move(_line));
|
_lines.emplace_back(std::move(_line));
|
||||||
return std::move(_lines);
|
return std::move(_lines);
|
||||||
});
|
});
|
||||||
|
|
||||||
stringstream out;
|
std::stringstream out;
|
||||||
int depth = 0;
|
int depth = 0;
|
||||||
|
|
||||||
for (string const& line: lines)
|
for (std::string const& line: lines)
|
||||||
{
|
{
|
||||||
int const diff = countBraces(line);
|
int const diff = countBraces(line);
|
||||||
if (diff < 0)
|
if (diff < 0)
|
||||||
@ -91,7 +90,7 @@ u256 solidity::yul::valueOfNumberLiteral(Literal const& _literal)
|
|||||||
{
|
{
|
||||||
yulAssert(_literal.kind == LiteralKind::Number, "Expected number literal!");
|
yulAssert(_literal.kind == LiteralKind::Number, "Expected number literal!");
|
||||||
|
|
||||||
static map<YulString, u256> numberCache;
|
static std::map<YulString, u256> numberCache;
|
||||||
static YulStringRepository::ResetCallback callback{[&] { numberCache.clear(); }};
|
static YulStringRepository::ResetCallback callback{[&] { numberCache.clear(); }};
|
||||||
|
|
||||||
auto&& [it, isNew] = numberCache.try_emplace(_literal.value, 0);
|
auto&& [it, isNew] = numberCache.try_emplace(_literal.value, 0);
|
||||||
|
@ -39,7 +39,6 @@
|
|||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
using namespace std;
|
|
||||||
using namespace solidity;
|
using namespace solidity;
|
||||||
using namespace solidity::yul;
|
using namespace solidity::yul;
|
||||||
using namespace solidity::langutil;
|
using namespace solidity::langutil;
|
||||||
@ -63,7 +62,7 @@ Dialect const& languageToDialect(YulStack::Language _language, EVMVersion _versi
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CharStream const& YulStack::charStream(string const& _sourceName) const
|
CharStream const& YulStack::charStream(std::string const& _sourceName) const
|
||||||
{
|
{
|
||||||
yulAssert(m_charStream, "");
|
yulAssert(m_charStream, "");
|
||||||
yulAssert(m_charStream->name() == _sourceName, "");
|
yulAssert(m_charStream->name() == _sourceName, "");
|
||||||
@ -74,8 +73,8 @@ bool YulStack::parseAndAnalyze(std::string const& _sourceName, std::string const
|
|||||||
{
|
{
|
||||||
m_errors.clear();
|
m_errors.clear();
|
||||||
m_analysisSuccessful = false;
|
m_analysisSuccessful = false;
|
||||||
m_charStream = make_unique<CharStream>(_source, _sourceName);
|
m_charStream = std::make_unique<CharStream>(_source, _sourceName);
|
||||||
shared_ptr<Scanner> scanner = make_shared<Scanner>(*m_charStream);
|
std::shared_ptr<Scanner> scanner = std::make_shared<Scanner>(*m_charStream);
|
||||||
m_parserResult = ObjectParser(m_errorReporter, languageToDialect(m_language, m_evmVersion)).parse(scanner, false);
|
m_parserResult = ObjectParser(m_errorReporter, languageToDialect(m_language, m_evmVersion)).parse(scanner, false);
|
||||||
if (!m_errorReporter.errors().empty())
|
if (!m_errorReporter.errors().empty())
|
||||||
return false;
|
return false;
|
||||||
@ -112,7 +111,7 @@ bool YulStack::analyzeParsed()
|
|||||||
bool YulStack::analyzeParsed(Object& _object)
|
bool YulStack::analyzeParsed(Object& _object)
|
||||||
{
|
{
|
||||||
yulAssert(_object.code, "");
|
yulAssert(_object.code, "");
|
||||||
_object.analysisInfo = make_shared<AsmAnalysisInfo>();
|
_object.analysisInfo = std::make_shared<AsmAnalysisInfo>();
|
||||||
|
|
||||||
AsmAnalyzer analyzer(
|
AsmAnalyzer analyzer(
|
||||||
*_object.analysisInfo,
|
*_object.analysisInfo,
|
||||||
@ -161,9 +160,9 @@ void YulStack::optimize(Object& _object, bool _isCreation)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Dialect const& dialect = languageToDialect(m_language, m_evmVersion);
|
Dialect const& dialect = languageToDialect(m_language, m_evmVersion);
|
||||||
unique_ptr<GasMeter> meter;
|
std::unique_ptr<GasMeter> meter;
|
||||||
if (EVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&dialect))
|
if (EVMDialect const* evmDialect = dynamic_cast<EVMDialect const*>(&dialect))
|
||||||
meter = make_unique<GasMeter>(*evmDialect, _isCreation, m_optimiserSettings.expectedExecutionsPerDeployment);
|
meter = std::make_unique<GasMeter>(*evmDialect, _isCreation, m_optimiserSettings.expectedExecutionsPerDeployment);
|
||||||
|
|
||||||
OptimiserSuite::run(
|
OptimiserSuite::run(
|
||||||
dialect,
|
dialect,
|
||||||
@ -173,7 +172,7 @@ void YulStack::optimize(Object& _object, bool _isCreation)
|
|||||||
m_optimiserSettings.runYulOptimiser ? m_optimiserSettings.optimizeStackAllocation : true,
|
m_optimiserSettings.runYulOptimiser ? m_optimiserSettings.optimizeStackAllocation : true,
|
||||||
m_optimiserSettings.runYulOptimiser ? m_optimiserSettings.yulOptimiserSteps : "u",
|
m_optimiserSettings.runYulOptimiser ? m_optimiserSettings.yulOptimiserSteps : "u",
|
||||||
m_optimiserSettings.runYulOptimiser ? m_optimiserSettings.yulOptimiserCleanupSteps : "",
|
m_optimiserSettings.runYulOptimiser ? m_optimiserSettings.yulOptimiserCleanupSteps : "",
|
||||||
_isCreation ? nullopt : make_optional(m_optimiserSettings.expectedExecutionsPerDeployment),
|
_isCreation ? std::nullopt : std::make_optional(m_optimiserSettings.expectedExecutionsPerDeployment),
|
||||||
{}
|
{}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -195,17 +194,17 @@ MachineAssemblyObject YulStack::assemble(Machine _machine) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::pair<MachineAssemblyObject, MachineAssemblyObject>
|
std::pair<MachineAssemblyObject, MachineAssemblyObject>
|
||||||
YulStack::assembleWithDeployed(optional<string_view> _deployName) const
|
YulStack::assembleWithDeployed(std::optional<std::string_view> _deployName) const
|
||||||
{
|
{
|
||||||
auto [creationAssembly, deployedAssembly] = assembleEVMWithDeployed(_deployName);
|
auto [creationAssembly, deployedAssembly] = assembleEVMWithDeployed(_deployName);
|
||||||
yulAssert(creationAssembly, "");
|
yulAssert(creationAssembly, "");
|
||||||
yulAssert(m_charStream, "");
|
yulAssert(m_charStream, "");
|
||||||
|
|
||||||
MachineAssemblyObject creationObject;
|
MachineAssemblyObject creationObject;
|
||||||
creationObject.bytecode = make_shared<evmasm::LinkerObject>(creationAssembly->assemble());
|
creationObject.bytecode = std::make_shared<evmasm::LinkerObject>(creationAssembly->assemble());
|
||||||
yulAssert(creationObject.bytecode->immutableReferences.empty(), "Leftover immutables.");
|
yulAssert(creationObject.bytecode->immutableReferences.empty(), "Leftover immutables.");
|
||||||
creationObject.assembly = creationAssembly->assemblyString(m_debugInfoSelection);
|
creationObject.assembly = creationAssembly->assemblyString(m_debugInfoSelection);
|
||||||
creationObject.sourceMappings = make_unique<string>(
|
creationObject.sourceMappings = std::make_unique<std::string>(
|
||||||
evmasm::AssemblyItem::computeSourceMapping(
|
evmasm::AssemblyItem::computeSourceMapping(
|
||||||
creationAssembly->items(),
|
creationAssembly->items(),
|
||||||
{{m_charStream->name(), 0}}
|
{{m_charStream->name(), 0}}
|
||||||
@ -215,9 +214,9 @@ YulStack::assembleWithDeployed(optional<string_view> _deployName) const
|
|||||||
MachineAssemblyObject deployedObject;
|
MachineAssemblyObject deployedObject;
|
||||||
if (deployedAssembly)
|
if (deployedAssembly)
|
||||||
{
|
{
|
||||||
deployedObject.bytecode = make_shared<evmasm::LinkerObject>(deployedAssembly->assemble());
|
deployedObject.bytecode = std::make_shared<evmasm::LinkerObject>(deployedAssembly->assemble());
|
||||||
deployedObject.assembly = deployedAssembly->assemblyString(m_debugInfoSelection);
|
deployedObject.assembly = deployedAssembly->assemblyString(m_debugInfoSelection);
|
||||||
deployedObject.sourceMappings = make_unique<string>(
|
deployedObject.sourceMappings = std::make_unique<std::string>(
|
||||||
evmasm::AssemblyItem::computeSourceMapping(
|
evmasm::AssemblyItem::computeSourceMapping(
|
||||||
deployedAssembly->items(),
|
deployedAssembly->items(),
|
||||||
{{m_charStream->name(), 0}}
|
{{m_charStream->name(), 0}}
|
||||||
@ -229,7 +228,7 @@ YulStack::assembleWithDeployed(optional<string_view> _deployName) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::pair<std::shared_ptr<evmasm::Assembly>, std::shared_ptr<evmasm::Assembly>>
|
std::pair<std::shared_ptr<evmasm::Assembly>, std::shared_ptr<evmasm::Assembly>>
|
||||||
YulStack::assembleEVMWithDeployed(optional<string_view> _deployName) const
|
YulStack::assembleEVMWithDeployed(std::optional<std::string_view> _deployName) const
|
||||||
{
|
{
|
||||||
yulAssert(m_analysisSuccessful, "");
|
yulAssert(m_analysisSuccessful, "");
|
||||||
yulAssert(m_parserResult, "");
|
yulAssert(m_parserResult, "");
|
||||||
@ -250,7 +249,7 @@ YulStack::assembleEVMWithDeployed(optional<string_view> _deployName) const
|
|||||||
|
|
||||||
assembly.optimise(evmasm::Assembly::OptimiserSettings::translateSettings(m_optimiserSettings, m_evmVersion));
|
assembly.optimise(evmasm::Assembly::OptimiserSettings::translateSettings(m_optimiserSettings, m_evmVersion));
|
||||||
|
|
||||||
optional<size_t> subIndex;
|
std::optional<size_t> subIndex;
|
||||||
|
|
||||||
// Pick matching assembly if name was given
|
// Pick matching assembly if name was given
|
||||||
if (_deployName.has_value())
|
if (_deployName.has_value())
|
||||||
@ -271,13 +270,13 @@ YulStack::assembleEVMWithDeployed(optional<string_view> _deployName) const
|
|||||||
if (subIndex.has_value())
|
if (subIndex.has_value())
|
||||||
{
|
{
|
||||||
evmasm::Assembly& runtimeAssembly = assembly.sub(*subIndex);
|
evmasm::Assembly& runtimeAssembly = assembly.sub(*subIndex);
|
||||||
return {make_shared<evmasm::Assembly>(assembly), make_shared<evmasm::Assembly>(runtimeAssembly)};
|
return {std::make_shared<evmasm::Assembly>(assembly), std::make_shared<evmasm::Assembly>(runtimeAssembly)};
|
||||||
}
|
}
|
||||||
|
|
||||||
return {make_shared<evmasm::Assembly>(assembly), {}};
|
return {std::make_shared<evmasm::Assembly>(assembly), {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
string YulStack::print(
|
std::string YulStack::print(
|
||||||
CharStreamProvider const* _soliditySourceProvider
|
CharStreamProvider const* _soliditySourceProvider
|
||||||
) const
|
) const
|
||||||
{
|
{
|
||||||
@ -293,7 +292,7 @@ Json::Value YulStack::astJson() const
|
|||||||
return m_parserResult->toJson();
|
return m_parserResult->toJson();
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<Object> YulStack::parserResult() const
|
std::shared_ptr<Object> YulStack::parserResult() const
|
||||||
{
|
{
|
||||||
yulAssert(m_analysisSuccessful, "Analysis was not successful.");
|
yulAssert(m_analysisSuccessful, "Analysis was not successful.");
|
||||||
yulAssert(m_parserResult, "");
|
yulAssert(m_parserResult, "");
|
||||||
|
@ -34,6 +34,7 @@ NAMESPACE_STD_FREE_FILES=(
|
|||||||
libsolidity/lsp/*
|
libsolidity/lsp/*
|
||||||
libsolidity/parsing/*
|
libsolidity/parsing/*
|
||||||
libsolutil/*
|
libsolutil/*
|
||||||
|
libyul/*
|
||||||
libyul/backends/evm/*
|
libyul/backends/evm/*
|
||||||
libyul/optimiser/*
|
libyul/optimiser/*
|
||||||
solc/*
|
solc/*
|
||||||
|
Loading…
Reference in New Issue
Block a user