Refactoring yul source locations.

This commit is contained in:
Djordje Mijovic 2021-04-27 16:53:04 +02:00
parent fe4822a1d2
commit e404b6e7a6
62 changed files with 394 additions and 358 deletions

View File

@ -482,7 +482,7 @@ void ControlFlowBuilder::operator()(yul::Identifier const& _identifier)
m_currentNode->variableOccurrences.emplace_back(
*declaration,
VariableOccurrence::Kind::Access,
_identifier.location
_identifier.debugData->location
);
}
}
@ -498,7 +498,7 @@ void ControlFlowBuilder::operator()(yul::Assignment const& _assignment)
m_currentNode->variableOccurrences.emplace_back(
*declaration,
VariableOccurrence::Kind::Assignment,
variable.location
variable.debugData->location
);
}

View File

@ -201,9 +201,9 @@ bool ReferencesResolver::visit(Return const& _return)
void ReferencesResolver::operator()(yul::FunctionDefinition const& _function)
{
validateYulIdentifierName(_function.name, _function.location);
validateYulIdentifierName(_function.name, _function.debugData->location);
for (yul::TypedName const& varName: _function.parameters + _function.returnVariables)
validateYulIdentifierName(varName.name, varName.location);
validateYulIdentifierName(varName.name, varName.debugData->location);
bool wasInsideFunction = m_yulInsideFunction;
m_yulInsideFunction = true;
@ -238,7 +238,7 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
{
m_errorReporter.declarationError(
4718_error,
_identifier.location,
_identifier.debugData->location,
"Multiple matching identifiers. Resolving overloaded identifiers is not supported."
);
return;
@ -251,7 +251,7 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
)
m_errorReporter.declarationError(
9467_error,
_identifier.location,
_identifier.debugData->location,
"Identifier not found. Use \".slot\" and \".offset\" to access storage variables."
);
return;
@ -261,7 +261,7 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
{
m_errorReporter.declarationError(
6578_error,
_identifier.location,
_identifier.debugData->location,
"Cannot access local Solidity variables from inside an inline assembly function."
);
return;
@ -275,7 +275,7 @@ void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)
{
for (auto const& identifier: _varDecl.variables)
{
validateYulIdentifierName(identifier.name, identifier.location);
validateYulIdentifierName(identifier.name, identifier.debugData->location);
if (
@ -289,7 +289,7 @@ void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)
if (!ssl.infos.empty())
m_errorReporter.declarationError(
3859_error,
identifier.location,
identifier.debugData->location,
ssl,
"This declaration shadows a declaration outside the inline assembly block."
);

View File

@ -743,7 +743,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
solAssert(var->type(), "Expected variable type!");
if (var->immutable())
{
m_errorReporter.typeError(3773_error, _identifier.location, "Assembly access to immutable variables is not supported.");
m_errorReporter.typeError(3773_error, _identifier.debugData->location, "Assembly access to immutable variables is not supported.");
return false;
}
if (var->isConstant())
@ -752,7 +752,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{
m_errorReporter.typeError(
3558_error,
_identifier.location,
_identifier.debugData->location,
"Constant variable is circular."
);
return false;
@ -762,24 +762,24 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
if (var && !var->value())
{
m_errorReporter.typeError(3224_error, _identifier.location, "Constant has no value.");
m_errorReporter.typeError(3224_error, _identifier.debugData->location, "Constant has no value.");
return false;
}
else if (_context == yul::IdentifierContext::LValue)
{
m_errorReporter.typeError(6252_error, _identifier.location, "Constant variables cannot be assigned to.");
m_errorReporter.typeError(6252_error, _identifier.debugData->location, "Constant variables cannot be assigned to.");
return false;
}
else if (!identifierInfo.suffix.empty())
{
m_errorReporter.typeError(6617_error, _identifier.location, "The suffixes .offset and .slot can only be used on non-constant storage variables.");
m_errorReporter.typeError(6617_error, _identifier.debugData->location, "The suffixes .offset and .slot can only be used on non-constant storage variables.");
return false;
}
else if (var && var->value() && !var->value()->annotation().type && !dynamic_cast<Literal const*>(var->value().get()))
{
m_errorReporter.typeError(
2249_error,
_identifier.location,
_identifier.debugData->location,
"Constant variables with non-literal values cannot be forward referenced from inline assembly."
);
return false;
@ -789,7 +789,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
type(*var->value())->category() != Type::Category::RationalNumber
))
{
m_errorReporter.typeError(7615_error, _identifier.location, "Only direct number constants and references to such constants are supported by inline assembly.");
m_errorReporter.typeError(7615_error, _identifier.debugData->location, "Only direct number constants and references to such constants are supported by inline assembly.");
return false;
}
}
@ -804,19 +804,19 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{
if (suffix != "slot" && suffix != "offset")
{
m_errorReporter.typeError(4656_error, _identifier.location, "State variables only support \".slot\" and \".offset\".");
m_errorReporter.typeError(4656_error, _identifier.debugData->location, "State variables only support \".slot\" and \".offset\".");
return false;
}
else if (_context == yul::IdentifierContext::LValue)
{
if (var->isStateVariable())
{
m_errorReporter.typeError(4713_error, _identifier.location, "State variables cannot be assigned to - you have to use \"sstore()\".");
m_errorReporter.typeError(4713_error, _identifier.debugData->location, "State variables cannot be assigned to - you have to use \"sstore()\".");
return false;
}
else if (suffix != "slot")
{
m_errorReporter.typeError(9739_error, _identifier.location, "Only .slot can be assigned to.");
m_errorReporter.typeError(9739_error, _identifier.debugData->location, "Only .slot can be assigned to.");
return false;
}
}
@ -828,13 +828,13 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{
if (suffix != "offset" && suffix != "length")
{
m_errorReporter.typeError(1536_error, _identifier.location, "Calldata variables only support \".offset\" and \".length\".");
m_errorReporter.typeError(1536_error, _identifier.debugData->location, "Calldata variables only support \".offset\" and \".length\".");
return false;
}
}
else
{
m_errorReporter.typeError(3622_error, _identifier.location, "The suffix \"." + suffix + "\" is not supported by this variable or type.");
m_errorReporter.typeError(3622_error, _identifier.debugData->location, "The suffix \"." + suffix + "\" is not supported by this variable or type.");
return false;
}
}
@ -842,14 +842,14 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{
m_errorReporter.typeError(
1408_error,
_identifier.location,
_identifier.debugData->location,
"Only local variables are supported. To access storage variables, use the \".slot\" and \".offset\" suffixes."
);
return false;
}
else if (var->type()->dataStoredIn(DataLocation::Storage))
{
m_errorReporter.typeError(9068_error, _identifier.location, "You have to use the \".slot\" or \".offset\" suffix to access storage reference variables.");
m_errorReporter.typeError(9068_error, _identifier.debugData->location, "You have to use the \".slot\" or \".offset\" suffix to access storage reference variables.");
return false;
}
else if (var->type()->sizeOnStack() != 1)
@ -858,18 +858,18 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
auto const* arrayType = dynamic_cast<ArrayType const*>(var->type());
arrayType && arrayType->isDynamicallySized() && arrayType->dataStoredIn(DataLocation::CallData)
)
m_errorReporter.typeError(1397_error, _identifier.location, "Call data elements cannot be accessed directly. Use \".offset\" and \".length\" to access the calldata offset and length of this array and then use \"calldatacopy\".");
m_errorReporter.typeError(1397_error, _identifier.debugData->location, "Call data elements cannot be accessed directly. Use \".offset\" and \".length\" to access the calldata offset and length of this array and then use \"calldatacopy\".");
else
{
solAssert(!var->type()->dataStoredIn(DataLocation::CallData), "");
m_errorReporter.typeError(9857_error, _identifier.location, "Only types that use one stack slot are supported.");
m_errorReporter.typeError(9857_error, _identifier.debugData->location, "Only types that use one stack slot are supported.");
}
return false;
}
}
else if (!identifierInfo.suffix.empty())
{
m_errorReporter.typeError(7944_error, _identifier.location, "The suffixes \".offset\", \".slot\" and \".length\" can only be used with variables.");
m_errorReporter.typeError(7944_error, _identifier.debugData->location, "The suffixes \".offset\", \".slot\" and \".length\" can only be used with variables.");
return false;
}
else if (_context == yul::IdentifierContext::LValue)
@ -877,7 +877,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
if (dynamic_cast<MagicVariableDeclaration const*>(declaration))
return false;
m_errorReporter.typeError(1990_error, _identifier.location, "Only local variables can be assigned to in inline assembly.");
m_errorReporter.typeError(1990_error, _identifier.debugData->location, "Only local variables can be assigned to in inline assembly.");
return false;
}
@ -886,7 +886,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
solAssert(!!declaration->type(), "Type of declaration required but not yet determined.");
if (dynamic_cast<FunctionDefinition const*>(declaration))
{
m_errorReporter.declarationError(2025_error, _identifier.location, "Access to functions is not allowed in inline assembly.");
m_errorReporter.declarationError(2025_error, _identifier.debugData->location, "Access to functions is not allowed in inline assembly.");
return false;
}
else if (dynamic_cast<VariableDeclaration const*>(declaration))
@ -896,7 +896,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{
if (!contract->isLibrary())
{
m_errorReporter.typeError(4977_error, _identifier.location, "Expected a library.");
m_errorReporter.typeError(4977_error, _identifier.debugData->location, "Expected a library.");
return false;
}
}

View File

@ -69,7 +69,7 @@ public:
if (yul::EVMDialect const* dialect = dynamic_cast<decltype(dialect)>(&m_dialect))
if (yul::BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name))
if (fun->instruction)
checkInstruction(_funCall.location, *fun->instruction);
checkInstruction(_funCall.debugData->location, *fun->instruction);
for (auto const& arg: _funCall.arguments)
std::visit(*this, arg);

View File

@ -175,7 +175,7 @@ void ASTJsonConverter::appendExpressionAttributes(
Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair<yul::Identifier const* ,InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const
{
Json::Value tuple(Json::objectValue);
tuple["src"] = sourceLocationToString(_info.first->location);
tuple["src"] = sourceLocationToString(_info.first->debugData->location);
tuple["declaration"] = idOrNull(_info.second.declaration);
tuple["isSlot"] = Json::Value(_info.second.suffix == "slot");
tuple["isOffset"] = Json::Value(_info.second.suffix == "offset");

View File

@ -24,12 +24,10 @@
#include <libsolidity/ast/ASTJsonImporter.h>
#include <libyul/AsmJsonImporter.h>
#include <libyul/AsmParser.h>
#include <libyul/AST.h>
#include <libyul/Dialect.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <liblangutil/ErrorReporter.h>
#include <liblangutil/Exceptions.h>
#include <liblangutil/Scanner.h>
#include <liblangutil/SourceLocation.h>

View File

@ -28,11 +28,11 @@
#include <libsolidity/codegen/CompilerUtils.h>
#include <libsolidity/interface/Version.h>
#include <libyul/AST.h>
#include <libyul/AsmParser.h>
#include <libyul/AsmPrinter.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/AsmAnalysisInfo.h>
#include <libyul/AST.h>
#include <libyul/backends/evm/AsmCodeGen.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <libyul/backends/evm/EVMMetrics.h>
@ -426,7 +426,7 @@ void CompilerContext::appendInlineAssembly(
if (stackDiff < 1 || stackDiff > 16)
BOOST_THROW_EXCEPTION(
StackTooDeepError() <<
errinfo_sourceLocation(_identifier.location) <<
errinfo_sourceLocation(_identifier.debugData->location) <<
util::errinfo_comment("Stack too deep (" + to_string(stackDiff) + "), try removing local variables.")
);
if (_context == yul::IdentifierContext::RValue)

View File

@ -192,9 +192,9 @@ private:
solAssert(false, "");
if (isdigit(value.front()))
return yul::Literal{_identifier.location, yul::LiteralKind::Number, yul::YulString{value}, {}};
return yul::Literal{_identifier.debugData, yul::LiteralKind::Number, yul::YulString{value}, {}};
else
return yul::Identifier{_identifier.location, yul::YulString{value}};
return yul::Identifier{_identifier.debugData, yul::YulString{value}};
}

View File

@ -61,8 +61,8 @@
#include <libyul/AsmPrinter.h>
#include <libyul/AsmJsonConverter.h>
#include <libyul/AssemblyStack.h>
#include <libyul/AsmParser.h>
#include <libyul/AST.h>
#include <libyul/AsmParser.h>
#include <liblangutil/Scanner.h>
#include <liblangutil/SemVerHandler.h>

View File

@ -24,8 +24,8 @@
#include <libsolidity/parsing/Parser.h>
#include <libsolidity/interface/Version.h>
#include <libyul/AsmParser.h>
#include <libyul/AST.h>
#include <libyul/AsmParser.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <liblangutil/ErrorReporter.h>
#include <liblangutil/Scanner.h>
@ -1299,7 +1299,7 @@ ASTPointer<InlineAssembly> Parser::parseInlineAssembly(ASTPointer<ASTString> con
if (block == nullptr)
BOOST_THROW_EXCEPTION(FatalError());
location.end = block->location.end;
location.end = block->debugData->location.end;
return make_shared<InlineAssembly>(nextID(), location, _docString, dialect, block);
}

View File

@ -35,56 +35,80 @@ namespace solidity::yul
using Type = YulString;
struct TypedName { langutil::SourceLocation location; YulString name; Type type; };
struct DebugData
{
explicit DebugData(langutil::SourceLocation _location): location(std::move(_location)) {}
langutil::SourceLocation location;
static std::shared_ptr<DebugData const> create(langutil::SourceLocation _location = {})
{
return std::make_shared<DebugData const>(_location);
}
};
struct TypedName { std::shared_ptr<DebugData const> debugData; YulString name; Type type; };
using TypedNameList = std::vector<TypedName>;
/// Literal number or string (up to 32 bytes)
enum class LiteralKind { Number, Boolean, String };
struct Literal { langutil::SourceLocation location; LiteralKind kind; YulString value; Type type; };
struct Literal { std::shared_ptr<DebugData const> debugData; LiteralKind kind; YulString value; Type type; };
/// External / internal identifier or label reference
struct Identifier { langutil::SourceLocation location; YulString name; };
struct Identifier { std::shared_ptr<DebugData const> debugData; YulString name; };
/// Assignment ("x := mload(20:u256)", expects push-1-expression on the right hand
/// side and requires x to occupy exactly one stack slot.
///
/// Multiple assignment ("x, y := f()"), where the left hand side variables each occupy
/// a single stack slot and expects a single expression on the right hand returning
/// the same amount of items as the number of variables.
struct Assignment { langutil::SourceLocation location; std::vector<Identifier> variableNames; std::unique_ptr<Expression> value; };
struct FunctionCall { langutil::SourceLocation location; Identifier functionName; std::vector<Expression> arguments; };
struct Assignment { std::shared_ptr<DebugData const> debugData; std::vector<Identifier> variableNames; std::unique_ptr<Expression> value; };
struct FunctionCall { std::shared_ptr<DebugData const> debugData; Identifier functionName; std::vector<Expression> arguments; };
/// Statement that contains only a single expression
struct ExpressionStatement { langutil::SourceLocation location; Expression expression; };
struct ExpressionStatement { std::shared_ptr<DebugData const> debugData; Expression expression; };
/// Block-scope variable declaration ("let x:u256 := mload(20:u256)"), non-hoisted
struct VariableDeclaration { langutil::SourceLocation location; TypedNameList variables; std::unique_ptr<Expression> value; };
struct VariableDeclaration { std::shared_ptr<DebugData const> debugData; TypedNameList variables; std::unique_ptr<Expression> value; };
/// Block that creates a scope (frees declared stack variables)
struct Block { langutil::SourceLocation location; std::vector<Statement> statements; };
struct Block { std::shared_ptr<DebugData const> debugData; std::vector<Statement> statements; };
/// Function definition ("function f(a, b) -> (d, e) { ... }")
struct FunctionDefinition { langutil::SourceLocation location; YulString name; TypedNameList parameters; TypedNameList returnVariables; Block body; };
struct FunctionDefinition { std::shared_ptr<DebugData const> debugData; YulString name; TypedNameList parameters; TypedNameList returnVariables; Block body; };
/// Conditional execution without "else" part.
struct If { langutil::SourceLocation location; std::unique_ptr<Expression> condition; Block body; };
struct If { std::shared_ptr<DebugData const> debugData; std::unique_ptr<Expression> condition; Block body; };
/// Switch case or default case
struct Case { langutil::SourceLocation location; std::unique_ptr<Literal> value; Block body; };
struct Case { std::shared_ptr<DebugData const> debugData; std::unique_ptr<Literal> value; Block body; };
/// Switch statement
struct Switch { langutil::SourceLocation location; std::unique_ptr<Expression> expression; std::vector<Case> cases; };
struct ForLoop { langutil::SourceLocation location; Block pre; std::unique_ptr<Expression> condition; Block post; Block body; };
struct Switch { std::shared_ptr<DebugData const> debugData; std::unique_ptr<Expression> expression; std::vector<Case> cases; };
struct ForLoop { std::shared_ptr<DebugData const> debugData; Block pre; std::unique_ptr<Expression> condition; Block post; Block body; };
/// Break statement (valid within for loop)
struct Break { langutil::SourceLocation location; };
struct Break { std::shared_ptr<DebugData const> debugData; };
/// Continue statement (valid within for loop)
struct Continue { langutil::SourceLocation location; };
struct Continue { std::shared_ptr<DebugData const> debugData; };
/// Leave statement (valid within function)
struct Leave { langutil::SourceLocation location; };
struct Leave { std::shared_ptr<DebugData const> debugData; };
struct LocationExtractor
{
template <class T> langutil::SourceLocation operator()(T const& _node) const
{
return _node.location;
return _node.debugData ? _node.debugData->location : langutil::SourceLocation{};
}
};
/// Extracts the source location from an inline assembly node.
/// Extracts the source location from a Yul node.
template <class T> inline langutil::SourceLocation locationOf(T const& _node)
{
return std::visit(LocationExtractor(), _node);
}
struct DebugDataExtractor
{
template <class T> std::shared_ptr<DebugData const> const& operator()(T const& _node) const
{
return _node.debugData;
}
};
/// Extracts the debug data from a Yul node.
template <class T> inline std::shared_ptr<DebugData const> const& debugDataOf(T const& _node)
{
return std::visit(DebugDataExtractor(), _node);
}
}

View File

@ -28,6 +28,7 @@
namespace solidity::yul
{
struct DebugData;
enum class LiteralKind;
struct Literal;
struct Label;

View File

@ -98,22 +98,22 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect,
vector<YulString> AsmAnalyzer::operator()(Literal const& _literal)
{
expectValidType(_literal.type, _literal.location);
expectValidType(_literal.type, _literal.debugData->location);
if (_literal.kind == LiteralKind::String && _literal.value.str().size() > 32)
m_errorReporter.typeError(
3069_error,
_literal.location,
_literal.debugData->location,
"String literal too long (" + to_string(_literal.value.str().size()) + " > 32)"
);
else if (_literal.kind == LiteralKind::Number && bigint(_literal.value.str()) > u256(-1))
m_errorReporter.typeError(6708_error, _literal.location, "Number literal too large (> 256 bits)");
m_errorReporter.typeError(6708_error, _literal.debugData->location, "Number literal too large (> 256 bits)");
else if (_literal.kind == LiteralKind::Boolean)
yulAssert(_literal.value == "true"_yulstring || _literal.value == "false"_yulstring, "");
if (!m_dialect.validTypeForLiteral(_literal.kind, _literal.value, _literal.type))
m_errorReporter.typeError(
5170_error,
_literal.location,
_literal.debugData->location,
"Invalid type \"" + _literal.type.str() + "\" for literal \"" + _literal.value.str() + "\"."
);
@ -133,7 +133,7 @@ vector<YulString> AsmAnalyzer::operator()(Identifier const& _identifier)
if (!m_activeVariables.count(&_var))
m_errorReporter.declarationError(
4990_error,
_identifier.location,
_identifier.debugData->location,
"Variable " + _identifier.name.str() + " used before it was declared."
);
type = _var.type;
@ -142,7 +142,7 @@ vector<YulString> AsmAnalyzer::operator()(Identifier const& _identifier)
{
m_errorReporter.typeError(
6041_error,
_identifier.location,
_identifier.debugData->location,
"Function " + _identifier.name.str() + " used without being called."
);
}
@ -160,7 +160,7 @@ vector<YulString> AsmAnalyzer::operator()(Identifier const& _identifier)
// Only add an error message if the callback did not do it.
m_errorReporter.declarationError(
8198_error,
_identifier.location,
_identifier.debugData->location,
"Identifier \"" + _identifier.name.str() + "\" not found."
);
@ -176,7 +176,7 @@ void AsmAnalyzer::operator()(ExpressionStatement const& _statement)
if (watcher.ok() && !types.empty())
m_errorReporter.typeError(
3083_error,
_statement.location,
_statement.debugData->location,
"Top-level expressions are not supposed to return values (this expression returns " +
to_string(types.size()) +
" value" +
@ -196,7 +196,7 @@ void AsmAnalyzer::operator()(Assignment const& _assignment)
if (!variables.insert(_variableName.name).second)
m_errorReporter.declarationError(
9005_error,
_assignment.location,
_assignment.debugData->location,
"Variable " +
_variableName.name.str() +
" occurs multiple times on the left-hand side of the assignment."
@ -207,7 +207,7 @@ void AsmAnalyzer::operator()(Assignment const& _assignment)
if (types.size() != numVariables)
m_errorReporter.declarationError(
8678_error,
_assignment.location,
_assignment.debugData->location,
"Variable count for assignment to \"" +
joinHumanReadable(applyMap(_assignment.variableNames, [](auto const& _identifier){ return _identifier.name.str(); })) +
"\" does not match number of values (" +
@ -229,14 +229,14 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
for (auto const& variable: _varDecl.variables)
// Call the resolver for variable declarations to allow it to raise errors on shadowing.
m_resolver(
yul::Identifier{variable.location, variable.name},
yul::Identifier{variable.debugData, variable.name},
yul::IdentifierContext::VariableDeclaration,
m_currentScope->insideFunction()
);
for (auto const& variable: _varDecl.variables)
{
expectValidIdentifier(variable.name, variable.location);
expectValidType(variable.type, variable.location);
expectValidIdentifier(variable.name, variable.debugData->location);
expectValidType(variable.type, variable.debugData->location);
}
if (_varDecl.value)
@ -245,7 +245,7 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
if (types.size() != numVariables)
m_errorReporter.declarationError(
3812_error,
_varDecl.location,
_varDecl.debugData->location,
"Variable count mismatch for declaration of \"" +
joinHumanReadable(applyMap(_varDecl.variables, [](auto const& _identifier){ return _identifier.name.str(); })) +
+ "\": " +
@ -264,7 +264,7 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
if (variable.type != givenType)
m_errorReporter.typeError(
3947_error,
variable.location,
variable.debugData->location,
"Assigning value of type \"" + givenType.str() + "\" to variable of type \"" + variable.type.str() + "\"."
);
}
@ -279,14 +279,14 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
void AsmAnalyzer::operator()(FunctionDefinition const& _funDef)
{
yulAssert(!_funDef.name.empty(), "");
expectValidIdentifier(_funDef.name, _funDef.location);
expectValidIdentifier(_funDef.name, _funDef.debugData->location);
Block const* virtualBlock = m_info.virtualBlocks.at(&_funDef).get();
yulAssert(virtualBlock, "");
Scope& varScope = scope(virtualBlock);
for (auto const& var: _funDef.parameters + _funDef.returnVariables)
{
expectValidIdentifier(var.name, var.location);
expectValidType(var.type, var.location);
expectValidIdentifier(var.name, var.debugData->location);
expectValidType(var.type, var.debugData->location);
m_activeVariables.insert(&std::get<Scope::Variable>(varScope.identifiers.at(var.name)));
}
@ -315,7 +315,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
{
m_errorReporter.typeError(
4202_error,
_funCall.functionName.location,
_funCall.functionName.debugData->location,
"Attempt to call variable instead of function."
);
},
@ -329,7 +329,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
if (!validateInstructions(_funCall))
m_errorReporter.declarationError(
4619_error,
_funCall.functionName.location,
_funCall.functionName.debugData->location,
"Function \"" + _funCall.functionName.name.str() + "\" not found."
);
yulAssert(!watcher.ok(), "Expected a reported error.");
@ -338,7 +338,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
if (parameterTypes && _funCall.arguments.size() != parameterTypes->size())
m_errorReporter.typeError(
7000_error,
_funCall.functionName.location,
_funCall.functionName.debugData->location,
"Function \"" + _funCall.functionName.name.str() + "\" expects " +
to_string(parameterTypes->size()) +
" arguments but got " +
@ -358,13 +358,13 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
if (!holds_alternative<Literal>(arg))
m_errorReporter.typeError(
9114_error,
_funCall.functionName.location,
_funCall.functionName.debugData->location,
"Function expects direct literals as arguments."
);
else if (*literalArgumentKind != get<Literal>(arg).kind)
m_errorReporter.typeError(
5859_error,
get<Literal>(arg).location,
get<Literal>(arg).debugData->location,
"Function expects " + to_string(*literalArgumentKind) + " literal."
);
else if (*literalArgumentKind == LiteralKind::String)
@ -375,7 +375,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
if (!m_dataNames.count(get<Literal>(arg).value))
m_errorReporter.typeError(
3517_error,
get<Literal>(arg).location,
get<Literal>(arg).debugData->location,
"Unknown data object \"" + std::get<Literal>(arg).value.str() + "\"."
);
}
@ -384,7 +384,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
if (get<Literal>(arg).value.empty())
m_errorReporter.typeError(
1844_error,
get<Literal>(arg).location,
get<Literal>(arg).debugData->location,
"The \"verbatim_*\" builtins cannot be used with empty bytecode."
);
}
@ -427,7 +427,7 @@ void AsmAnalyzer::operator()(Switch const& _switch)
if (_switch.cases.size() == 1 && !_switch.cases[0].value)
m_errorReporter.warning(
9592_error,
_switch.location,
_switch.debugData->location,
"\"switch\" statement with only a default case."
);
@ -440,7 +440,7 @@ void AsmAnalyzer::operator()(Switch const& _switch)
{
auto watcher = m_errorReporter.errorWatcher();
expectType(valueType, _case.value->type, _case.value->location);
expectType(valueType, _case.value->type, _case.value->debugData->location);
// We cannot use "expectExpression" here because *_case.value is not an
// Expression and would be converted to an Expression otherwise.
@ -450,7 +450,7 @@ void AsmAnalyzer::operator()(Switch const& _switch)
if (watcher.ok() && !cases.insert(valueOfLiteral(*_case.value)).second)
m_errorReporter.declarationError(
6792_error,
_case.location,
_case.debugData->location,
"Duplicate case \"" +
valueOfLiteral(*_case.value).str() +
"\" defined."
@ -542,11 +542,11 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulString _valueT
if (Scope::Identifier const* var = m_currentScope->lookup(_variable.name))
{
if (!holds_alternative<Scope::Variable>(*var))
m_errorReporter.typeError(2657_error, _variable.location, "Assignment requires variable.");
m_errorReporter.typeError(2657_error, _variable.debugData->location, "Assignment requires variable.");
else if (!m_activeVariables.count(&std::get<Scope::Variable>(*var)))
m_errorReporter.declarationError(
1133_error,
_variable.location,
_variable.debugData->location,
"Variable " + _variable.name.str() + " used before it was declared."
);
else
@ -565,11 +565,11 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulString _valueT
if (!found && watcher.ok())
// Only add message if the callback did not.
m_errorReporter.declarationError(4634_error, _variable.location, "Variable not found or variable not lvalue.");
m_errorReporter.declarationError(4634_error, _variable.debugData->location, "Variable not found or variable not lvalue.");
if (variableType && *variableType != _valueType)
m_errorReporter.typeError(
9547_error,
_variable.location,
_variable.debugData->location,
"Assigning a value of type \"" +
_valueType.str() +
"\" to a variable of type \"" +
@ -713,5 +713,5 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio
bool AsmAnalyzer::validateInstructions(FunctionCall const& _functionCall)
{
return validateInstructions(_functionCall.functionName.name.str(), _functionCall.functionName.location);
return validateInstructions(_functionCall.functionName.name.str(), _functionCall.functionName.debugData->location);
}

View File

@ -32,7 +32,7 @@ namespace solidity::yul
Json::Value AsmJsonConverter::operator()(Block const& _node) const
{
Json::Value ret = createAstNode(_node.location, "YulBlock");
Json::Value ret = createAstNode(_node.debugData->location, "YulBlock");
ret["statements"] = vectorOfVariantsToJson(_node.statements);
return ret;
}
@ -40,7 +40,7 @@ Json::Value AsmJsonConverter::operator()(Block const& _node) const
Json::Value AsmJsonConverter::operator()(TypedName const& _node) const
{
yulAssert(!_node.name.empty(), "Invalid variable name.");
Json::Value ret = createAstNode(_node.location, "YulTypedName");
Json::Value ret = createAstNode(_node.debugData->location, "YulTypedName");
ret["name"] = _node.name.str();
ret["type"] = _node.type.str();
return ret;
@ -48,7 +48,7 @@ Json::Value AsmJsonConverter::operator()(TypedName const& _node) const
Json::Value AsmJsonConverter::operator()(Literal const& _node) const
{
Json::Value ret = createAstNode(_node.location, "YulLiteral");
Json::Value ret = createAstNode(_node.debugData->location, "YulLiteral");
switch (_node.kind)
{
case LiteralKind::Number:
@ -73,7 +73,7 @@ Json::Value AsmJsonConverter::operator()(Literal const& _node) const
Json::Value AsmJsonConverter::operator()(Identifier const& _node) const
{
yulAssert(!_node.name.empty(), "Invalid identifier");
Json::Value ret = createAstNode(_node.location, "YulIdentifier");
Json::Value ret = createAstNode(_node.debugData->location, "YulIdentifier");
ret["name"] = _node.name.str();
return ret;
}
@ -81,7 +81,7 @@ Json::Value AsmJsonConverter::operator()(Identifier const& _node) const
Json::Value AsmJsonConverter::operator()(Assignment const& _node) const
{
yulAssert(_node.variableNames.size() >= 1, "Invalid assignment syntax");
Json::Value ret = createAstNode(_node.location, "YulAssignment");
Json::Value ret = createAstNode(_node.debugData->location, "YulAssignment");
for (auto const& var: _node.variableNames)
ret["variableNames"].append((*this)(var));
ret["value"] = _node.value ? std::visit(*this, *_node.value) : Json::nullValue;
@ -90,7 +90,7 @@ Json::Value AsmJsonConverter::operator()(Assignment const& _node) const
Json::Value AsmJsonConverter::operator()(FunctionCall const& _node) const
{
Json::Value ret = createAstNode(_node.location, "YulFunctionCall");
Json::Value ret = createAstNode(_node.debugData->location, "YulFunctionCall");
ret["functionName"] = (*this)(_node.functionName);
ret["arguments"] = vectorOfVariantsToJson(_node.arguments);
return ret;
@ -98,14 +98,14 @@ Json::Value AsmJsonConverter::operator()(FunctionCall const& _node) const
Json::Value AsmJsonConverter::operator()(ExpressionStatement const& _node) const
{
Json::Value ret = createAstNode(_node.location, "YulExpressionStatement");
Json::Value ret = createAstNode(_node.debugData->location, "YulExpressionStatement");
ret["expression"] = std::visit(*this, _node.expression);
return ret;
}
Json::Value AsmJsonConverter::operator()(VariableDeclaration const& _node) const
{
Json::Value ret = createAstNode(_node.location, "YulVariableDeclaration");
Json::Value ret = createAstNode(_node.debugData->location, "YulVariableDeclaration");
for (auto const& var: _node.variables)
ret["variables"].append((*this)(var));
@ -117,7 +117,7 @@ Json::Value AsmJsonConverter::operator()(VariableDeclaration const& _node) const
Json::Value AsmJsonConverter::operator()(FunctionDefinition const& _node) const
{
yulAssert(!_node.name.empty(), "Invalid function name.");
Json::Value ret = createAstNode(_node.location, "YulFunctionDefinition");
Json::Value ret = createAstNode(_node.debugData->location, "YulFunctionDefinition");
ret["name"] = _node.name.str();
for (auto const& var: _node.parameters)
ret["parameters"].append((*this)(var));
@ -130,7 +130,7 @@ Json::Value AsmJsonConverter::operator()(FunctionDefinition const& _node) const
Json::Value AsmJsonConverter::operator()(If const& _node) const
{
yulAssert(_node.condition, "Invalid if condition.");
Json::Value ret = createAstNode(_node.location, "YulIf");
Json::Value ret = createAstNode(_node.debugData->location, "YulIf");
ret["condition"] = std::visit(*this, *_node.condition);
ret["body"] = (*this)(_node.body);
return ret;
@ -139,7 +139,7 @@ Json::Value AsmJsonConverter::operator()(If const& _node) const
Json::Value AsmJsonConverter::operator()(Switch const& _node) const
{
yulAssert(_node.expression, "Invalid expression pointer.");
Json::Value ret = createAstNode(_node.location, "YulSwitch");
Json::Value ret = createAstNode(_node.debugData->location, "YulSwitch");
ret["expression"] = std::visit(*this, *_node.expression);
for (auto const& var: _node.cases)
ret["cases"].append((*this)(var));
@ -148,7 +148,7 @@ Json::Value AsmJsonConverter::operator()(Switch const& _node) const
Json::Value AsmJsonConverter::operator()(Case const& _node) const
{
Json::Value ret = createAstNode(_node.location, "YulCase");
Json::Value ret = createAstNode(_node.debugData->location, "YulCase");
ret["value"] = _node.value ? (*this)(*_node.value) : "default";
ret["body"] = (*this)(_node.body);
return ret;
@ -157,7 +157,7 @@ Json::Value AsmJsonConverter::operator()(Case const& _node) const
Json::Value AsmJsonConverter::operator()(ForLoop const& _node) const
{
yulAssert(_node.condition, "Invalid for loop condition.");
Json::Value ret = createAstNode(_node.location, "YulForLoop");
Json::Value ret = createAstNode(_node.debugData->location, "YulForLoop");
ret["pre"] = (*this)(_node.pre);
ret["condition"] = std::visit(*this, *_node.condition);
ret["post"] = (*this)(_node.post);
@ -167,17 +167,17 @@ Json::Value AsmJsonConverter::operator()(ForLoop const& _node) const
Json::Value AsmJsonConverter::operator()(Break const& _node) const
{
return createAstNode(_node.location, "YulBreak");
return createAstNode(_node.debugData->location, "YulBreak");
}
Json::Value AsmJsonConverter::operator()(Continue const& _node) const
{
return createAstNode(_node.location, "YulContinue");
return createAstNode(_node.debugData->location, "YulContinue");
}
Json::Value AsmJsonConverter::operator()(Leave const& _node) const
{
return createAstNode(_node.location, "YulLeave");
return createAstNode(_node.debugData->location, "YulLeave");
}
Json::Value AsmJsonConverter::createAstNode(langutil::SourceLocation const& _location, string _nodeType) const

View File

@ -52,11 +52,12 @@ template <class T>
T AsmJsonImporter::createAsmNode(Json::Value const& _node)
{
T r;
r.location = createSourceLocation(_node);
SourceLocation location = createSourceLocation(_node);
yulAssert(
r.location.source && 0 <= r.location.start && r.location.start <= r.location.end,
location.source && 0 <= location.start && location.start <= location.end,
"Invalid source location in Asm AST"
);
r.debugData = DebugData::create(location);
return r;
}

View File

@ -21,8 +21,8 @@
* Solidity inline assembly parser.
*/
#include <libyul/AsmParser.h>
#include <libyul/AST.h>
#include <libyul/AsmParser.h>
#include <libyul/Exceptions.h>
#include <liblangutil/Scanner.h>
#include <liblangutil/ErrorReporter.h>
@ -40,6 +40,21 @@ using namespace solidity::util;
using namespace solidity::langutil;
using namespace solidity::yul;
namespace {
[[nodiscard]]
shared_ptr<DebugData const> updateLocationEndFrom(
shared_ptr<DebugData const> const& _debugData,
langutil::SourceLocation const& _location
)
{
SourceLocation updatedLocation = _debugData->location;
updatedLocation.end = _location.end;
return make_shared<DebugData const>(updatedLocation);
}
}
unique_ptr<Block> Parser::parse(std::shared_ptr<Scanner> const& _scanner, bool _reuseScanner)
{
m_recursionDepth = 0;
@ -70,7 +85,7 @@ Block Parser::parseBlock()
expectToken(Token::LBrace);
while (currentToken() != Token::RBrace)
block.statements.emplace_back(parseStatement());
block.location.end = currentLocation().end;
block.debugData = updateLocationEndFrom(block.debugData, currentLocation());
advance();
return block;
}
@ -109,7 +124,7 @@ Statement Parser::parseStatement()
fatalParserError(4904_error, "Case not allowed after default case.");
if (_switch.cases.empty())
fatalParserError(2418_error, "Switch statement without any cases.");
_switch.location.end = _switch.cases.back().body.location.end;
_switch.debugData = updateLocationEndFrom(_switch.debugData, _switch.cases.back().body.debugData->location);
return Statement{move(_switch)};
}
case Token::For:
@ -150,13 +165,13 @@ Statement Parser::parseStatement()
case Token::LParen:
{
Expression expr = parseCall(std::move(elementary));
return ExpressionStatement{locationOf(expr), move(expr)};
return ExpressionStatement{debugDataOf(expr), move(expr)};
}
case Token::Comma:
case Token::AssemblyAssign:
{
Assignment assignment;
assignment.location = locationOf(elementary);
assignment.debugData = debugDataOf(elementary);
while (true)
{
@ -191,7 +206,7 @@ Statement Parser::parseStatement()
expectToken(Token::AssemblyAssign);
assignment.value = make_unique<Expression>(parseExpression());
assignment.location.end = locationOf(*assignment.value).end;
assignment.debugData = updateLocationEndFrom(assignment.debugData, locationOf(*assignment.value));
return Statement{move(assignment)};
}
@ -221,7 +236,7 @@ Case Parser::parseCase()
else
yulAssert(false, "Case or default case expected.");
_case.body = parseBlock();
_case.location.end = _case.body.location.end;
_case.debugData = updateLocationEndFrom(_case.debugData, _case.body.debugData->location);
return _case;
}
@ -241,7 +256,7 @@ ForLoop Parser::parseForLoop()
forLoop.post = parseBlock();
m_currentForLoopComponent = ForLoopComponent::ForLoopBody;
forLoop.body = parseBlock();
forLoop.location.end = forLoop.body.location.end;
forLoop.debugData = updateLocationEndFrom(forLoop.debugData, forLoop.body.debugData->location);
m_currentForLoopComponent = outerForLoopComponent;
@ -261,7 +276,7 @@ Expression Parser::parseExpression()
if (m_dialect.builtin(_identifier.name))
fatalParserError(
7104_error,
_identifier.location,
_identifier.debugData->location,
"Builtin function \"" + _identifier.name.str() + "\" must be called."
);
return move(_identifier);
@ -280,7 +295,7 @@ variant<Literal, Identifier> Parser::parseLiteralOrIdentifier()
{
case Token::Identifier:
{
Identifier identifier{currentLocation(), YulString{currentLiteral()}};
Identifier identifier{DebugData::create(currentLocation()), YulString{currentLiteral()}};
advance();
return identifier;
}
@ -311,7 +326,7 @@ variant<Literal, Identifier> Parser::parseLiteralOrIdentifier()
}
Literal literal{
currentLocation(),
DebugData::create(currentLocation()),
kind,
YulString{currentLiteral()},
kind == LiteralKind::Boolean ? m_dialect.boolType : m_dialect.defaultType
@ -320,7 +335,7 @@ variant<Literal, Identifier> Parser::parseLiteralOrIdentifier()
if (currentToken() == Token::Colon)
{
expectToken(Token::Colon);
literal.location.end = currentLocation().end;
literal.debugData = updateLocationEndFrom(literal.debugData, currentLocation());
literal.type = expectAsmIdentifier();
}
@ -352,10 +367,11 @@ VariableDeclaration Parser::parseVariableDeclaration()
{
expectToken(Token::AssemblyAssign);
varDecl.value = make_unique<Expression>(parseExpression());
varDecl.location.end = locationOf(*varDecl.value).end;
varDecl.debugData = updateLocationEndFrom(varDecl.debugData, locationOf(*varDecl.value));
}
else
varDecl.location.end = varDecl.variables.back().location.end;
varDecl.debugData = updateLocationEndFrom(varDecl.debugData, varDecl.variables.back().debugData->location);
return varDecl;
}
@ -400,7 +416,7 @@ FunctionDefinition Parser::parseFunctionDefinition()
m_insideFunction = true;
funDef.body = parseBlock();
m_insideFunction = preInsideFunction;
funDef.location.end = funDef.body.location.end;
funDef.debugData = updateLocationEndFrom(funDef.debugData, funDef.body.debugData->location);
m_currentForLoopComponent = outerForLoopComponent;
return funDef;
@ -415,7 +431,7 @@ FunctionCall Parser::parseCall(variant<Literal, Identifier>&& _initialOp)
FunctionCall ret;
ret.functionName = std::move(std::get<Identifier>(_initialOp));
ret.location = ret.functionName.location;
ret.debugData = ret.functionName.debugData;
expectToken(Token::LParen);
if (currentToken() != Token::RParen)
@ -427,7 +443,7 @@ FunctionCall Parser::parseCall(variant<Literal, Identifier>&& _initialOp)
ret.arguments.emplace_back(parseExpression());
}
}
ret.location.end = currentLocation().end;
ret.debugData = updateLocationEndFrom(ret.debugData, currentLocation());
expectToken(Token::RParen);
return ret;
}
@ -440,7 +456,7 @@ TypedName Parser::parseTypedName()
if (currentToken() == Token::Colon)
{
expectToken(Token::Colon);
typedName.location.end = currentLocation().end;
typedName.debugData = updateLocationEndFrom(typedName.debugData, currentLocation());
typedName.type = expectAsmIdentifier();
}
else

View File

@ -70,7 +70,7 @@ protected:
template <class T> T createWithLocation() const
{
T r;
r.location = currentLocation();
r.debugData = DebugData::create(currentLocation());
return r;
}

View File

@ -25,7 +25,6 @@
#include <libyul/AsmAnalysis.h>
#include <libyul/AsmAnalysisInfo.h>
#include <libyul/AsmParser.h>
#include <libyul/AsmPrinter.h>
#include <libyul/backends/evm/EthAssemblyAdapter.h>
#include <libyul/backends/evm/EVMAssembly.h>

View File

@ -29,17 +29,17 @@ using namespace solidity::langutil;
Literal Dialect::zeroLiteralForType(solidity::yul::YulString _type) const
{
if (_type == boolType && _type != defaultType)
return {SourceLocation{}, LiteralKind::Boolean, "false"_yulstring, _type};
return {SourceLocation{}, LiteralKind::Number, "0"_yulstring, _type};
return {DebugData::create(), LiteralKind::Boolean, "false"_yulstring, _type};
return {DebugData::create(), LiteralKind::Number, "0"_yulstring, _type};
}
Literal Dialect::trueLiteral() const
{
if (boolType != defaultType)
return {SourceLocation{}, LiteralKind::Boolean, "true"_yulstring, boolType};
return {DebugData::create(), LiteralKind::Boolean, "true"_yulstring, boolType};
else
return {SourceLocation{}, LiteralKind::Number, "1"_yulstring, defaultType};
return {DebugData::create(), LiteralKind::Number, "1"_yulstring, defaultType};
}
bool Dialect::validTypeForLiteral(LiteralKind _kind, YulString, YulString _type) const

View File

@ -19,10 +19,10 @@
* Parser for Yul code and data object container.
*/
#include <libyul/AST.h>
#include <libyul/ObjectParser.h>
#include <libyul/AsmParser.h>
#include <libyul/AST.h>
#include <libyul/Exceptions.h>
#include <liblangutil/Token.h>

View File

@ -53,7 +53,7 @@ bool ScopeFiller::operator()(ExpressionStatement const& _expr)
bool ScopeFiller::operator()(VariableDeclaration const& _varDecl)
{
for (auto const& variable: _varDecl.variables)
if (!registerVariable(variable, _varDecl.location, *m_currentScope))
if (!registerVariable(variable, _varDecl.debugData->location, *m_currentScope))
return false;
return true;
}
@ -68,7 +68,7 @@ bool ScopeFiller::operator()(FunctionDefinition const& _funDef)
bool success = true;
for (auto const& var: _funDef.parameters + _funDef.returnVariables)
if (!registerVariable(var, _funDef.location, varScope))
if (!registerVariable(var, _funDef.debugData->location, varScope))
success = false;
if (!(*this)(_funDef.body))
@ -162,7 +162,7 @@ bool ScopeFiller::registerFunction(FunctionDefinition const& _funDef)
//@TODO secondary location
m_errorReporter.declarationError(
6052_error,
_funDef.location,
_funDef.debugData->location,
"Function name " + _funDef.name.str() + " already taken in this scope."
);
return false;

View File

@ -23,6 +23,8 @@
#pragma once
#include <libyul/ASTForward.h>
#include <libsolutil/Common.h>
#include <libsolutil/CommonData.h>

View File

@ -100,7 +100,7 @@ void ConstantOptimiser::visit(Expression& _e)
if (
Expression const* repr =
RepresentationFinder(m_dialect, m_meter, locationOf(_e), m_cache)
RepresentationFinder(m_dialect, m_meter, debugDataOf(_e), m_cache)
.tryFindRepresentation(valueOfLiteral(literal))
)
_e = ASTCopier{}.translate(*repr);
@ -180,7 +180,7 @@ Representation const& RepresentationFinder::findRepresentation(u256 const& _valu
Representation RepresentationFinder::represent(u256 const& _value) const
{
Representation repr;
repr.expression = make_unique<Expression>(Literal{m_location, LiteralKind::Number, YulString{formatNumber(_value)}, {}});
repr.expression = make_unique<Expression>(Literal{m_debugData, LiteralKind::Number, YulString{formatNumber(_value)}, {}});
repr.cost = m_meter.costs(*repr.expression);
return repr;
}
@ -192,8 +192,8 @@ Representation RepresentationFinder::represent(
{
Representation repr;
repr.expression = make_unique<Expression>(FunctionCall{
m_location,
Identifier{m_location, _instruction},
m_debugData,
Identifier{m_debugData, _instruction},
{ASTCopier{}.translate(*_argument.expression)}
});
repr.cost = _argument.cost + m_meter.instructionCosts(*m_dialect.builtin(_instruction)->instruction);
@ -208,8 +208,8 @@ Representation RepresentationFinder::represent(
{
Representation repr;
repr.expression = make_unique<Expression>(FunctionCall{
m_location,
Identifier{m_location, _instruction},
m_debugData,
Identifier{m_debugData, _instruction},
{ASTCopier{}.translate(*_arg1.expression), ASTCopier{}.translate(*_arg2.expression)}
});
repr.cost = m_meter.instructionCosts(*m_dialect.builtin(_instruction)->instruction) + _arg1.cost + _arg2.cost;

View File

@ -74,12 +74,12 @@ public:
RepresentationFinder(
EVMDialect const& _dialect,
GasMeter const& _meter,
langutil::SourceLocation _location,
std::shared_ptr<DebugData const> _debugData,
std::map<u256, Representation>& _cache
):
m_dialect(_dialect),
m_meter(_meter),
m_location(std::move(_location)),
m_debugData(std::move(_debugData)),
m_cache(_cache)
{}
@ -100,7 +100,7 @@ private:
EVMDialect const& m_dialect;
GasMeter const& m_meter;
langutil::SourceLocation m_location;
std::shared_ptr<DebugData const> m_debugData;
/// Counter for the complexity of optimization, will stop when it reaches zero.
size_t m_maxSteps = 10000;
std::map<u256, Representation>& m_cache;

View File

@ -39,7 +39,7 @@ size_t constexpr assemblySizeReferenceSize = 4;
}
void EVMAssembly::setSourceLocation(SourceLocation const&)
void EVMAssembly::setSourceLocation(langutil::SourceLocation const&)
{
// Ignored for now;
}

View File

@ -44,6 +44,16 @@ using namespace solidity;
using namespace solidity::yul;
using namespace solidity::util;
namespace
{
langutil::SourceLocation extractSourceLocationFromDebugData(shared_ptr<DebugData const> const& _debugData)
{
return _debugData ? _debugData->location : langutil::SourceLocation{};
}
}
CodeTransform::CodeTransform(
AbstractAssembly& _assembly,
AsmAnalysisInfo& _analysisInfo,
@ -145,13 +155,13 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl)
}
else
{
m_assembly.setSourceLocation(_varDecl.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_varDecl.debugData));
size_t variablesLeft = numVariables;
while (variablesLeft--)
m_assembly.appendConstant(u256(0));
}
m_assembly.setSourceLocation(_varDecl.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_varDecl.debugData));
bool atTopOfStack = true;
for (size_t varIndex = 0; varIndex < numVariables; ++varIndex)
{
@ -205,13 +215,13 @@ void CodeTransform::operator()(Assignment const& _assignment)
std::visit(*this, *_assignment.value);
expectDeposit(static_cast<int>(_assignment.variableNames.size()), height);
m_assembly.setSourceLocation(_assignment.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_assignment.debugData));
generateMultiAssignment(_assignment.variableNames);
}
void CodeTransform::operator()(ExpressionStatement const& _statement)
{
m_assembly.setSourceLocation(_statement.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_statement.debugData));
std::visit(*this, _statement.expression);
}
@ -225,7 +235,7 @@ void CodeTransform::operator()(FunctionCall const& _call)
});
else
{
m_assembly.setSourceLocation(_call.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_call.debugData));
EVMAssembly::LabelID returnLabel(numeric_limits<EVMAssembly::LabelID>::max()); // only used for evm 1.0
returnLabel = m_assembly.newLabelId();
@ -240,7 +250,7 @@ void CodeTransform::operator()(FunctionCall const& _call)
yulAssert(function->arguments.size() == _call.arguments.size(), "");
for (auto const& arg: _call.arguments | ranges::views::reverse)
visitExpression(arg);
m_assembly.setSourceLocation(_call.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_call.debugData));
m_assembly.appendJumpTo(
functionEntryID(_call.functionName.name, *function),
static_cast<int>(function->returns.size() - function->arguments.size()) - 1,
@ -252,7 +262,7 @@ void CodeTransform::operator()(FunctionCall const& _call)
void CodeTransform::operator()(Identifier const& _identifier)
{
m_assembly.setSourceLocation(_identifier.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_identifier.debugData));
// First search internals, then externals.
yulAssert(m_scope, "");
if (m_scope->lookup(_identifier.name, GenericVisitor{
@ -284,19 +294,19 @@ void CodeTransform::operator()(Identifier const& _identifier)
void CodeTransform::operator()(Literal const& _literal)
{
m_assembly.setSourceLocation(_literal.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_literal.debugData));
m_assembly.appendConstant(valueOfLiteral(_literal));
}
void CodeTransform::operator()(If const& _if)
{
visitExpression(*_if.condition);
m_assembly.setSourceLocation(_if.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_if.debugData));
m_assembly.appendInstruction(evmasm::Instruction::ISZERO);
AbstractAssembly::LabelID end = m_assembly.newLabelId();
m_assembly.appendJumpToIf(end);
(*this)(_if.body);
m_assembly.setSourceLocation(_if.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_if.debugData));
m_assembly.appendLabel(end);
}
@ -313,7 +323,7 @@ void CodeTransform::operator()(Switch const& _switch)
if (c.value)
{
(*this)(*c.value);
m_assembly.setSourceLocation(c.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(c.debugData));
AbstractAssembly::LabelID bodyLabel = m_assembly.newLabelId();
caseBodies[&c] = bodyLabel;
yulAssert(m_assembly.stackHeight() == expressionHeight + 1, "");
@ -325,24 +335,24 @@ void CodeTransform::operator()(Switch const& _switch)
// default case
(*this)(c.body);
}
m_assembly.setSourceLocation(_switch.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_switch.debugData));
m_assembly.appendJumpTo(end);
size_t numCases = caseBodies.size();
for (auto const& c: caseBodies)
{
m_assembly.setSourceLocation(c.first->location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(c.first->debugData));
m_assembly.appendLabel(c.second);
(*this)(c.first->body);
// Avoid useless "jump to next" for the last case.
if (--numCases > 0)
{
m_assembly.setSourceLocation(c.first->location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(c.first->debugData));
m_assembly.appendJumpTo(end);
}
}
m_assembly.setSourceLocation(_switch.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_switch.debugData));
m_assembly.appendLabel(end);
m_assembly.appendInstruction(evmasm::Instruction::POP);
}
@ -363,7 +373,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
m_context->variableStackHeights[&var] = height++;
}
m_assembly.setSourceLocation(_function.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_function.debugData));
int const stackHeightBefore = m_assembly.stackHeight();
m_assembly.appendLabel(functionEntryID(_function.name, function));
@ -488,11 +498,11 @@ void CodeTransform::operator()(ForLoop const& _forLoop)
AbstractAssembly::LabelID postPart = m_assembly.newLabelId();
AbstractAssembly::LabelID loopEnd = m_assembly.newLabelId();
m_assembly.setSourceLocation(_forLoop.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_forLoop.debugData));
m_assembly.appendLabel(loopStart);
visitExpression(*_forLoop.condition);
m_assembly.setSourceLocation(_forLoop.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_forLoop.debugData));
m_assembly.appendInstruction(evmasm::Instruction::ISZERO);
m_assembly.appendJumpToIf(loopEnd);
@ -500,12 +510,12 @@ void CodeTransform::operator()(ForLoop const& _forLoop)
m_context->forLoopStack.emplace(Context::ForLoopLabels{ {postPart, stackHeightBody}, {loopEnd, stackHeightBody} });
(*this)(_forLoop.body);
m_assembly.setSourceLocation(_forLoop.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_forLoop.debugData));
m_assembly.appendLabel(postPart);
(*this)(_forLoop.post);
m_assembly.setSourceLocation(_forLoop.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_forLoop.debugData));
m_assembly.appendJumpTo(loopStart);
m_assembly.appendLabel(loopEnd);
@ -525,7 +535,7 @@ int CodeTransform::appendPopUntil(int _targetDepth)
void CodeTransform::operator()(Break const& _break)
{
yulAssert(!m_context->forLoopStack.empty(), "Invalid break-statement. Requires surrounding for-loop in code generation.");
m_assembly.setSourceLocation(_break.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_break.debugData));
Context::JumpInfo const& jump = m_context->forLoopStack.top().done;
m_assembly.appendJumpTo(jump.label, appendPopUntil(jump.targetStackHeight));
@ -534,7 +544,7 @@ void CodeTransform::operator()(Break const& _break)
void CodeTransform::operator()(Continue const& _continue)
{
yulAssert(!m_context->forLoopStack.empty(), "Invalid continue-statement. Requires surrounding for-loop in code generation.");
m_assembly.setSourceLocation(_continue.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_continue.debugData));
Context::JumpInfo const& jump = m_context->forLoopStack.top().post;
m_assembly.appendJumpTo(jump.label, appendPopUntil(jump.targetStackHeight));
@ -544,7 +554,7 @@ void CodeTransform::operator()(Leave const& _leaveStatement)
{
yulAssert(m_functionExitLabel, "Invalid leave-statement. Requires surrounding function in code generation.");
yulAssert(m_functionExitStackHeight, "");
m_assembly.setSourceLocation(_leaveStatement.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_leaveStatement.debugData));
m_assembly.appendJumpTo(*m_functionExitLabel, appendPopUntil(*m_functionExitStackHeight));
}
@ -605,7 +615,7 @@ void CodeTransform::setupReturnVariablesAndFunctionExit()
// Allocate slots for return variables as if they were declared as variables in the virtual function scope.
for (TypedName const& var: m_delayedReturnVariables)
(*this)(VariableDeclaration{var.location, {var}, {}});
(*this)(VariableDeclaration{var.debugData, {var}, {}});
m_functionExitStackHeight = ranges::max(m_delayedReturnVariables | ranges::views::transform([&](TypedName const& _name) {
return variableStackHeight(_name.name);
@ -654,7 +664,7 @@ void CodeTransform::visitStatements(vector<Statement> const& _statements)
auto const* functionDefinition = std::get_if<FunctionDefinition>(&statement);
if (functionDefinition && !jumpTarget)
{
m_assembly.setSourceLocation(locationOf(statement));
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(functionDefinition->debugData));
jumpTarget = m_assembly.newLabelId();
m_assembly.appendJumpTo(*jumpTarget, 0);
}
@ -675,7 +685,7 @@ void CodeTransform::visitStatements(vector<Statement> const& _statements)
void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartStackHeight)
{
m_assembly.setSourceLocation(_block.location);
m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_block.debugData));
freeUnusedVariables();

View File

@ -39,6 +39,7 @@ class ErrorReporter;
namespace solidity::yul
{
struct AsmAnalysisInfo;
class EVMAssembly;

View File

@ -55,7 +55,7 @@ void visitArguments(
for (auto const& arg: _call.arguments | ranges::views::reverse)
_visitExpression(arg);
_assembly.setSourceLocation(_call.location);
_assembly.setSourceLocation(_call.debugData->location);
}
@ -259,7 +259,7 @@ map<YulString, BuiltinFunctionForEVM> createBuiltins(langutil::EVMVersion _evmVe
_visitExpression(_call.arguments[2]);
YulString identifier = std::get<Literal>(_call.arguments[1]).value;
_visitExpression(_call.arguments[0]);
_assembly.setSourceLocation(_call.location);
_assembly.setSourceLocation(_call.debugData->location);
_assembly.appendImmutableAssignment(identifier.str());
}
));

View File

@ -32,10 +32,10 @@
#include <libyul/optimiser/OptimiserStep.h>
#include <libyul/optimiser/ForLoopConditionIntoBody.h>
#include <libyul/AST.h>
#include <libyul/AsmParser.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/AsmAnalysisInfo.h>
#include <libyul/AST.h>
#include <libyul/Object.h>
#include <liblangutil/ErrorReporter.h>

View File

@ -65,8 +65,8 @@ void WordSizeTransform::operator()(FunctionCall& _fc)
void WordSizeTransform::operator()(If& _if)
{
_if.condition = make_unique<Expression>(FunctionCall{
locationOf(*_if.condition),
Identifier{locationOf(*_if.condition), "or_bool"_yulstring},
debugDataOf(*_if.condition),
Identifier{debugDataOf(*_if.condition), "or_bool"_yulstring},
expandValueToVector(*_if.condition)
});
(*this)(_if.body);
@ -81,8 +81,8 @@ void WordSizeTransform::operator()(ForLoop& _for)
{
(*this)(_for.pre);
_for.condition = make_unique<Expression>(FunctionCall{
locationOf(*_for.condition),
Identifier{locationOf(*_for.condition), "or_bool"_yulstring},
debugDataOf(*_for.condition),
Identifier{debugDataOf(*_for.condition), "or_bool"_yulstring},
expandValueToVector(*_for.condition)
});
(*this)(_for.post);
@ -116,18 +116,18 @@ void WordSizeTransform::operator()(Block& _block)
vector<Statement> ret;
for (size_t i = 0; i < 3; i++)
ret.emplace_back(VariableDeclaration{
varDecl.location,
{TypedName{varDecl.location, newLhs[i], m_targetDialect.defaultType}},
varDecl.debugData,
{TypedName{varDecl.debugData, newLhs[i], m_targetDialect.defaultType}},
make_unique<Expression>(Literal{
locationOf(*varDecl.value),
debugDataOf(*varDecl.value),
LiteralKind::Number,
"0"_yulstring,
m_targetDialect.defaultType
})
});
ret.emplace_back(VariableDeclaration{
varDecl.location,
{TypedName{varDecl.location, newLhs[3], m_targetDialect.defaultType}},
varDecl.debugData,
{TypedName{varDecl.debugData, newLhs[3], m_targetDialect.defaultType}},
std::move(varDecl.value)
});
return {std::move(ret)};
@ -147,8 +147,8 @@ void WordSizeTransform::operator()(Block& _block)
vector<Statement> ret;
for (size_t i = 0; i < 4; i++)
ret.emplace_back(VariableDeclaration{
varDecl.location,
{TypedName{varDecl.location, newLhs[i], m_targetDialect.defaultType}},
varDecl.debugData,
{TypedName{varDecl.debugData, newLhs[i], m_targetDialect.defaultType}},
std::move(newRhs[i])
}
);
@ -177,18 +177,18 @@ void WordSizeTransform::operator()(Block& _block)
vector<Statement> ret;
for (size_t i = 0; i < 3; i++)
ret.emplace_back(Assignment{
assignment.location,
{Identifier{assignment.location, newLhs[i]}},
assignment.debugData,
{Identifier{assignment.debugData, newLhs[i]}},
make_unique<Expression>(Literal{
locationOf(*assignment.value),
debugDataOf(*assignment.value),
LiteralKind::Number,
"0"_yulstring,
m_targetDialect.defaultType
})
});
ret.emplace_back(Assignment{
assignment.location,
{Identifier{assignment.location, newLhs[3]}},
assignment.debugData,
{Identifier{assignment.debugData, newLhs[3]}},
std::move(assignment.value)
});
return {std::move(ret)};
@ -208,8 +208,8 @@ void WordSizeTransform::operator()(Block& _block)
vector<Statement> ret;
for (size_t i = 0; i < 4; i++)
ret.emplace_back(Assignment{
assignment.location,
{Identifier{assignment.location, m_variableMapping.at(lhsName)[i]}},
assignment.debugData,
{Identifier{assignment.debugData, m_variableMapping.at(lhsName)[i]}},
std::move(newRhs[i])
}
);
@ -258,7 +258,7 @@ void WordSizeTransform::rewriteVarDeclList(TypedNameList& _nameList)
{
TypedNameList ret;
for (auto newName: generateU64IdentifierNames(_n.name))
ret.emplace_back(TypedName{_n.location, newName, m_targetDialect.defaultType});
ret.emplace_back(TypedName{_n.debugData, newName, m_targetDialect.defaultType});
return ret;
}
);
@ -272,14 +272,14 @@ void WordSizeTransform::rewriteIdentifierList(vector<Identifier>& _ids)
{
vector<Identifier> ret;
for (auto newId: m_variableMapping.at(_id.name))
ret.push_back(Identifier{_id.location, newId});
ret.push_back(Identifier{_id.debugData, newId});
return ret;
}
);
}
vector<Statement> WordSizeTransform::handleSwitchInternal(
langutil::SourceLocation const& _location,
shared_ptr<DebugData const> const& _debugData,
vector<YulString> const& _splitExpressions,
vector<Case> _cases,
YulString _runDefaultFlag,
@ -304,19 +304,19 @@ vector<Statement> WordSizeTransform::handleSwitchInternal(
}
Switch ret{
_location,
make_unique<Expression>(Identifier{_location, _splitExpressions.at(_depth)}),
_debugData,
make_unique<Expression>(Identifier{_debugData, _splitExpressions.at(_depth)}),
{}
};
for (auto& c: cases)
{
Literal label{_location, LiteralKind::Number, YulString(c.first.str()), m_targetDialect.defaultType};
Literal label{_debugData, LiteralKind::Number, YulString(c.first.str()), m_targetDialect.defaultType};
ret.cases.emplace_back(Case{
c.second.front().location,
c.second.front().debugData,
make_unique<Literal>(std::move(label)),
Block{_location, handleSwitchInternal(
_location,
Block{_debugData, handleSwitchInternal(
_debugData,
_splitExpressions,
std::move(c.second),
_runDefaultFlag,
@ -326,13 +326,13 @@ vector<Statement> WordSizeTransform::handleSwitchInternal(
}
if (!_runDefaultFlag.empty())
ret.cases.emplace_back(Case{
_location,
_debugData,
nullptr,
Block{_location, make_vector<Statement>(
Block{_debugData, make_vector<Statement>(
Assignment{
_location,
{{_location, _runDefaultFlag}},
make_unique<Expression>(Literal{_location, LiteralKind::Boolean, "true"_yulstring, m_targetDialect.boolType})
_debugData,
{{_debugData, _runDefaultFlag}},
make_unique<Expression>(Literal{_debugData, LiteralKind::Boolean, "true"_yulstring, m_targetDialect.boolType})
}
)}
});
@ -356,8 +356,8 @@ std::vector<Statement> WordSizeTransform::handleSwitch(Switch& _switch)
defaultCase = std::move(_switch.cases.back());
_switch.cases.pop_back();
ret.emplace_back(VariableDeclaration{
_switch.location,
{TypedName{_switch.location, runDefaultFlag, m_targetDialect.boolType}},
_switch.debugData,
{TypedName{_switch.debugData, runDefaultFlag, m_targetDialect.boolType}},
{}
});
}
@ -366,7 +366,7 @@ std::vector<Statement> WordSizeTransform::handleSwitch(Switch& _switch)
splitExpressions.emplace_back(std::get<Identifier>(*expr).name);
ret += handleSwitchInternal(
_switch.location,
_switch.debugData,
splitExpressions,
std::move(_switch.cases),
runDefaultFlag,
@ -374,8 +374,8 @@ std::vector<Statement> WordSizeTransform::handleSwitch(Switch& _switch)
);
if (!runDefaultFlag.empty())
ret.emplace_back(If{
_switch.location,
make_unique<Expression>(Identifier{_switch.location, runDefaultFlag}),
_switch.debugData,
make_unique<Expression>(Identifier{_switch.debugData, runDefaultFlag}),
std::move(defaultCase.body)
});
return ret;
@ -397,7 +397,7 @@ array<unique_ptr<Expression>, 4> WordSizeTransform::expandValue(Expression const
{
auto const& id = std::get<Identifier>(_e);
for (size_t i = 0; i < 4; i++)
ret[i] = make_unique<Expression>(Identifier{id.location, m_variableMapping.at(id.name)[i]});
ret[i] = make_unique<Expression>(Identifier{id.debugData, m_variableMapping.at(id.name)[i]});
}
else if (holds_alternative<Literal>(_e))
{
@ -410,7 +410,7 @@ array<unique_ptr<Expression>, 4> WordSizeTransform::expandValue(Expression const
val >>= 64;
ret[exprIndexReverse] = make_unique<Expression>(
Literal{
lit.location,
lit.debugData,
LiteralKind::Number,
YulString(currentVal.str()),
m_targetDialect.defaultType

View File

@ -87,7 +87,7 @@ private:
std::vector<Statement> handleSwitch(Switch& _switch);
std::vector<Statement> handleSwitchInternal(
langutil::SourceLocation const& _location,
std::shared_ptr<DebugData const> const& _debugData,
std::vector<YulString> const& _splitExpressions,
std::vector<Case> _cases,
YulString _runDefaultFlag,

View File

@ -34,13 +34,13 @@ using namespace solidity::util;
Statement ASTCopier::operator()(ExpressionStatement const& _statement)
{
return ExpressionStatement{ _statement.location, translate(_statement.expression) };
return ExpressionStatement{ _statement.debugData, translate(_statement.expression) };
}
Statement ASTCopier::operator()(VariableDeclaration const& _varDecl)
{
return VariableDeclaration{
_varDecl.location,
_varDecl.debugData,
translateVector(_varDecl.variables),
translate(_varDecl.value)
};
@ -49,7 +49,7 @@ Statement ASTCopier::operator()(VariableDeclaration const& _varDecl)
Statement ASTCopier::operator()(Assignment const& _assignment)
{
return Assignment{
_assignment.location,
_assignment.debugData,
translateVector(_assignment.variableNames),
translate(_assignment.value)
};
@ -58,7 +58,7 @@ Statement ASTCopier::operator()(Assignment const& _assignment)
Expression ASTCopier::operator()(FunctionCall const& _call)
{
return FunctionCall{
_call.location,
_call.debugData,
translate(_call.functionName),
translateVector(_call.arguments)
};
@ -76,12 +76,12 @@ Expression ASTCopier::operator()(Literal const& _literal)
Statement ASTCopier::operator()(If const& _if)
{
return If{_if.location, translate(_if.condition), translate(_if.body)};
return If{_if.debugData, translate(_if.condition), translate(_if.body)};
}
Statement ASTCopier::operator()(Switch const& _switch)
{
return Switch{_switch.location, translate(_switch.expression), translateVector(_switch.cases)};
return Switch{_switch.debugData, translate(_switch.expression), translateVector(_switch.cases)};
}
Statement ASTCopier::operator()(FunctionDefinition const& _function)
@ -92,7 +92,7 @@ Statement ASTCopier::operator()(FunctionDefinition const& _function)
ScopeGuard g([&]() { this->leaveFunction(_function); });
return FunctionDefinition{
_function.location,
_function.debugData,
translatedName,
translateVector(_function.parameters),
translateVector(_function.returnVariables),
@ -106,7 +106,7 @@ Statement ASTCopier::operator()(ForLoop const& _forLoop)
ScopeGuard g([&]() { this->leaveScope(_forLoop.pre); });
return ForLoop{
_forLoop.location,
_forLoop.debugData,
translate(_forLoop.pre),
translate(_forLoop.condition),
translate(_forLoop.post),
@ -148,17 +148,17 @@ Block ASTCopier::translate(Block const& _block)
enterScope(_block);
ScopeGuard g([&]() { this->leaveScope(_block); });
return Block{_block.location, translateVector(_block.statements)};
return Block{_block.debugData, translateVector(_block.statements)};
}
Case ASTCopier::translate(Case const& _case)
{
return Case{_case.location, translate(_case.value), translate(_case.body)};
return Case{_case.debugData, translate(_case.value), translate(_case.body)};
}
Identifier ASTCopier::translate(Identifier const& _identifier)
{
return Identifier{_identifier.location, translateIdentifier(_identifier.name)};
return Identifier{_identifier.debugData, translateIdentifier(_identifier.name)};
}
Literal ASTCopier::translate(Literal const& _literal)
@ -168,7 +168,7 @@ Literal ASTCopier::translate(Literal const& _literal)
TypedName ASTCopier::translate(TypedName const& _typedName)
{
return TypedName{_typedName.location, translateIdentifier(_typedName.name), _typedName.type};
return TypedName{_typedName.debugData, translateIdentifier(_typedName.name), _typedName.type};
}
YulString FunctionCopier::translateIdentifier(YulString _name)

View File

@ -95,13 +95,13 @@ void CommonSubexpressionEliminator::visit(Expression& _e)
if (Identifier const* identifier = get_if<Identifier>(&_e))
{
YulString name = identifier->name;
if (m_value.count(name))
YulString identifierName = identifier->name;
if (m_value.count(identifierName))
{
assertThrow(m_value.at(name).value, OptimizerException, "");
if (Identifier const* value = get_if<Identifier>(m_value.at(name).value))
assertThrow(m_value.at(identifierName).value, OptimizerException, "");
if (Identifier const* value = get_if<Identifier>(m_value.at(identifierName).value))
if (inScope(value->name))
_e = Identifier{locationOf(_e), value->name};
_e = Identifier{debugDataOf(_e), value->name};
}
}
else
@ -120,7 +120,7 @@ void CommonSubexpressionEliminator::visit(Expression& _e)
continue;
if (SyntacticallyEqual{}(_e, *value.value) && inScope(variable))
{
_e = Identifier{locationOf(_e), variable};
_e = Identifier{debugDataOf(_e), variable};
break;
}
}

View File

@ -44,8 +44,8 @@ void ConditionalSimplifier::operator()(Switch& _switch)
(*this)(*_case.value);
_case.body.statements.insert(_case.body.statements.begin(),
Assignment{
_case.body.location,
{Identifier{_case.body.location, expr}},
_case.body.debugData,
{Identifier{_case.body.debugData, expr}},
make_unique<Expression>(*_case.value)
}
);
@ -72,12 +72,12 @@ void ConditionalSimplifier::operator()(Block& _block)
)
{
YulString condition = std::get<Identifier>(*_if.condition).name;
langutil::SourceLocation location = _if.location;
std::shared_ptr<DebugData const> debugData = _if.debugData;
return make_vector<Statement>(
std::move(_s),
Assignment{
location,
{Identifier{location, condition}},
debugData,
{Identifier{debugData, condition}},
make_unique<Expression>(m_dialect.zeroLiteralForType(m_dialect.boolType))
}
);

View File

@ -38,14 +38,14 @@ namespace
{
ExpressionStatement makeDiscardCall(
langutil::SourceLocation const& _location,
std::shared_ptr<DebugData const> const& _debugData,
BuiltinFunction const& _discardFunction,
Expression&& _expression
)
{
return {_location, FunctionCall{
_location,
Identifier{_location, _discardFunction.name},
return {_debugData, FunctionCall{
_debugData,
Identifier{_debugData, _discardFunction.name},
{std::move(_expression)}
}};
}
@ -126,7 +126,7 @@ void ControlFlowSimplifier::visit(Statement& _st)
if (isTerminating && m_numContinueStatements == 0 && m_numBreakStatements == 0)
{
If replacement{forLoop.location, std::move(forLoop.condition), std::move(forLoop.body)};
If replacement{forLoop.debugData, std::move(forLoop.condition), std::move(forLoop.body)};
if (controlFlow == TerminationFinder::ControlFlow::Break)
replacement.body.statements.resize(replacement.body.statements.size() - 1);
_st = std::move(replacement);
@ -149,7 +149,7 @@ void ControlFlowSimplifier::simplify(std::vector<yul::Statement>& _statements)
{
OptionalStatements s = vector<Statement>{};
s->emplace_back(makeDiscardCall(
_ifStmt.location,
_ifStmt.debugData,
*m_dialect.discardFunction(m_dialect.boolType),
std::move(*_ifStmt.condition)
));
@ -191,10 +191,8 @@ OptionalStatements ControlFlowSimplifier::reduceNoCaseSwitch(Switch& _switchStmt
if (!discardFunction)
return {};
auto loc = locationOf(*_switchStmt.expression);
return make_vector<Statement>(makeDiscardCall(
loc,
debugDataOf(*_switchStmt.expression),
*discardFunction,
std::move(*_switchStmt.expression)
));
@ -205,17 +203,17 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch
yulAssert(_switchStmt.cases.size() == 1, "Expected only one case!");
auto& switchCase = _switchStmt.cases.front();
auto loc = locationOf(*_switchStmt.expression);
shared_ptr<DebugData const> debugData = debugDataOf(*_switchStmt.expression);
YulString type = m_typeInfo.typeOf(*_switchStmt.expression);
if (switchCase.value)
{
if (!m_dialect.equalityFunction(type))
return {};
return make_vector<Statement>(If{
std::move(_switchStmt.location),
std::move(_switchStmt.debugData),
make_unique<Expression>(FunctionCall{
loc,
Identifier{loc, m_dialect.equalityFunction(type)->name},
debugData,
Identifier{debugData, m_dialect.equalityFunction(type)->name},
{std::move(*switchCase.value), std::move(*_switchStmt.expression)}
}),
std::move(switchCase.body)
@ -228,7 +226,7 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch
return make_vector<Statement>(
makeDiscardCall(
loc,
debugData,
*m_dialect.discardFunction(type),
std::move(*_switchStmt.expression)
),

View File

@ -39,5 +39,5 @@ void ExpressionSimplifier::visit(Expression& _expression)
ASTModifier::visit(_expression);
while (auto const* match = SimplificationRules::findFirstMatch(_expression, m_dialect, m_value))
_expression = match->action().toExpression(locationOf(_expression));
_expression = match->action().toExpression(debugDataOf(_expression));
}

View File

@ -101,15 +101,15 @@ void ExpressionSplitter::outlineExpression(Expression& _expr)
visit(_expr);
SourceLocation location = locationOf(_expr);
shared_ptr<DebugData const> debugData = debugDataOf(_expr);
YulString var = m_nameDispenser.newName({});
YulString type = m_typeInfo.typeOf(_expr);
m_statementsToPrefix.emplace_back(VariableDeclaration{
location,
{{TypedName{location, var, type}}},
debugData,
{{TypedName{debugData, var, type}}},
make_unique<Expression>(std::move(_expr))
});
_expr = Identifier{location, var};
_expr = Identifier{debugData, var};
m_typeInfo.setVariableType(var, type);
}

View File

@ -39,25 +39,25 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop)
!holds_alternative<Identifier>(*_forLoop.condition)
)
{
langutil::SourceLocation const loc = locationOf(*_forLoop.condition);
shared_ptr<DebugData const> debugData = debugDataOf(*_forLoop.condition);
_forLoop.body.statements.emplace(
begin(_forLoop.body.statements),
If {
loc,
debugData,
make_unique<Expression>(
FunctionCall {
loc,
{loc, m_dialect.booleanNegationFunction()->name},
debugData,
{debugData, m_dialect.booleanNegationFunction()->name},
util::make_vector<Expression>(std::move(*_forLoop.condition))
}
),
Block {loc, util::make_vector<Statement>(Break{{}})}
Block {debugData, util::make_vector<Statement>(Break{{}})}
}
);
_forLoop.condition = make_unique<Expression>(
Literal {
loc,
debugData,
LiteralKind::Boolean,
"true"_yulstring,
m_dialect.boolType

View File

@ -55,7 +55,7 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop)
return;
YulString iszero = m_dialect.booleanNegationFunction()->name;
langutil::SourceLocation location = locationOf(*firstStatement.condition);
shared_ptr<DebugData const> debugData = debugDataOf(*firstStatement.condition);
if (
holds_alternative<FunctionCall>(*firstStatement.condition) &&
@ -64,8 +64,8 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop)
_forLoop.condition = make_unique<Expression>(std::move(std::get<FunctionCall>(*firstStatement.condition).arguments.front()));
else
_forLoop.condition = make_unique<Expression>(FunctionCall{
location,
Identifier{location, iszero},
debugData,
Identifier{debugData, iszero},
util::make_vector<Expression>(
std::move(*firstStatement.condition)
)

View File

@ -268,7 +268,7 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
auto newVariable = [&](TypedName const& _existingVariable, Expression* _value) {
YulString newName = m_nameDispenser.newName(_existingVariable.name);
variableReplacements[_existingVariable.name] = newName;
VariableDeclaration varDecl{_funCall.location, {{_funCall.location, newName, _existingVariable.type}}, {}};
VariableDeclaration varDecl{_funCall.debugData, {{_funCall.debugData, newName, _existingVariable.type}}, {}};
if (_value)
varDecl.value = make_unique<Expression>(std::move(*_value));
else
@ -290,10 +290,10 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
{
for (size_t i = 0; i < _assignment.variableNames.size(); ++i)
newStatements.emplace_back(Assignment{
_assignment.location,
_assignment.debugData,
{_assignment.variableNames[i]},
make_unique<Expression>(Identifier{
_assignment.location,
_assignment.debugData,
variableReplacements.at(function->returnVariables[i].name)
})
});
@ -302,10 +302,10 @@ vector<Statement> InlineModifier::performInline(Statement& _statement, FunctionC
{
for (size_t i = 0; i < _varDecl.variables.size(); ++i)
newStatements.emplace_back(VariableDeclaration{
_varDecl.location,
_varDecl.debugData,
{std::move(_varDecl.variables[i])},
make_unique<Expression>(Identifier{
_varDecl.location,
_varDecl.debugData,
variableReplacements.at(function->returnVariables[i].name)
})
});

View File

@ -35,7 +35,7 @@ void FunctionGrouper::operator()(Block& _block)
return;
vector<Statement> reordered;
reordered.emplace_back(Block{_block.location, {}});
reordered.emplace_back(Block{_block.debugData, {}});
for (auto&& statement: _block.statements)
{

View File

@ -41,7 +41,7 @@ void FunctionHoister::operator()(Block& _block)
if (holds_alternative<FunctionDefinition>(statement))
{
m_functions.emplace_back(std::move(statement));
statement = Block{_block.location, {}};
statement = Block{_block.debugData, {}};
}
}
removeEmptyBlocks(_block);

View File

@ -104,7 +104,7 @@ FunctionDefinition FunctionSpecializer::specialize(
if (argument)
missingVariableDeclarations.emplace_back(
VariableDeclaration{
_f.location,
_f.debugData,
vector<TypedName>{newFunction.parameters[index]},
make_unique<Expression>(move(*argument))
}

View File

@ -84,7 +84,7 @@ Expression KnowledgeBase::simplify(Expression _expression)
arg = simplify(arg);
if (auto match = SimplificationRules::findFirstMatch(_expression, m_dialect, m_variableValues))
return simplify(match->action().toExpression(locationOf(_expression)));
return simplify(match->action().toExpression(debugDataOf(_expression)));
return _expression;
}

View File

@ -85,12 +85,12 @@ void LoadResolver::tryResolve(
{
if (auto value = util::valueOrNullptr(m_storage, key))
if (inScope(*value))
_e = Identifier{locationOf(_e), *value};
_e = Identifier{debugDataOf(_e), *value};
}
else if (!m_containsMSize && _location == StoreLoadLocation::Memory)
if (auto value = util::valueOrNullptr(m_memory, key))
if (inScope(*value))
_e = Identifier{locationOf(_e), *value};
_e = Identifier{debugDataOf(_e), *value};
}
void LoadResolver::tryEvaluateKeccak(
@ -140,7 +140,7 @@ void LoadResolver::tryEvaluateKeccak(
bytes contentAsBytes = toBigEndian(*memoryContent);
contentAsBytes.resize(static_cast<size_t>(*byteLength));
_e = Literal{
locationOf(_e),
debugDataOf(_e),
LiteralKind::Number,
YulString{u256(keccak256(contentAsBytes)).str()},
m_dialect.defaultType

View File

@ -44,7 +44,7 @@ void MainFunction::operator()(Block& _block)
Block& block = std::get<Block>(_block.statements[0]);
FunctionDefinition main{
block.location,
block.debugData,
"main"_yulstring,
{},
{},

View File

@ -79,7 +79,7 @@ void ReasoningBasedSimplifier::operator()(If& _if)
if (result == CheckResult::UNSATISFIABLE)
{
Literal trueCondition = m_dialect.trueLiteral();
trueCondition.location = locationOf(*_if.condition);
trueCondition.debugData = debugDataOf(*_if.condition);
_if.condition = make_unique<yul::Expression>(move(trueCondition));
}
else
@ -91,7 +91,7 @@ void ReasoningBasedSimplifier::operator()(If& _if)
if (result2 == CheckResult::UNSATISFIABLE)
{
Literal falseCondition = m_dialect.zeroLiteralForType(m_dialect.boolType);
falseCondition.location = locationOf(*_if.condition);
falseCondition.debugData = debugDataOf(*_if.condition);
_if.condition = make_unique<yul::Expression>(move(falseCondition));
_if.body = yul::Block{};
// Nothing left to be done.

View File

@ -66,12 +66,12 @@ void SSAReverser::operator()(Block& _block)
else
return util::make_vector<Statement>(
Assignment{
std::move(assignment->location),
std::move(assignment->debugData),
assignment->variableNames,
std::move(varDecl->value)
},
VariableDeclaration{
std::move(varDecl->location),
std::move(varDecl->debugData),
std::move(varDecl->variables),
std::make_unique<Expression>(assignment->variableNames.front())
}
@ -97,17 +97,17 @@ void SSAReverser::operator()(Block& _block)
)
{
auto varIdentifier2 = std::make_unique<Expression>(Identifier{
varDecl2->variables.front().location,
varDecl2->variables.front().debugData,
varDecl2->variables.front().name
});
return util::make_vector<Statement>(
VariableDeclaration{
std::move(varDecl2->location),
std::move(varDecl2->debugData),
std::move(varDecl2->variables),
std::move(varDecl->value)
},
VariableDeclaration{
std::move(varDecl->location),
std::move(varDecl->debugData),
std::move(varDecl->variables),
std::move(varIdentifier2)
}

View File

@ -85,19 +85,19 @@ void IntroduceSSA::operator()(Block& _block)
// Replace "let a := v" by "let a_1 := v let a := a_1"
// Replace "let a, b := v" by "let a_1, b_1 := v let a := a_1 let b := b_2"
auto loc = varDecl.location;
shared_ptr<DebugData const> debugData = varDecl.debugData;
vector<Statement> statements;
statements.emplace_back(VariableDeclaration{loc, {}, std::move(varDecl.value)});
statements.emplace_back(VariableDeclaration{debugData, {}, std::move(varDecl.value)});
TypedNameList newVariables;
for (auto const& var: varDecl.variables)
{
YulString oldName = var.name;
YulString newName = m_nameDispenser.newName(oldName);
newVariables.emplace_back(TypedName{loc, newName, var.type});
newVariables.emplace_back(TypedName{debugData, newName, var.type});
statements.emplace_back(VariableDeclaration{
loc,
{TypedName{loc, oldName, var.type}},
make_unique<Expression>(Identifier{loc, newName})
debugData,
{TypedName{debugData, oldName, var.type}},
make_unique<Expression>(Identifier{debugData, newName})
});
}
std::get<VariableDeclaration>(statements.front()).variables = std::move(newVariables);
@ -112,23 +112,22 @@ void IntroduceSSA::operator()(Block& _block)
// Replace "a := v" by "let a_1 := v a := v"
// Replace "a, b := v" by "let a_1, b_1 := v a := a_1 b := b_2"
auto loc = assignment.location;
std::shared_ptr<DebugData const> debugData = assignment.debugData;
vector<Statement> statements;
statements.emplace_back(VariableDeclaration{loc, {}, std::move(assignment.value)});
statements.emplace_back(VariableDeclaration{debugData, {}, std::move(assignment.value)});
TypedNameList newVariables;
for (auto const& var: assignment.variableNames)
{
YulString oldName = var.name;
YulString newName = m_nameDispenser.newName(oldName);
newVariables.emplace_back(TypedName{
loc,
newVariables.emplace_back(TypedName{debugData,
newName,
m_typeInfo.typeOfVariable(oldName)
});
statements.emplace_back(Assignment{
loc,
{Identifier{loc, oldName}},
make_unique<Expression>(Identifier{loc, newName})
debugData,
{Identifier{debugData, oldName}},
make_unique<Expression>(Identifier{debugData, newName})
});
}
std::get<VariableDeclaration>(statements.front()).variables = std::move(newVariables);
@ -238,9 +237,9 @@ void IntroduceControlFlowSSA::operator()(Block& _block)
{
YulString newName = m_nameDispenser.newName(toReassign);
toPrepend.emplace_back(VariableDeclaration{
locationOf(_s),
{TypedName{locationOf(_s), newName, m_typeInfo.typeOfVariable(toReassign)}},
make_unique<Expression>(Identifier{locationOf(_s), toReassign})
debugDataOf(_s),
{TypedName{debugDataOf(_s), newName, m_typeInfo.typeOfVariable(toReassign)}},
make_unique<Expression>(Identifier{debugDataOf(_s), toReassign})
});
assignedVariables.insert(toReassign);
}

View File

@ -234,27 +234,26 @@ evmasm::Instruction Pattern::instruction() const
return m_instruction;
}
Expression Pattern::toExpression(SourceLocation const& _location) const
Expression Pattern::toExpression(shared_ptr<DebugData const> const& _debugData) const
{
if (matchGroup())
return ASTCopier().translate(matchGroupValue());
if (m_kind == PatternKind::Constant)
{
assertThrow(m_data, OptimizerException, "No match group and no constant value given.");
return Literal{_location, LiteralKind::Number, YulString{util::formatNumber(*m_data)}, {}};
return Literal{_debugData, LiteralKind::Number, YulString{util::formatNumber(*m_data)}, {}};
}
else if (m_kind == PatternKind::Operation)
{
vector<Expression> arguments;
for (auto const& arg: m_arguments)
arguments.emplace_back(arg.toExpression(_location));
arguments.emplace_back(arg.toExpression(_debugData));
string name = instructionInfo(m_instruction).name;
transform(begin(name), end(name), begin(name), [](auto _c) { return tolower(_c); });
return FunctionCall{
_location,
Identifier{_location, YulString{name}},
return FunctionCall{_debugData,
Identifier{_debugData, YulString{name}},
std::move(arguments)
};
}

View File

@ -130,7 +130,7 @@ public:
/// Turns this pattern into an actual expression. Should only be called
/// for patterns resulting from an action, i.e. with match groups assigned.
Expression toExpression(langutil::SourceLocation const& _location) const;
Expression toExpression(std::shared_ptr<DebugData const> const& _debugData) const;
private:
Expression const& matchGroupValue() const;

View File

@ -31,7 +31,7 @@ namespace
{
vector<Statement> generateMemoryStore(
Dialect const& _dialect,
langutil::SourceLocation const& _loc,
shared_ptr<DebugData const> const& _debugData,
YulString _mpos,
Expression _value
)
@ -39,26 +39,26 @@ vector<Statement> generateMemoryStore(
BuiltinFunction const* memoryStoreFunction = _dialect.memoryStoreFunction(_dialect.defaultType);
yulAssert(memoryStoreFunction, "");
vector<Statement> result;
result.emplace_back(ExpressionStatement{_loc, FunctionCall{
_loc,
Identifier{_loc, memoryStoreFunction->name},
result.emplace_back(ExpressionStatement{_debugData, FunctionCall{
_debugData,
Identifier{_debugData, memoryStoreFunction->name},
{
Literal{_loc, LiteralKind::Number, _mpos, {}},
Literal{_debugData, LiteralKind::Number, _mpos, {}},
std::move(_value)
}
}});
return result;
}
FunctionCall generateMemoryLoad(Dialect const& _dialect, langutil::SourceLocation const& _loc, YulString _mpos)
FunctionCall generateMemoryLoad(Dialect const& _dialect, std::shared_ptr<DebugData const> const& _debugData, YulString _mpos)
{
BuiltinFunction const* memoryLoadFunction = _dialect.memoryLoadFunction(_dialect.defaultType);
yulAssert(memoryLoadFunction, "");
return FunctionCall{
_loc,
Identifier{_loc, memoryLoadFunction->name}, {
_debugData,
Identifier{_debugData, memoryLoadFunction->name}, {
Literal{
_loc,
_debugData,
LiteralKind::Number,
_mpos,
{}
@ -123,39 +123,38 @@ void StackToMemoryMover::operator()(Block& _block)
if (!leftHandSideNeedsMoving)
return {};
langutil::SourceLocation loc = _stmt.location;
if (_variables.size() == 1)
{
optional<YulString> offset = m_memoryOffsetTracker(_variables.front().name);
yulAssert(offset, "");
return generateMemoryStore(
m_context.dialect,
loc,
_stmt.debugData,
*offset,
_stmt.value ? *std::move(_stmt.value) : Literal{loc, LiteralKind::Number, "0"_yulstring, {}}
_stmt.value ? *std::move(_stmt.value) : Literal{_stmt.debugData, LiteralKind::Number, "0"_yulstring, {}}
);
}
VariableDeclaration tempDecl{loc, {}, std::move(_stmt.value)};
VariableDeclaration tempDecl{_stmt.debugData, {}, std::move(_stmt.value)};
vector<Statement> memoryAssignments;
vector<Statement> variableAssignments;
for (auto& var: _variables)
{
YulString tempVarName = m_nameDispenser.newName(var.name);
tempDecl.variables.emplace_back(TypedName{var.location, tempVarName, {}});
tempDecl.variables.emplace_back(TypedName{var.debugData, tempVarName, {}});
if (optional<YulString> offset = m_memoryOffsetTracker(var.name))
memoryAssignments += generateMemoryStore(
m_context.dialect,
loc,
_stmt.debugData,
*offset,
Identifier{loc, tempVarName}
Identifier{_stmt.debugData, tempVarName}
);
else
variableAssignments.emplace_back(StatementType{
loc, {move(var)},
make_unique<Expression>(Identifier{loc, tempVarName})
_stmt.debugData,
{move(var)},
make_unique<Expression>(Identifier{_stmt.debugData, tempVarName})
});
}
std::vector<Statement> result;
@ -191,7 +190,7 @@ void StackToMemoryMover::visit(Expression& _expression)
ASTModifier::visit(_expression);
if (Identifier* identifier = std::get_if<Identifier>(&_expression))
if (optional<YulString> offset = m_memoryOffsetTracker(identifier->name))
_expression = generateMemoryLoad(m_context.dialect, identifier->location, *offset);
_expression = generateMemoryLoad(m_context.dialect, identifier->debugData, *offset);
}
optional<YulString> StackToMemoryMover::VariableMemoryOffsetTracker::operator()(YulString _variable) const

View File

@ -40,33 +40,31 @@ FunctionDefinition unusedFunctionsCommon::createLinkingFunction(
auto generateTypedName = [&](TypedName t)
{
return TypedName{
t.location,
t.debugData,
_nameDispenser.newName(t.name),
t.type
};
};
langutil::SourceLocation loc = _original.location;
FunctionDefinition linkingFunction{
loc,
_original.debugData,
_linkingFunctionName,
util::applyMap(_original.parameters, generateTypedName),
util::applyMap(_original.returnVariables, generateTypedName),
{loc, {}} // body
{_original.debugData, {}} // body
};
FunctionCall call{loc, Identifier{loc, _originalFunctionName}, {}};
FunctionCall call{_original.debugData, Identifier{_original.debugData, _originalFunctionName}, {}};
for (auto const& p: filter(linkingFunction.parameters, _usedParametersAndReturns.first))
call.arguments.emplace_back(Identifier{loc, p.name});
call.arguments.emplace_back(Identifier{_original.debugData, p.name});
Assignment assignment{loc, {}, nullptr};
Assignment assignment{_original.debugData, {}, nullptr};
for (auto const& r: filter(linkingFunction.returnVariables, _usedParametersAndReturns.second))
assignment.variableNames.emplace_back(Identifier{loc, r.name});
assignment.variableNames.emplace_back(Identifier{_original.debugData, r.name});
if (assignment.variableNames.empty())
linkingFunction.body.statements.emplace_back(ExpressionStatement{loc, std::move(call)});
linkingFunction.body.statements.emplace_back(ExpressionStatement{_original.debugData, std::move(call)});
else
{
assignment.value = std::make_unique<Expression>(std::move(call));

View File

@ -72,7 +72,7 @@ void UnusedPruner::operator()(Block& _block)
if (!used(funDef.name))
{
subtractReferences(ReferencesCounter::countReferences(funDef.body));
statement = Block{std::move(funDef.location), {}};
statement = Block{std::move(funDef.debugData), {}};
}
}
else if (holds_alternative<VariableDeclaration>(statement))
@ -90,19 +90,19 @@ void UnusedPruner::operator()(Block& _block)
))
{
if (!varDecl.value)
statement = Block{std::move(varDecl.location), {}};
statement = Block{std::move(varDecl.debugData), {}};
else if (
SideEffectsCollector(m_dialect, *varDecl.value, m_functionSideEffects).
canBeRemoved(m_allowMSizeOptimization)
)
{
subtractReferences(ReferencesCounter::countReferences(*varDecl.value));
statement = Block{std::move(varDecl.location), {}};
statement = Block{std::move(varDecl.debugData), {}};
}
else if (varDecl.variables.size() == 1 && m_dialect.discardFunction(varDecl.variables.front().type))
statement = ExpressionStatement{varDecl.location, FunctionCall{
varDecl.location,
{varDecl.location, m_dialect.discardFunction(varDecl.variables.front().type)->name},
statement = ExpressionStatement{varDecl.debugData, FunctionCall{
varDecl.debugData,
{varDecl.debugData, m_dialect.discardFunction(varDecl.variables.front().type)->name},
{*std::move(varDecl.value)}
}};
}
@ -116,7 +116,7 @@ void UnusedPruner::operator()(Block& _block)
)
{
subtractReferences(ReferencesCounter::countReferences(exprStmt.expression));
statement = Block{std::move(exprStmt.location), {}};
statement = Block{std::move(exprStmt.debugData), {}};
}
}

View File

@ -47,11 +47,10 @@ void VarDeclInitializer::operator()(Block& _block)
else
{
OptionalStatements ret{vector<Statement>{}};
langutil::SourceLocation loc{std::move(_varDecl.location)};
for (auto& var: _varDecl.variables)
{
unique_ptr<Expression> expr = make_unique<Expression >(m_dialect.zeroLiteralForType(var.type));
ret->emplace_back(VariableDeclaration{loc, {std::move(var)}, std::move(expr)});
ret->emplace_back(VariableDeclaration{std::move(_varDecl.debugData), {std::move(var)}, std::move(expr)});
}
return ret;
}

View File

@ -26,7 +26,6 @@
#include <liblangutil/SourceReferenceFormatter.h>
#include <libyul/optimiser/Disambiguator.h>
#include <libyul/AsmParser.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/AsmPrinter.h>
#include <libyul/AssemblyStack.h>

View File

@ -25,7 +25,6 @@
#include <libyul/backends/evm/EVMDialect.h>
#include <libyul/backends/wasm/WasmDialect.h>
#include <libyul/backends/wasm/EVMToEwasmTranslator.h>
#include <libyul/AsmParser.h>
#include <libyul/AssemblyStack.h>
#include <libyul/AsmAnalysisInfo.h>
#include <libyul/AST.h>

View File

@ -24,11 +24,11 @@
#include <test/libsolidity/ErrorCheck.h>
#include <test/libyul/Common.h>
#include <libyul/AST.h>
#include <libyul/AsmParser.h>
#include <libyul/AsmPrinter.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/AsmAnalysisInfo.h>
#include <libyul/AST.h>
#include <libyul/Dialect.h>
#include <liblangutil/Scanner.h>
#include <liblangutil/ErrorReporter.h>

View File

@ -18,7 +18,6 @@
#include <libyul/AsmAnalysis.h>
#include <libyul/AsmAnalysisInfo.h>
#include <libyul/AsmParser.h>
#include <liblangutil/EVMVersion.h>
#include <liblangutil/Exceptions.h>

View File

@ -23,7 +23,6 @@
#include <test/Common.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <libyul/AsmParser.h>
#include <libyul/AssemblyStack.h>
#include <libyul/AsmAnalysisInfo.h>

View File

@ -17,14 +17,12 @@
// SPDX-License-Identifier: GPL-3.0
#include <libyul/AsmAnalysisInfo.h>
#include <libyul/AsmParser.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/Dialect.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <libyul/AssemblyStack.h>
#include <liblangutil/Exceptions.h>
#include <liblangutil/ErrorReporter.h>
#include <liblangutil/EVMVersion.h>
#include <libsolutil/CommonIO.h>

View File

@ -22,14 +22,12 @@
#include <test/tools/yulInterpreter/Interpreter.h>
#include <libyul/AsmAnalysisInfo.h>
#include <libyul/AsmParser.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/Dialect.h>
#include <libyul/backends/evm/EVMDialect.h>
#include <libyul/AssemblyStack.h>
#include <liblangutil/Exceptions.h>
#include <liblangutil/ErrorReporter.h>
#include <liblangutil/EVMVersion.h>
#include <liblangutil/SourceReferenceFormatter.h>