diff --git a/libsolidity/analysis/ControlFlowBuilder.cpp b/libsolidity/analysis/ControlFlowBuilder.cpp index 8946e6ed3..5c179fbf5 100644 --- a/libsolidity/analysis/ControlFlowBuilder.cpp +++ b/libsolidity/analysis/ControlFlowBuilder.cpp @@ -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 ); } diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index aaa9c6ef9..abaeada03 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -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." ); diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index e0c288aeb..e57822ee1 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -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(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(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(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(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(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; } } diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index daf0f8625..87831972d 100644 --- a/libsolidity/analysis/ViewPureChecker.cpp +++ b/libsolidity/analysis/ViewPureChecker.cpp @@ -69,7 +69,7 @@ public: if (yul::EVMDialect const* dialect = dynamic_cast(&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); diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index 70ec98992..40cef6b8e 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -175,7 +175,7 @@ void ASTJsonConverter::appendExpressionAttributes( Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair _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"); diff --git a/libsolidity/ast/ASTJsonImporter.cpp b/libsolidity/ast/ASTJsonImporter.cpp index 0fa88ae3b..916dbac14 100644 --- a/libsolidity/ast/ASTJsonImporter.cpp +++ b/libsolidity/ast/ASTJsonImporter.cpp @@ -24,12 +24,10 @@ #include #include -#include #include #include #include -#include #include #include #include diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 434d9056e..ab1a67b96 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -28,11 +28,11 @@ #include #include +#include #include #include #include #include -#include #include #include #include @@ -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) diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp index 1eed9f04d..aeda4a794 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.cpp +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.cpp @@ -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}}; } diff --git a/libsolidity/interface/CompilerStack.cpp b/libsolidity/interface/CompilerStack.cpp index f29f5f137..12f3ceac7 100644 --- a/libsolidity/interface/CompilerStack.cpp +++ b/libsolidity/interface/CompilerStack.cpp @@ -61,8 +61,8 @@ #include #include #include -#include #include +#include #include #include diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index cad62e173..560d374c9 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -24,8 +24,8 @@ #include #include -#include #include +#include #include #include #include @@ -1299,7 +1299,7 @@ ASTPointer Parser::parseInlineAssembly(ASTPointer con if (block == nullptr) BOOST_THROW_EXCEPTION(FatalError()); - location.end = block->location.end; + location.end = block->debugData->location.end; return make_shared(nextID(), location, _docString, dialect, block); } diff --git a/libyul/AST.h b/libyul/AST.h index 09d39832f..54d44f6ae 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -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 create(langutil::SourceLocation _location = {}) + { + return std::make_shared(_location); + } +}; + +struct TypedName { std::shared_ptr debugData; YulString name; Type type; }; using TypedNameList = std::vector; /// 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; 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; 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 variableNames; std::unique_ptr value; }; -struct FunctionCall { langutil::SourceLocation location; Identifier functionName; std::vector arguments; }; +struct Assignment { std::shared_ptr debugData; std::vector variableNames; std::unique_ptr value; }; +struct FunctionCall { std::shared_ptr debugData; Identifier functionName; std::vector arguments; }; /// Statement that contains only a single expression -struct ExpressionStatement { langutil::SourceLocation location; Expression expression; }; +struct ExpressionStatement { std::shared_ptr 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 value; }; +struct VariableDeclaration { std::shared_ptr debugData; TypedNameList variables; std::unique_ptr value; }; /// Block that creates a scope (frees declared stack variables) -struct Block { langutil::SourceLocation location; std::vector statements; }; +struct Block { std::shared_ptr debugData; std::vector 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; YulString name; TypedNameList parameters; TypedNameList returnVariables; Block body; }; /// Conditional execution without "else" part. -struct If { langutil::SourceLocation location; std::unique_ptr condition; Block body; }; +struct If { std::shared_ptr debugData; std::unique_ptr condition; Block body; }; /// Switch case or default case -struct Case { langutil::SourceLocation location; std::unique_ptr value; Block body; }; +struct Case { std::shared_ptr debugData; std::unique_ptr value; Block body; }; /// Switch statement -struct Switch { langutil::SourceLocation location; std::unique_ptr expression; std::vector cases; }; -struct ForLoop { langutil::SourceLocation location; Block pre; std::unique_ptr condition; Block post; Block body; }; +struct Switch { std::shared_ptr debugData; std::unique_ptr expression; std::vector cases; }; +struct ForLoop { std::shared_ptr debugData; Block pre; std::unique_ptr condition; Block post; Block body; }; /// Break statement (valid within for loop) -struct Break { langutil::SourceLocation location; }; +struct Break { std::shared_ptr debugData; }; /// Continue statement (valid within for loop) -struct Continue { langutil::SourceLocation location; }; +struct Continue { std::shared_ptr debugData; }; /// Leave statement (valid within function) -struct Leave { langutil::SourceLocation location; }; +struct Leave { std::shared_ptr debugData; }; struct LocationExtractor { template 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 inline langutil::SourceLocation locationOf(T const& _node) { return std::visit(LocationExtractor(), _node); } +struct DebugDataExtractor +{ + template std::shared_ptr const& operator()(T const& _node) const + { + return _node.debugData; + } +}; + +/// Extracts the debug data from a Yul node. +template inline std::shared_ptr const& debugDataOf(T const& _node) +{ + return std::visit(DebugDataExtractor(), _node); +} + } diff --git a/libyul/ASTForward.h b/libyul/ASTForward.h index a4dc5be3f..0e61c6ca1 100644 --- a/libyul/ASTForward.h +++ b/libyul/ASTForward.h @@ -28,6 +28,7 @@ namespace solidity::yul { +struct DebugData; enum class LiteralKind; struct Literal; struct Label; diff --git a/libyul/AsmAnalysis.cpp b/libyul/AsmAnalysis.cpp index d3b5cd890..a6b0e729c 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -98,22 +98,22 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect, vector 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 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 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 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(varScope.identifiers.at(var.name))); } @@ -315,7 +315,7 @@ vector 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 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 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 AsmAnalyzer::operator()(FunctionCall const& _funCall) if (!holds_alternative(arg)) m_errorReporter.typeError( 9114_error, - _funCall.functionName.location, + _funCall.functionName.debugData->location, "Function expects direct literals as arguments." ); else if (*literalArgumentKind != get(arg).kind) m_errorReporter.typeError( 5859_error, - get(arg).location, + get(arg).debugData->location, "Function expects " + to_string(*literalArgumentKind) + " literal." ); else if (*literalArgumentKind == LiteralKind::String) @@ -375,7 +375,7 @@ vector AsmAnalyzer::operator()(FunctionCall const& _funCall) if (!m_dataNames.count(get(arg).value)) m_errorReporter.typeError( 3517_error, - get(arg).location, + get(arg).debugData->location, "Unknown data object \"" + std::get(arg).value.str() + "\"." ); } @@ -384,7 +384,7 @@ vector AsmAnalyzer::operator()(FunctionCall const& _funCall) if (get(arg).value.empty()) m_errorReporter.typeError( 1844_error, - get(arg).location, + get(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(*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(*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); } diff --git a/libyul/AsmJsonConverter.cpp b/libyul/AsmJsonConverter.cpp index aece124aa..582d95a82 100644 --- a/libyul/AsmJsonConverter.cpp +++ b/libyul/AsmJsonConverter.cpp @@ -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 diff --git a/libyul/AsmJsonImporter.cpp b/libyul/AsmJsonImporter.cpp index bbcd1b9a7..410bdbed5 100644 --- a/libyul/AsmJsonImporter.cpp +++ b/libyul/AsmJsonImporter.cpp @@ -52,11 +52,12 @@ template 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; } diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 408fadf7a..20a0e9f03 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -21,8 +21,8 @@ * Solidity inline assembly parser. */ -#include #include +#include #include #include #include @@ -40,6 +40,21 @@ using namespace solidity::util; using namespace solidity::langutil; using namespace solidity::yul; +namespace { + +[[nodiscard]] +shared_ptr updateLocationEndFrom( + shared_ptr const& _debugData, + langutil::SourceLocation const& _location +) +{ + SourceLocation updatedLocation = _debugData->location; + updatedLocation.end = _location.end; + return make_shared(updatedLocation); +} + +} + unique_ptr Parser::parse(std::shared_ptr 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(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 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 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 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(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&& _initialOp) FunctionCall ret; ret.functionName = std::move(std::get(_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&& _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 diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index d1294b111..896cb6d51 100644 --- a/libyul/AsmParser.h +++ b/libyul/AsmParser.h @@ -70,7 +70,7 @@ protected: template T createWithLocation() const { T r; - r.location = currentLocation(); + r.debugData = DebugData::create(currentLocation()); return r; } diff --git a/libyul/AssemblyStack.cpp b/libyul/AssemblyStack.cpp index 0f52bdaa2..4eb655fb6 100644 --- a/libyul/AssemblyStack.cpp +++ b/libyul/AssemblyStack.cpp @@ -25,7 +25,6 @@ #include #include -#include #include #include #include diff --git a/libyul/Dialect.cpp b/libyul/Dialect.cpp index 847c9f1ac..9ed18a21e 100644 --- a/libyul/Dialect.cpp +++ b/libyul/Dialect.cpp @@ -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 diff --git a/libyul/ObjectParser.cpp b/libyul/ObjectParser.cpp index 4385c2b3b..d2eb1feca 100644 --- a/libyul/ObjectParser.cpp +++ b/libyul/ObjectParser.cpp @@ -19,10 +19,10 @@ * Parser for Yul code and data object container. */ +#include #include #include -#include #include #include diff --git a/libyul/ScopeFiller.cpp b/libyul/ScopeFiller.cpp index 691bdc981..5c4599eda 100644 --- a/libyul/ScopeFiller.cpp +++ b/libyul/ScopeFiller.cpp @@ -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; diff --git a/libyul/backends/evm/AbstractAssembly.h b/libyul/backends/evm/AbstractAssembly.h index 1eb5a3fd8..18d36953a 100644 --- a/libyul/backends/evm/AbstractAssembly.h +++ b/libyul/backends/evm/AbstractAssembly.h @@ -23,6 +23,8 @@ #pragma once +#include + #include #include diff --git a/libyul/backends/evm/ConstantOptimiser.cpp b/libyul/backends/evm/ConstantOptimiser.cpp index d37ddade1..09d87da83 100644 --- a/libyul/backends/evm/ConstantOptimiser.cpp +++ b/libyul/backends/evm/ConstantOptimiser.cpp @@ -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(Literal{m_location, LiteralKind::Number, YulString{formatNumber(_value)}, {}}); + repr.expression = make_unique(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(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(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; diff --git a/libyul/backends/evm/ConstantOptimiser.h b/libyul/backends/evm/ConstantOptimiser.h index e95a152c8..a60d2b2f5 100644 --- a/libyul/backends/evm/ConstantOptimiser.h +++ b/libyul/backends/evm/ConstantOptimiser.h @@ -74,12 +74,12 @@ public: RepresentationFinder( EVMDialect const& _dialect, GasMeter const& _meter, - langutil::SourceLocation _location, + std::shared_ptr _debugData, std::map& _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 m_debugData; /// Counter for the complexity of optimization, will stop when it reaches zero. size_t m_maxSteps = 10000; std::map& m_cache; diff --git a/libyul/backends/evm/EVMAssembly.cpp b/libyul/backends/evm/EVMAssembly.cpp index 949f89c9d..63f54419f 100644 --- a/libyul/backends/evm/EVMAssembly.cpp +++ b/libyul/backends/evm/EVMAssembly.cpp @@ -39,7 +39,7 @@ size_t constexpr assemblySizeReferenceSize = 4; } -void EVMAssembly::setSourceLocation(SourceLocation const&) +void EVMAssembly::setSourceLocation(langutil::SourceLocation const&) { // Ignored for now; } diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index e357a071c..49bfed968 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -44,6 +44,16 @@ using namespace solidity; using namespace solidity::yul; using namespace solidity::util; +namespace +{ + +langutil::SourceLocation extractSourceLocationFromDebugData(shared_ptr 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(_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::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(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 const& _statements) auto const* functionDefinition = std::get_if(&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 const& _statements) void CodeTransform::finalizeBlock(Block const& _block, optional blockStartStackHeight) { - m_assembly.setSourceLocation(_block.location); + m_assembly.setSourceLocation(extractSourceLocationFromDebugData(_block.debugData)); freeUnusedVariables(); diff --git a/libyul/backends/evm/EVMCodeTransform.h b/libyul/backends/evm/EVMCodeTransform.h index be7fef528..531861a6e 100644 --- a/libyul/backends/evm/EVMCodeTransform.h +++ b/libyul/backends/evm/EVMCodeTransform.h @@ -39,6 +39,7 @@ class ErrorReporter; namespace solidity::yul { + struct AsmAnalysisInfo; class EVMAssembly; diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index dda28f19e..90e5b2815 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -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 createBuiltins(langutil::EVMVersion _evmVe _visitExpression(_call.arguments[2]); YulString identifier = std::get(_call.arguments[1]).value; _visitExpression(_call.arguments[0]); - _assembly.setSourceLocation(_call.location); + _assembly.setSourceLocation(_call.debugData->location); _assembly.appendImmutableAssignment(identifier.str()); } )); diff --git a/libyul/backends/wasm/EVMToEwasmTranslator.cpp b/libyul/backends/wasm/EVMToEwasmTranslator.cpp index a2723533d..074174532 100644 --- a/libyul/backends/wasm/EVMToEwasmTranslator.cpp +++ b/libyul/backends/wasm/EVMToEwasmTranslator.cpp @@ -32,10 +32,10 @@ #include #include +#include #include #include #include -#include #include #include diff --git a/libyul/backends/wasm/WordSizeTransform.cpp b/libyul/backends/wasm/WordSizeTransform.cpp index ec5e3a0de..e796b1f8f 100644 --- a/libyul/backends/wasm/WordSizeTransform.cpp +++ b/libyul/backends/wasm/WordSizeTransform.cpp @@ -65,8 +65,8 @@ void WordSizeTransform::operator()(FunctionCall& _fc) void WordSizeTransform::operator()(If& _if) { _if.condition = make_unique(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(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 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(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 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 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(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 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& _ids) { vector 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 WordSizeTransform::handleSwitchInternal( - langutil::SourceLocation const& _location, + shared_ptr const& _debugData, vector const& _splitExpressions, vector _cases, YulString _runDefaultFlag, @@ -304,19 +304,19 @@ vector WordSizeTransform::handleSwitchInternal( } Switch ret{ - _location, - make_unique(Identifier{_location, _splitExpressions.at(_depth)}), + _debugData, + make_unique(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(std::move(label)), - Block{_location, handleSwitchInternal( - _location, + Block{_debugData, handleSwitchInternal( + _debugData, _splitExpressions, std::move(c.second), _runDefaultFlag, @@ -326,13 +326,13 @@ vector WordSizeTransform::handleSwitchInternal( } if (!_runDefaultFlag.empty()) ret.cases.emplace_back(Case{ - _location, + _debugData, nullptr, - Block{_location, make_vector( + Block{_debugData, make_vector( Assignment{ - _location, - {{_location, _runDefaultFlag}}, - make_unique(Literal{_location, LiteralKind::Boolean, "true"_yulstring, m_targetDialect.boolType}) + _debugData, + {{_debugData, _runDefaultFlag}}, + make_unique(Literal{_debugData, LiteralKind::Boolean, "true"_yulstring, m_targetDialect.boolType}) } )} }); @@ -356,8 +356,8 @@ std::vector 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 WordSizeTransform::handleSwitch(Switch& _switch) splitExpressions.emplace_back(std::get(*expr).name); ret += handleSwitchInternal( - _switch.location, + _switch.debugData, splitExpressions, std::move(_switch.cases), runDefaultFlag, @@ -374,8 +374,8 @@ std::vector WordSizeTransform::handleSwitch(Switch& _switch) ); if (!runDefaultFlag.empty()) ret.emplace_back(If{ - _switch.location, - make_unique(Identifier{_switch.location, runDefaultFlag}), + _switch.debugData, + make_unique(Identifier{_switch.debugData, runDefaultFlag}), std::move(defaultCase.body) }); return ret; @@ -397,7 +397,7 @@ array, 4> WordSizeTransform::expandValue(Expression const { auto const& id = std::get(_e); for (size_t i = 0; i < 4; i++) - ret[i] = make_unique(Identifier{id.location, m_variableMapping.at(id.name)[i]}); + ret[i] = make_unique(Identifier{id.debugData, m_variableMapping.at(id.name)[i]}); } else if (holds_alternative(_e)) { @@ -410,7 +410,7 @@ array, 4> WordSizeTransform::expandValue(Expression const val >>= 64; ret[exprIndexReverse] = make_unique( Literal{ - lit.location, + lit.debugData, LiteralKind::Number, YulString(currentVal.str()), m_targetDialect.defaultType diff --git a/libyul/backends/wasm/WordSizeTransform.h b/libyul/backends/wasm/WordSizeTransform.h index 1bf7dcaca..faa7806a5 100644 --- a/libyul/backends/wasm/WordSizeTransform.h +++ b/libyul/backends/wasm/WordSizeTransform.h @@ -87,7 +87,7 @@ private: std::vector handleSwitch(Switch& _switch); std::vector handleSwitchInternal( - langutil::SourceLocation const& _location, + std::shared_ptr const& _debugData, std::vector const& _splitExpressions, std::vector _cases, YulString _runDefaultFlag, diff --git a/libyul/optimiser/ASTCopier.cpp b/libyul/optimiser/ASTCopier.cpp index 8c0b3acfa..6117e0bfa 100644 --- a/libyul/optimiser/ASTCopier.cpp +++ b/libyul/optimiser/ASTCopier.cpp @@ -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) diff --git a/libyul/optimiser/CommonSubexpressionEliminator.cpp b/libyul/optimiser/CommonSubexpressionEliminator.cpp index c2b5f8a42..2725db395 100644 --- a/libyul/optimiser/CommonSubexpressionEliminator.cpp +++ b/libyul/optimiser/CommonSubexpressionEliminator.cpp @@ -95,13 +95,13 @@ void CommonSubexpressionEliminator::visit(Expression& _e) if (Identifier const* identifier = get_if(&_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(m_value.at(name).value)) + assertThrow(m_value.at(identifierName).value, OptimizerException, ""); + if (Identifier const* value = get_if(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; } } diff --git a/libyul/optimiser/ConditionalSimplifier.cpp b/libyul/optimiser/ConditionalSimplifier.cpp index 0a66e28df..78fcb174e 100644 --- a/libyul/optimiser/ConditionalSimplifier.cpp +++ b/libyul/optimiser/ConditionalSimplifier.cpp @@ -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(*_case.value) } ); @@ -72,12 +72,12 @@ void ConditionalSimplifier::operator()(Block& _block) ) { YulString condition = std::get(*_if.condition).name; - langutil::SourceLocation location = _if.location; + std::shared_ptr debugData = _if.debugData; return make_vector( std::move(_s), Assignment{ - location, - {Identifier{location, condition}}, + debugData, + {Identifier{debugData, condition}}, make_unique(m_dialect.zeroLiteralForType(m_dialect.boolType)) } ); diff --git a/libyul/optimiser/ControlFlowSimplifier.cpp b/libyul/optimiser/ControlFlowSimplifier.cpp index 73d907d33..443a2a9be 100644 --- a/libyul/optimiser/ControlFlowSimplifier.cpp +++ b/libyul/optimiser/ControlFlowSimplifier.cpp @@ -38,14 +38,14 @@ namespace { ExpressionStatement makeDiscardCall( - langutil::SourceLocation const& _location, + std::shared_ptr 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& _statements) { OptionalStatements s = vector{}; 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(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 = debugDataOf(*_switchStmt.expression); YulString type = m_typeInfo.typeOf(*_switchStmt.expression); if (switchCase.value) { if (!m_dialect.equalityFunction(type)) return {}; return make_vector(If{ - std::move(_switchStmt.location), + std::move(_switchStmt.debugData), make_unique(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( makeDiscardCall( - loc, + debugData, *m_dialect.discardFunction(type), std::move(*_switchStmt.expression) ), diff --git a/libyul/optimiser/ExpressionSimplifier.cpp b/libyul/optimiser/ExpressionSimplifier.cpp index 21107c026..736ebe4b9 100644 --- a/libyul/optimiser/ExpressionSimplifier.cpp +++ b/libyul/optimiser/ExpressionSimplifier.cpp @@ -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)); } diff --git a/libyul/optimiser/ExpressionSplitter.cpp b/libyul/optimiser/ExpressionSplitter.cpp index 7aad0bd58..b93b55613 100644 --- a/libyul/optimiser/ExpressionSplitter.cpp +++ b/libyul/optimiser/ExpressionSplitter.cpp @@ -101,15 +101,15 @@ void ExpressionSplitter::outlineExpression(Expression& _expr) visit(_expr); - SourceLocation location = locationOf(_expr); + shared_ptr 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(std::move(_expr)) }); - _expr = Identifier{location, var}; + _expr = Identifier{debugData, var}; m_typeInfo.setVariableType(var, type); } diff --git a/libyul/optimiser/ForLoopConditionIntoBody.cpp b/libyul/optimiser/ForLoopConditionIntoBody.cpp index 059479757..cf7c6814e 100644 --- a/libyul/optimiser/ForLoopConditionIntoBody.cpp +++ b/libyul/optimiser/ForLoopConditionIntoBody.cpp @@ -39,25 +39,25 @@ void ForLoopConditionIntoBody::operator()(ForLoop& _forLoop) !holds_alternative(*_forLoop.condition) ) { - langutil::SourceLocation const loc = locationOf(*_forLoop.condition); + shared_ptr debugData = debugDataOf(*_forLoop.condition); _forLoop.body.statements.emplace( begin(_forLoop.body.statements), If { - loc, + debugData, make_unique( FunctionCall { - loc, - {loc, m_dialect.booleanNegationFunction()->name}, + debugData, + {debugData, m_dialect.booleanNegationFunction()->name}, util::make_vector(std::move(*_forLoop.condition)) } ), - Block {loc, util::make_vector(Break{{}})} + Block {debugData, util::make_vector(Break{{}})} } ); _forLoop.condition = make_unique( Literal { - loc, + debugData, LiteralKind::Boolean, "true"_yulstring, m_dialect.boolType diff --git a/libyul/optimiser/ForLoopConditionOutOfBody.cpp b/libyul/optimiser/ForLoopConditionOutOfBody.cpp index 1ddc3c257..98a37d9fc 100644 --- a/libyul/optimiser/ForLoopConditionOutOfBody.cpp +++ b/libyul/optimiser/ForLoopConditionOutOfBody.cpp @@ -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 = debugDataOf(*firstStatement.condition); if ( holds_alternative(*firstStatement.condition) && @@ -64,8 +64,8 @@ void ForLoopConditionOutOfBody::operator()(ForLoop& _forLoop) _forLoop.condition = make_unique(std::move(std::get(*firstStatement.condition).arguments.front())); else _forLoop.condition = make_unique(FunctionCall{ - location, - Identifier{location, iszero}, + debugData, + Identifier{debugData, iszero}, util::make_vector( std::move(*firstStatement.condition) ) diff --git a/libyul/optimiser/FullInliner.cpp b/libyul/optimiser/FullInliner.cpp index 189a06164..0a494a31f 100644 --- a/libyul/optimiser/FullInliner.cpp +++ b/libyul/optimiser/FullInliner.cpp @@ -268,7 +268,7 @@ vector 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(std::move(*_value)); else @@ -290,10 +290,10 @@ vector 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(Identifier{ - _assignment.location, + _assignment.debugData, variableReplacements.at(function->returnVariables[i].name) }) }); @@ -302,10 +302,10 @@ vector 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(Identifier{ - _varDecl.location, + _varDecl.debugData, variableReplacements.at(function->returnVariables[i].name) }) }); diff --git a/libyul/optimiser/FunctionGrouper.cpp b/libyul/optimiser/FunctionGrouper.cpp index 2ed92435e..41fb75554 100644 --- a/libyul/optimiser/FunctionGrouper.cpp +++ b/libyul/optimiser/FunctionGrouper.cpp @@ -35,7 +35,7 @@ void FunctionGrouper::operator()(Block& _block) return; vector reordered; - reordered.emplace_back(Block{_block.location, {}}); + reordered.emplace_back(Block{_block.debugData, {}}); for (auto&& statement: _block.statements) { diff --git a/libyul/optimiser/FunctionHoister.cpp b/libyul/optimiser/FunctionHoister.cpp index aa5c373e9..5d5cf7d12 100644 --- a/libyul/optimiser/FunctionHoister.cpp +++ b/libyul/optimiser/FunctionHoister.cpp @@ -41,7 +41,7 @@ void FunctionHoister::operator()(Block& _block) if (holds_alternative(statement)) { m_functions.emplace_back(std::move(statement)); - statement = Block{_block.location, {}}; + statement = Block{_block.debugData, {}}; } } removeEmptyBlocks(_block); diff --git a/libyul/optimiser/FunctionSpecializer.cpp b/libyul/optimiser/FunctionSpecializer.cpp index 65f092487..1d14db18b 100644 --- a/libyul/optimiser/FunctionSpecializer.cpp +++ b/libyul/optimiser/FunctionSpecializer.cpp @@ -104,7 +104,7 @@ FunctionDefinition FunctionSpecializer::specialize( if (argument) missingVariableDeclarations.emplace_back( VariableDeclaration{ - _f.location, + _f.debugData, vector{newFunction.parameters[index]}, make_unique(move(*argument)) } diff --git a/libyul/optimiser/KnowledgeBase.cpp b/libyul/optimiser/KnowledgeBase.cpp index 623db6a70..059c9d40c 100644 --- a/libyul/optimiser/KnowledgeBase.cpp +++ b/libyul/optimiser/KnowledgeBase.cpp @@ -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; } diff --git a/libyul/optimiser/LoadResolver.cpp b/libyul/optimiser/LoadResolver.cpp index 3ef080155..2716be3bd 100644 --- a/libyul/optimiser/LoadResolver.cpp +++ b/libyul/optimiser/LoadResolver.cpp @@ -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(*byteLength)); _e = Literal{ - locationOf(_e), + debugDataOf(_e), LiteralKind::Number, YulString{u256(keccak256(contentAsBytes)).str()}, m_dialect.defaultType diff --git a/libyul/optimiser/MainFunction.cpp b/libyul/optimiser/MainFunction.cpp index 646bc8faf..8adabbe32 100644 --- a/libyul/optimiser/MainFunction.cpp +++ b/libyul/optimiser/MainFunction.cpp @@ -44,7 +44,7 @@ void MainFunction::operator()(Block& _block) Block& block = std::get(_block.statements[0]); FunctionDefinition main{ - block.location, + block.debugData, "main"_yulstring, {}, {}, diff --git a/libyul/optimiser/ReasoningBasedSimplifier.cpp b/libyul/optimiser/ReasoningBasedSimplifier.cpp index b428cbab5..e75ca3cf5 100644 --- a/libyul/optimiser/ReasoningBasedSimplifier.cpp +++ b/libyul/optimiser/ReasoningBasedSimplifier.cpp @@ -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(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(move(falseCondition)); _if.body = yul::Block{}; // Nothing left to be done. diff --git a/libyul/optimiser/SSAReverser.cpp b/libyul/optimiser/SSAReverser.cpp index d59a93d0e..d6bf7138a 100644 --- a/libyul/optimiser/SSAReverser.cpp +++ b/libyul/optimiser/SSAReverser.cpp @@ -66,12 +66,12 @@ void SSAReverser::operator()(Block& _block) else return util::make_vector( 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(assignment->variableNames.front()) } @@ -97,17 +97,17 @@ void SSAReverser::operator()(Block& _block) ) { auto varIdentifier2 = std::make_unique(Identifier{ - varDecl2->variables.front().location, + varDecl2->variables.front().debugData, varDecl2->variables.front().name }); return util::make_vector( 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) } diff --git a/libyul/optimiser/SSATransform.cpp b/libyul/optimiser/SSATransform.cpp index f77e836f2..f0ce68c92 100644 --- a/libyul/optimiser/SSATransform.cpp +++ b/libyul/optimiser/SSATransform.cpp @@ -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 = varDecl.debugData; vector 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(Identifier{loc, newName}) + debugData, + {TypedName{debugData, oldName, var.type}}, + make_unique(Identifier{debugData, newName}) }); } std::get(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 = assignment.debugData; vector 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(Identifier{loc, newName}) + debugData, + {Identifier{debugData, oldName}}, + make_unique(Identifier{debugData, newName}) }); } std::get(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(Identifier{locationOf(_s), toReassign}) + debugDataOf(_s), + {TypedName{debugDataOf(_s), newName, m_typeInfo.typeOfVariable(toReassign)}}, + make_unique(Identifier{debugDataOf(_s), toReassign}) }); assignedVariables.insert(toReassign); } diff --git a/libyul/optimiser/SimplificationRules.cpp b/libyul/optimiser/SimplificationRules.cpp index 8e55e8c5e..4a0e0668c 100644 --- a/libyul/optimiser/SimplificationRules.cpp +++ b/libyul/optimiser/SimplificationRules.cpp @@ -234,27 +234,26 @@ evmasm::Instruction Pattern::instruction() const return m_instruction; } -Expression Pattern::toExpression(SourceLocation const& _location) const +Expression Pattern::toExpression(shared_ptr 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 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) }; } diff --git a/libyul/optimiser/SimplificationRules.h b/libyul/optimiser/SimplificationRules.h index f9d0c9da9..d4da4a2b0 100644 --- a/libyul/optimiser/SimplificationRules.h +++ b/libyul/optimiser/SimplificationRules.h @@ -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 const& _debugData) const; private: Expression const& matchGroupValue() const; diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index 25eb25cd5..3e2d72cad 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -31,7 +31,7 @@ namespace { vector generateMemoryStore( Dialect const& _dialect, - langutil::SourceLocation const& _loc, + shared_ptr const& _debugData, YulString _mpos, Expression _value ) @@ -39,26 +39,26 @@ vector generateMemoryStore( BuiltinFunction const* memoryStoreFunction = _dialect.memoryStoreFunction(_dialect.defaultType); yulAssert(memoryStoreFunction, ""); vector 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 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 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 memoryAssignments; vector 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 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(Identifier{loc, tempVarName}) + _stmt.debugData, + {move(var)}, + make_unique(Identifier{_stmt.debugData, tempVarName}) }); } std::vector result; @@ -191,7 +190,7 @@ void StackToMemoryMover::visit(Expression& _expression) ASTModifier::visit(_expression); if (Identifier* identifier = std::get_if(&_expression)) if (optional offset = m_memoryOffsetTracker(identifier->name)) - _expression = generateMemoryLoad(m_context.dialect, identifier->location, *offset); + _expression = generateMemoryLoad(m_context.dialect, identifier->debugData, *offset); } optional StackToMemoryMover::VariableMemoryOffsetTracker::operator()(YulString _variable) const diff --git a/libyul/optimiser/UnusedFunctionsCommon.cpp b/libyul/optimiser/UnusedFunctionsCommon.cpp index db2ca5dee..161a51b97 100644 --- a/libyul/optimiser/UnusedFunctionsCommon.cpp +++ b/libyul/optimiser/UnusedFunctionsCommon.cpp @@ -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(std::move(call)); diff --git a/libyul/optimiser/UnusedPruner.cpp b/libyul/optimiser/UnusedPruner.cpp index b0b4b794c..dae4d4c6f 100644 --- a/libyul/optimiser/UnusedPruner.cpp +++ b/libyul/optimiser/UnusedPruner.cpp @@ -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(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), {}}; } } diff --git a/libyul/optimiser/VarDeclInitializer.cpp b/libyul/optimiser/VarDeclInitializer.cpp index dc3e27c2a..9b96bef3b 100644 --- a/libyul/optimiser/VarDeclInitializer.cpp +++ b/libyul/optimiser/VarDeclInitializer.cpp @@ -47,11 +47,10 @@ void VarDeclInitializer::operator()(Block& _block) else { OptionalStatements ret{vector{}}; - langutil::SourceLocation loc{std::move(_varDecl.location)}; for (auto& var: _varDecl.variables) { unique_ptr expr = make_unique(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; } diff --git a/test/libyul/Common.cpp b/test/libyul/Common.cpp index 547f665b9..35dd0de26 100644 --- a/test/libyul/Common.cpp +++ b/test/libyul/Common.cpp @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/test/libyul/EwasmTranslationTest.cpp b/test/libyul/EwasmTranslationTest.cpp index 15ddfb86e..3c5e6cacb 100644 --- a/test/libyul/EwasmTranslationTest.cpp +++ b/test/libyul/EwasmTranslationTest.cpp @@ -25,7 +25,6 @@ #include #include #include -#include #include #include #include diff --git a/test/libyul/Parser.cpp b/test/libyul/Parser.cpp index b4a848267..6bb34064e 100644 --- a/test/libyul/Parser.cpp +++ b/test/libyul/Parser.cpp @@ -24,11 +24,11 @@ #include #include +#include #include #include #include #include -#include #include #include #include diff --git a/test/libyul/SyntaxTest.cpp b/test/libyul/SyntaxTest.cpp index 21d295058..4668773e9 100644 --- a/test/libyul/SyntaxTest.cpp +++ b/test/libyul/SyntaxTest.cpp @@ -18,7 +18,6 @@ #include #include -#include #include #include diff --git a/test/libyul/YulInterpreterTest.cpp b/test/libyul/YulInterpreterTest.cpp index 11e85d66b..f275e38a4 100644 --- a/test/libyul/YulInterpreterTest.cpp +++ b/test/libyul/YulInterpreterTest.cpp @@ -23,7 +23,6 @@ #include #include -#include #include #include diff --git a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp index 4a097d2b7..6c7bc61cb 100644 --- a/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp +++ b/test/tools/ossfuzz/strictasm_diff_ossfuzz.cpp @@ -17,14 +17,12 @@ // SPDX-License-Identifier: GPL-3.0 #include -#include #include #include #include #include #include -#include #include #include diff --git a/test/tools/yulrun.cpp b/test/tools/yulrun.cpp index 3cc16c56f..9f764f539 100644 --- a/test/tools/yulrun.cpp +++ b/test/tools/yulrun.cpp @@ -22,14 +22,12 @@ #include #include -#include #include #include #include #include #include -#include #include #include