diff --git a/libsolidity/analysis/ControlFlowBuilder.cpp b/libsolidity/analysis/ControlFlowBuilder.cpp index 8946e6ed3..f0fc92e13 100644 --- a/libsolidity/analysis/ControlFlowBuilder.cpp +++ b/libsolidity/analysis/ControlFlowBuilder.cpp @@ -390,7 +390,7 @@ bool ControlFlowBuilder::visit(InlineAssembly const& _inlineAssembly) void ControlFlowBuilder::visit(yul::Statement const& _statement) { solAssert(m_currentNode && m_inlineAssembly, ""); - m_currentNode->location = langutil::SourceLocation::smallestCovering(m_currentNode->location, locationOf(_statement)); + m_currentNode->location = langutil::SourceLocation::smallestCovering(m_currentNode->location, locationOf(_statement)->irLocation); ASTWalker::visit(_statement); } @@ -482,8 +482,7 @@ void ControlFlowBuilder::operator()(yul::Identifier const& _identifier) m_currentNode->variableOccurrences.emplace_back( *declaration, VariableOccurrence::Kind::Access, - _identifier.location - ); + _identifier.debugData->irLocation); } } @@ -498,8 +497,7 @@ void ControlFlowBuilder::operator()(yul::Assignment const& _assignment) m_currentNode->variableOccurrences.emplace_back( *declaration, VariableOccurrence::Kind::Assignment, - variable.location - ); + variable.debugData->irLocation); } void ControlFlowBuilder::operator()(yul::FunctionCall const& _functionCall) diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index aaa9c6ef9..cdb23d926 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->irLocation); for (yul::TypedName const& varName: _function.parameters + _function.returnVariables) - validateYulIdentifierName(varName.name, varName.location); + validateYulIdentifierName(varName.name, varName.debugData->irLocation); 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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation); 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->irLocation, ssl, "This declaration shadows a declaration outside the inline assembly block." ); diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index d13c2eaae..c7534cc70 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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "Expected a library."); return false; } } diff --git a/libsolidity/analysis/ViewPureChecker.cpp b/libsolidity/analysis/ViewPureChecker.cpp index daf0f8625..6c4ab0daf 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->irLocation, *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 b3aa47b00..38b0bc6f2 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->irLocation); 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/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 88b7770ad..0e3c562bb 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -426,7 +426,7 @@ void CompilerContext::appendInlineAssembly( if (stackDiff < 1 || stackDiff > 16) BOOST_THROW_EXCEPTION( StackTooDeepError() << - errinfo_sourceLocation(_identifier.location) << + errinfo_sourceLocation(_identifier.debugData->irLocation) << 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 e59fde079..1e8ab7857 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}}; } @@ -3167,6 +3167,23 @@ bool IRGeneratorForStatements::visit(TryCatchClause const& _clause) void IRGeneratorForStatements::setLocation(ASTNode const& _node) { m_currentLocation = _node.location(); + appendCurrentLocation(); +} + +void IRGeneratorForStatements::appendCurrentLocation() +{ + if (m_currentLocation.isValid() && m_code.tellp() != m_lastSourceLocationPosition) + { + m_code << + "/// @origin " << + m_currentLocation.source->name() << + ":" << + m_currentLocation.start << + "," << + m_currentLocation.end << + "\n"; + m_lastSourceLocationPosition = m_code.tellp(); + } } string IRGeneratorForStatements::linkerSymbol(ContractDefinition const& _library) const diff --git a/libsolidity/codegen/ir/IRGeneratorForStatements.h b/libsolidity/codegen/ir/IRGeneratorForStatements.h index 90504aa7f..d3da9ee52 100644 --- a/libsolidity/codegen/ir/IRGeneratorForStatements.h +++ b/libsolidity/codegen/ir/IRGeneratorForStatements.h @@ -195,6 +195,8 @@ private: void setLocation(ASTNode const& _node); + void appendCurrentLocation(); + std::string linkerSymbol(ContractDefinition const& _library) const; std::ostringstream m_code; @@ -203,6 +205,7 @@ private: YulUtilFunctions& m_utils; std::optional m_currentLValue; langutil::SourceLocation m_currentLocation; + std::streampos m_lastSourceLocationPosition; }; } diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 10d396c4c..19f39facc 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -1302,7 +1302,7 @@ ASTPointer Parser::parseInlineAssembly(ASTPointer con if (block == nullptr) BOOST_THROW_EXCEPTION(FatalError()); - location.end = block->location.end; + location.end = block->debugData->irLocation.end; return make_shared(nextID(), location, _docString, dialect, block); } diff --git a/libyul/AST.h b/libyul/AST.h index 09d39832f..545bf608f 100644 --- a/libyul/AST.h +++ b/libyul/AST.h @@ -35,54 +35,62 @@ namespace solidity::yul using Type = YulString; -struct TypedName { langutil::SourceLocation location; YulString name; Type type; }; +struct DebugData +{ + explicit DebugData(langutil::SourceLocation _yulLocation = {}, langutil::SourceLocation _sollLocation = {}): irLocation(std::move(_yulLocation)), originLocation(std::move(_sollLocation)) + {} + langutil::SourceLocation irLocation; + langutil::SourceLocation originLocation; +}; + +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 + template std::shared_ptr operator()(T const& _node) const { - return _node.location; + return _node.debugData; } }; /// Extracts the source location from an inline assembly node. -template inline langutil::SourceLocation locationOf(T const& _node) +template inline std::shared_ptr locationOf(T const& _node) { return std::visit(LocationExtractor(), _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 fdd4c19ed..8c6f319e0 100644 --- a/libyul/AsmAnalysis.cpp +++ b/libyul/AsmAnalysis.cpp @@ -97,22 +97,22 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect, vector AsmAnalyzer::operator()(Literal const& _literal) { - expectValidType(_literal.type, _literal.location); + expectValidType(_literal.type, _literal.debugData->irLocation); if (_literal.kind == LiteralKind::String && _literal.value.str().size() > 32) m_errorReporter.typeError( 3069_error, - _literal.location, + _literal.debugData->irLocation, "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->irLocation, "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->irLocation, "Invalid type \"" + _literal.type.str() + "\" for literal \"" + _literal.value.str() + "\"." ); @@ -132,7 +132,7 @@ vector AsmAnalyzer::operator()(Identifier const& _identifier) if (!m_activeVariables.count(&_var)) m_errorReporter.declarationError( 4990_error, - _identifier.location, + _identifier.debugData->irLocation, "Variable " + _identifier.name.str() + " used before it was declared." ); type = _var.type; @@ -141,7 +141,7 @@ vector AsmAnalyzer::operator()(Identifier const& _identifier) { m_errorReporter.typeError( 6041_error, - _identifier.location, + _identifier.debugData->irLocation, "Function " + _identifier.name.str() + " used without being called." ); } @@ -159,7 +159,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->irLocation, "Identifier \"" + _identifier.name.str() + "\" not found." ); @@ -175,7 +175,7 @@ void AsmAnalyzer::operator()(ExpressionStatement const& _statement) if (watcher.ok() && !types.empty()) m_errorReporter.typeError( 3083_error, - _statement.location, + _statement.debugData->irLocation, "Top-level expressions are not supposed to return values (this expression returns " + to_string(types.size()) + " value" + @@ -195,7 +195,7 @@ void AsmAnalyzer::operator()(Assignment const& _assignment) if (!variables.insert(_variableName.name).second) m_errorReporter.declarationError( 9005_error, - _assignment.location, + _assignment.debugData->irLocation, "Variable " + _variableName.name.str() + " occurs multiple times on the left-hand side of the assignment." @@ -206,7 +206,7 @@ void AsmAnalyzer::operator()(Assignment const& _assignment) if (types.size() != numVariables) m_errorReporter.declarationError( 8678_error, - _assignment.location, + _assignment.debugData->irLocation, "Variable count for assignment to \"" + joinHumanReadable(applyMap(_assignment.variableNames, [](auto const& _identifier){ return _identifier.name.str(); })) + "\" does not match number of values (" + @@ -228,14 +228,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->irLocation); + expectValidType(variable.type, variable.debugData->irLocation); } if (_varDecl.value) @@ -244,7 +244,7 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl) if (types.size() != numVariables) m_errorReporter.declarationError( 3812_error, - _varDecl.location, + _varDecl.debugData->irLocation, "Variable count mismatch for declaration of \"" + joinHumanReadable(applyMap(_varDecl.variables, [](auto const& _identifier){ return _identifier.name.str(); })) + + "\": " + @@ -263,7 +263,7 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl) if (variable.type != givenType) m_errorReporter.typeError( 3947_error, - variable.location, + variable.debugData->irLocation, "Assigning value of type \"" + givenType.str() + "\" to variable of type \"" + variable.type.str() + "\"." ); } @@ -278,14 +278,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->irLocation); 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->irLocation); + expectValidType(var.type, var.debugData->irLocation); m_activeVariables.insert(&std::get(varScope.identifiers.at(var.name))); } @@ -314,7 +314,7 @@ vector AsmAnalyzer::operator()(FunctionCall const& _funCall) { m_errorReporter.typeError( 4202_error, - _funCall.functionName.location, + _funCall.functionName.debugData->irLocation, "Attempt to call variable instead of function." ); }, @@ -328,7 +328,7 @@ vector AsmAnalyzer::operator()(FunctionCall const& _funCall) if (!validateInstructions(_funCall)) m_errorReporter.declarationError( 4619_error, - _funCall.functionName.location, + _funCall.functionName.debugData->irLocation, "Function \"" + _funCall.functionName.name.str() + "\" not found." ); yulAssert(!watcher.ok(), "Expected a reported error."); @@ -337,7 +337,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->irLocation, "Function \"" + _funCall.functionName.name.str() + "\" expects " + to_string(parameterTypes->size()) + " arguments but got " + @@ -357,13 +357,13 @@ vector AsmAnalyzer::operator()(FunctionCall const& _funCall) if (!holds_alternative(arg)) m_errorReporter.typeError( 9114_error, - _funCall.functionName.location, + _funCall.functionName.debugData->irLocation, "Function expects direct literals as arguments." ); else if (*literalArgumentKind != get(arg).kind) m_errorReporter.typeError( 5859_error, - get(arg).location, + get(arg).debugData->irLocation, "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->irLocation, "Unknown data object \"" + std::get(arg).value.str() + "\"." ); argTypes.emplace_back(expectUnlimitedStringLiteral(get(arg))); @@ -388,7 +388,7 @@ vector AsmAnalyzer::operator()(FunctionCall const& _funCall) if (parameterTypes && parameterTypes->size() == argTypes.size()) for (size_t i = 0; i < parameterTypes->size(); ++i) - expectType((*parameterTypes)[i], argTypes[i], locationOf(_funCall.arguments[i])); + expectType((*parameterTypes)[i], argTypes[i], locationOf(_funCall.arguments[i])->irLocation); if (watcher.ok()) { @@ -416,7 +416,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->irLocation, "\"switch\" statement with only a default case." ); @@ -429,7 +429,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->irLocation); // We cannot use "expectExpression" here because *_case.value is not an // Expression and would be converted to an Expression otherwise. @@ -439,7 +439,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->irLocation, "Duplicate case \"" + valueOfLiteral(*_case.value).str() + "\" defined." @@ -491,7 +491,7 @@ YulString AsmAnalyzer::expectExpression(Expression const& _expr) if (types.size() != 1) m_errorReporter.typeError( 3950_error, - locationOf(_expr), + locationOf(_expr)->irLocation, "Expected expression to evaluate to one value, but got " + to_string(types.size()) + " values instead." @@ -513,7 +513,7 @@ void AsmAnalyzer::expectBoolExpression(Expression const& _expr) if (type != m_dialect.boolType) m_errorReporter.typeError( 1733_error, - locationOf(_expr), + locationOf(_expr)->irLocation, "Expected a value of boolean type \"" + m_dialect.boolType.str() + "\" but got \"" + @@ -531,11 +531,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->irLocation, "Assignment requires variable."); else if (!m_activeVariables.count(&std::get(*var))) m_errorReporter.declarationError( 1133_error, - _variable.location, + _variable.debugData->irLocation, "Variable " + _variable.name.str() + " used before it was declared." ); else @@ -554,11 +554,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->irLocation, "Variable not found or variable not lvalue."); if (variableType && *variableType != _valueType) m_errorReporter.typeError( 9547_error, - _variable.location, + _variable.debugData->irLocation, "Assigning a value of type \"" + _valueType.str() + "\" to a variable of type \"" + @@ -702,5 +702,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->irLocation); } diff --git a/libyul/AsmJsonConverter.cpp b/libyul/AsmJsonConverter.cpp index aece124aa..c1f299f05 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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "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->irLocation, "YulBreak"); } Json::Value AsmJsonConverter::operator()(Continue const& _node) const { - return createAstNode(_node.location, "YulContinue"); + return createAstNode(_node.debugData->irLocation, "YulContinue"); } Json::Value AsmJsonConverter::operator()(Leave const& _node) const { - return createAstNode(_node.location, "YulLeave"); + return createAstNode(_node.debugData->irLocation, "YulLeave"); } Json::Value AsmJsonConverter::createAstNode(langutil::SourceLocation const& _location, string _nodeType) const diff --git a/libyul/AsmJsonImporter.cpp b/libyul/AsmJsonImporter.cpp index bbcd1b9a7..79533309d 100644 --- a/libyul/AsmJsonImporter.cpp +++ b/libyul/AsmJsonImporter.cpp @@ -52,9 +52,11 @@ template T AsmJsonImporter::createAsmNode(Json::Value const& _node) { T r; - r.location = createSourceLocation(_node); + r.debugData = make_shared(createSourceLocation(_node)); yulAssert( - r.location.source && 0 <= r.location.start && r.location.start <= r.location.end, + r.debugData->irLocation.source && + 0 <= r.debugData->irLocation.start && + r.debugData->irLocation.start <= r.debugData->irLocation.end, "Invalid source location in Asm AST" ); return r; diff --git a/libyul/AsmParser.cpp b/libyul/AsmParser.cpp index 408fadf7a..1eb2a0ef9 100644 --- a/libyul/AsmParser.cpp +++ b/libyul/AsmParser.cpp @@ -70,7 +70,7 @@ Block Parser::parseBlock() expectToken(Token::LBrace); while (currentToken() != Token::RBrace) block.statements.emplace_back(parseStatement()); - block.location.end = currentLocation().end; + block.debugData->irLocation.end = currentLocation().end; advance(); return block; } @@ -109,7 +109,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->irLocation.end = _switch.cases.back().body.debugData->irLocation.end; return Statement{move(_switch)}; } case Token::For: @@ -156,7 +156,7 @@ Statement Parser::parseStatement() case Token::AssemblyAssign: { Assignment assignment; - assignment.location = locationOf(elementary); + assignment.debugData = locationOf(elementary); while (true) { @@ -191,7 +191,7 @@ Statement Parser::parseStatement() expectToken(Token::AssemblyAssign); assignment.value = make_unique(parseExpression()); - assignment.location.end = locationOf(*assignment.value).end; + assignment.debugData->irLocation.end = locationOf(*assignment.value)->irLocation.end; return Statement{move(assignment)}; } @@ -221,7 +221,7 @@ Case Parser::parseCase() else yulAssert(false, "Case or default case expected."); _case.body = parseBlock(); - _case.location.end = _case.body.location.end; + _case.debugData->irLocation.end = _case.body.debugData->irLocation.end; return _case; } @@ -241,7 +241,7 @@ ForLoop Parser::parseForLoop() forLoop.post = parseBlock(); m_currentForLoopComponent = ForLoopComponent::ForLoopBody; forLoop.body = parseBlock(); - forLoop.location.end = forLoop.body.location.end; + forLoop.debugData->irLocation.end = forLoop.body.debugData->irLocation.end; m_currentForLoopComponent = outerForLoopComponent; @@ -261,7 +261,7 @@ Expression Parser::parseExpression() if (m_dialect.builtin(_identifier.name)) fatalParserError( 7104_error, - _identifier.location, + _identifier.debugData->irLocation, "Builtin function \"" + _identifier.name.str() + "\" must be called." ); return move(_identifier); @@ -280,7 +280,7 @@ variant Parser::parseLiteralOrIdentifier() { case Token::Identifier: { - Identifier identifier{currentLocation(), YulString{currentLiteral()}}; + Identifier identifier{make_shared(currentLocation()), YulString{currentLiteral()}}; advance(); return identifier; } @@ -311,7 +311,7 @@ variant Parser::parseLiteralOrIdentifier() } Literal literal{ - currentLocation(), + make_shared(currentLocation()), kind, YulString{currentLiteral()}, kind == LiteralKind::Boolean ? m_dialect.boolType : m_dialect.defaultType @@ -320,7 +320,7 @@ variant Parser::parseLiteralOrIdentifier() if (currentToken() == Token::Colon) { expectToken(Token::Colon); - literal.location.end = currentLocation().end; + literal.debugData->irLocation.end = currentLocation().end; literal.type = expectAsmIdentifier(); } @@ -332,7 +332,7 @@ variant Parser::parseLiteralOrIdentifier() default: fatalParserError(1856_error, "Literal or identifier expected."); } - return {}; + return Literal{make_shared(), {}, {}, {}}; } VariableDeclaration Parser::parseVariableDeclaration() @@ -352,10 +352,10 @@ VariableDeclaration Parser::parseVariableDeclaration() { expectToken(Token::AssemblyAssign); varDecl.value = make_unique(parseExpression()); - varDecl.location.end = locationOf(*varDecl.value).end; + varDecl.debugData->irLocation.end = locationOf(*varDecl.value)->irLocation.end; } else - varDecl.location.end = varDecl.variables.back().location.end; + varDecl.debugData->irLocation.end = varDecl.variables.back().debugData->irLocation.end; return varDecl; } @@ -400,7 +400,7 @@ FunctionDefinition Parser::parseFunctionDefinition() m_insideFunction = true; funDef.body = parseBlock(); m_insideFunction = preInsideFunction; - funDef.location.end = funDef.body.location.end; + funDef.debugData->irLocation.end = funDef.body.debugData->irLocation.end; m_currentForLoopComponent = outerForLoopComponent; return funDef; @@ -415,7 +415,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 +427,7 @@ FunctionCall Parser::parseCall(variant&& _initialOp) ret.arguments.emplace_back(parseExpression()); } } - ret.location.end = currentLocation().end; + ret.debugData->irLocation.end = currentLocation().end; expectToken(Token::RParen); return ret; } @@ -440,7 +440,7 @@ TypedName Parser::parseTypedName() if (currentToken() == Token::Colon) { expectToken(Token::Colon); - typedName.location.end = currentLocation().end; + typedName.debugData->irLocation.end = currentLocation().end; typedName.type = expectAsmIdentifier(); } else diff --git a/libyul/AsmParser.h b/libyul/AsmParser.h index d1294b111..757e32048 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 = std::make_shared(currentLocation()); return r; } diff --git a/libyul/Dialect.cpp b/libyul/Dialect.cpp index 847c9f1ac..5a90db41f 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 {make_shared(), LiteralKind::Boolean, "false"_yulstring, _type}; + return {make_shared(), LiteralKind::Number, "0"_yulstring, _type}; } Literal Dialect::trueLiteral() const { if (boolType != defaultType) - return {SourceLocation{}, LiteralKind::Boolean, "true"_yulstring, boolType}; + return {make_shared(), LiteralKind::Boolean, "true"_yulstring, boolType}; else - return {SourceLocation{}, LiteralKind::Number, "1"_yulstring, defaultType}; + return {make_shared(), LiteralKind::Number, "1"_yulstring, defaultType}; } bool Dialect::validTypeForLiteral(LiteralKind _kind, YulString, YulString _type) const diff --git a/libyul/ScopeFiller.cpp b/libyul/ScopeFiller.cpp index 691bdc981..bad93569d 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->irLocation, *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->irLocation, 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->irLocation, "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 1f222da25..e204cf794 100644 --- a/libyul/backends/evm/AbstractAssembly.h +++ b/libyul/backends/evm/AbstractAssembly.h @@ -42,6 +42,7 @@ enum class Instruction: uint8_t; namespace solidity::yul { struct Identifier; +struct DebugData; /// /// Assembly class that abstracts both the libevmasm assembly and the new Yul assembly. @@ -56,7 +57,7 @@ public: virtual ~AbstractAssembly() = default; /// Set a new source location valid starting from the next instruction. - virtual void setSourceLocation(langutil::SourceLocation const& _location) = 0; + virtual void setSourceLocation(std::shared_ptr const& _debugData) = 0; /// Retrieve the current height of the stack. This does not have to be zero /// at the beginning. virtual int stackHeight() const = 0; diff --git a/libyul/backends/evm/AsmCodeGen.cpp b/libyul/backends/evm/AsmCodeGen.cpp index a2ecd92aa..2e2fbf50f 100644 --- a/libyul/backends/evm/AsmCodeGen.cpp +++ b/libyul/backends/evm/AsmCodeGen.cpp @@ -49,9 +49,9 @@ EthAssemblyAdapter::EthAssemblyAdapter(evmasm::Assembly& _assembly): { } -void EthAssemblyAdapter::setSourceLocation(SourceLocation const& _location) +void EthAssemblyAdapter::setSourceLocation(shared_ptr const& _debugData) { - m_assembly.setSourceLocation(_location); + m_assembly.setSourceLocation(_debugData ? _debugData->irLocation : langutil::SourceLocation{}); } int EthAssemblyAdapter::stackHeight() const diff --git a/libyul/backends/evm/AsmCodeGen.h b/libyul/backends/evm/AsmCodeGen.h index 9fa08ed3b..ca536b564 100644 --- a/libyul/backends/evm/AsmCodeGen.h +++ b/libyul/backends/evm/AsmCodeGen.h @@ -40,7 +40,7 @@ class EthAssemblyAdapter: public AbstractAssembly { public: explicit EthAssemblyAdapter(evmasm::Assembly& _assembly); - void setSourceLocation(langutil::SourceLocation const& _location) override; + void setSourceLocation(std::shared_ptr const& _debugData) override; int stackHeight() const override; void setStackHeight(int height) override; void appendInstruction(evmasm::Instruction _instruction) override; diff --git a/libyul/backends/evm/ConstantOptimiser.cpp b/libyul/backends/evm/ConstantOptimiser.cpp index d37ddade1..3af8f4270 100644 --- a/libyul/backends/evm/ConstantOptimiser.cpp +++ b/libyul/backends/evm/ConstantOptimiser.cpp @@ -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 52d78be86..41443e0e9 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..587dcc253 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(shared_ptr const&) { // Ignored for now; } diff --git a/libyul/backends/evm/EVMAssembly.h b/libyul/backends/evm/EVMAssembly.h index 00cea1208..603e64f1e 100644 --- a/libyul/backends/evm/EVMAssembly.h +++ b/libyul/backends/evm/EVMAssembly.h @@ -42,7 +42,7 @@ public: ~EVMAssembly() override = default; /// Set a new source location valid starting from the next instruction. - void setSourceLocation(langutil::SourceLocation const& _location) override; + void setSourceLocation(std::shared_ptr const& _debugData) override; /// Retrieve the current height of the stack. This does not have to be zero /// at the beginning. int stackHeight() const override { return m_stackHeight; } diff --git a/libyul/backends/evm/EVMCodeTransform.cpp b/libyul/backends/evm/EVMCodeTransform.cpp index 18d0f438c..21809ee0c 100644 --- a/libyul/backends/evm/EVMCodeTransform.cpp +++ b/libyul/backends/evm/EVMCodeTransform.cpp @@ -199,13 +199,13 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl) } else { - m_assembly.setSourceLocation(_varDecl.location); + m_assembly.setSourceLocation(_varDecl.debugData); size_t variablesLeft = numVariables; while (variablesLeft--) m_assembly.appendConstant(u256(0)); } - m_assembly.setSourceLocation(_varDecl.location); + m_assembly.setSourceLocation(_varDecl.debugData); bool atTopOfStack = true; for (size_t varIndex = 0; varIndex < numVariables; ++varIndex) { @@ -259,13 +259,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(_assignment.debugData); generateMultiAssignment(_assignment.variableNames); } void CodeTransform::operator()(ExpressionStatement const& _statement) { - m_assembly.setSourceLocation(_statement.location); + m_assembly.setSourceLocation(_statement.debugData); std::visit(*this, _statement.expression); } @@ -279,7 +279,7 @@ void CodeTransform::operator()(FunctionCall const& _call) }); else { - m_assembly.setSourceLocation(_call.location); + m_assembly.setSourceLocation(_call.debugData); EVMAssembly::LabelID returnLabel(numeric_limits::max()); // only used for evm 1.0 returnLabel = m_assembly.newLabelId(); @@ -294,7 +294,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(_call.debugData); m_assembly.appendJumpTo( functionEntryID(_call.functionName.name, *function), static_cast(function->returns.size() - function->arguments.size()) - 1, @@ -306,7 +306,7 @@ void CodeTransform::operator()(FunctionCall const& _call) void CodeTransform::operator()(Identifier const& _identifier) { - m_assembly.setSourceLocation(_identifier.location); + m_assembly.setSourceLocation(_identifier.debugData); // First search internals, then externals. yulAssert(m_scope, ""); if (m_scope->lookup(_identifier.name, GenericVisitor{ @@ -338,19 +338,19 @@ void CodeTransform::operator()(Identifier const& _identifier) void CodeTransform::operator()(Literal const& _literal) { - m_assembly.setSourceLocation(_literal.location); + m_assembly.setSourceLocation(_literal.debugData); m_assembly.appendConstant(valueOfLiteral(_literal)); } void CodeTransform::operator()(If const& _if) { visitExpression(*_if.condition); - m_assembly.setSourceLocation(_if.location); + m_assembly.setSourceLocation(_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(_if.debugData); m_assembly.appendLabel(end); } @@ -367,7 +367,7 @@ void CodeTransform::operator()(Switch const& _switch) if (c.value) { (*this)(*c.value); - m_assembly.setSourceLocation(c.location); + m_assembly.setSourceLocation(c.debugData); AbstractAssembly::LabelID bodyLabel = m_assembly.newLabelId(); caseBodies[&c] = bodyLabel; yulAssert(m_assembly.stackHeight() == expressionHeight + 1, ""); @@ -379,24 +379,24 @@ void CodeTransform::operator()(Switch const& _switch) // default case (*this)(c.body); } - m_assembly.setSourceLocation(_switch.location); + m_assembly.setSourceLocation(_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(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(c.first->debugData); m_assembly.appendJumpTo(end); } } - m_assembly.setSourceLocation(_switch.location); + m_assembly.setSourceLocation(_switch.debugData); m_assembly.appendLabel(end); m_assembly.appendInstruction(evmasm::Instruction::POP); } @@ -417,7 +417,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function) m_context->variableStackHeights[&var] = height++; } - m_assembly.setSourceLocation(_function.location); + m_assembly.setSourceLocation(_function.debugData); int const stackHeightBefore = m_assembly.stackHeight(); m_assembly.appendLabel(functionEntryID(_function.name, function)); @@ -542,11 +542,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(_forLoop.debugData); m_assembly.appendLabel(loopStart); visitExpression(*_forLoop.condition); - m_assembly.setSourceLocation(_forLoop.location); + m_assembly.setSourceLocation(_forLoop.debugData); m_assembly.appendInstruction(evmasm::Instruction::ISZERO); m_assembly.appendJumpToIf(loopEnd); @@ -554,12 +554,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(_forLoop.debugData); m_assembly.appendLabel(postPart); (*this)(_forLoop.post); - m_assembly.setSourceLocation(_forLoop.location); + m_assembly.setSourceLocation(_forLoop.debugData); m_assembly.appendJumpTo(loopStart); m_assembly.appendLabel(loopEnd); @@ -579,7 +579,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(_break.debugData); Context::JumpInfo const& jump = m_context->forLoopStack.top().done; m_assembly.appendJumpTo(jump.label, appendPopUntil(jump.targetStackHeight)); @@ -588,7 +588,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(_continue.debugData); Context::JumpInfo const& jump = m_context->forLoopStack.top().post; m_assembly.appendJumpTo(jump.label, appendPopUntil(jump.targetStackHeight)); @@ -598,7 +598,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(_leaveStatement.debugData); m_assembly.appendJumpTo(*m_functionExitLabel, appendPopUntil(*m_functionExitStackHeight)); } @@ -659,7 +659,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); @@ -729,7 +729,7 @@ void CodeTransform::visitStatements(vector const& _statements) void CodeTransform::finalizeBlock(Block const& _block, optional blockStartStackHeight) { - m_assembly.setSourceLocation(_block.location); + m_assembly.setSourceLocation(_block.debugData); freeUnusedVariables(); diff --git a/libyul/backends/evm/EVMDialect.cpp b/libyul/backends/evm/EVMDialect.cpp index eb21bd1b9..3b00c059c 100644 --- a/libyul/backends/evm/EVMDialect.cpp +++ b/libyul/backends/evm/EVMDialect.cpp @@ -52,7 +52,7 @@ void visitArguments( for (auto const& arg: _call.arguments | ranges::views::reverse) _visitExpression(arg); - _assembly.setSourceLocation(_call.location); + _assembly.setSourceLocation(_call.debugData); } @@ -256,7 +256,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); _assembly.appendImmutableAssignment(identifier.str()); } )); diff --git a/libyul/backends/evm/NoOutputAssembly.h b/libyul/backends/evm/NoOutputAssembly.h index a8c7c2f00..d6cfdc555 100644 --- a/libyul/backends/evm/NoOutputAssembly.h +++ b/libyul/backends/evm/NoOutputAssembly.h @@ -48,7 +48,7 @@ public: explicit NoOutputAssembly() { } ~NoOutputAssembly() override = default; - void setSourceLocation(langutil::SourceLocation const&) override {} + void setSourceLocation(std::shared_ptr const&) override {} int stackHeight() const override { return m_stackHeight; } void setStackHeight(int height) override { m_stackHeight = height; } void appendInstruction(evmasm::Instruction _instruction) override; diff --git a/libyul/backends/wasm/WordSizeTransform.cpp b/libyul/backends/wasm/WordSizeTransform.cpp index ec5e3a0de..7674cf22e 100644 --- a/libyul/backends/wasm/WordSizeTransform.cpp +++ b/libyul/backends/wasm/WordSizeTransform.cpp @@ -116,8 +116,8 @@ 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), LiteralKind::Number, @@ -126,8 +126,8 @@ void WordSizeTransform::operator()(Block& _block) }) }); 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,8 +177,8 @@ 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), LiteralKind::Number, @@ -187,8 +187,8 @@ void WordSizeTransform::operator()(Block& _block) }) }); 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,7 +272,7 @@ 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; } ); @@ -303,19 +303,20 @@ vector WordSizeTransform::handleSwitchInternal( ].emplace_back(std::move(c)); } + auto const debugData = make_shared(_location); 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( + Block{debugData, handleSwitchInternal( _location, _splitExpressions, std::move(c.second), @@ -326,13 +327,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 +357,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 +367,7 @@ std::vector WordSizeTransform::handleSwitch(Switch& _switch) splitExpressions.emplace_back(std::get(*expr).name); ret += handleSwitchInternal( - _switch.location, + _switch.debugData->irLocation, splitExpressions, std::move(_switch.cases), runDefaultFlag, @@ -374,8 +375,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 +398,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 +411,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/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/ConditionalSimplifier.cpp b/libyul/optimiser/ConditionalSimplifier.cpp index 0a66e28df..a5fcbc91d 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,11 @@ void ConditionalSimplifier::operator()(Block& _block) ) { YulString condition = std::get(*_if.condition).name; - langutil::SourceLocation location = _if.location; return make_vector( std::move(_s), Assignment{ - location, - {Identifier{location, condition}}, + _if.debugData, + {Identifier{_if.debugData, condition}}, make_unique(m_dialect.zeroLiteralForType(m_dialect.boolType)) } ); diff --git a/libyul/optimiser/ControlFlowSimplifier.cpp b/libyul/optimiser/ControlFlowSimplifier.cpp index c617e2005..9d6da137d 100644 --- a/libyul/optimiser/ControlFlowSimplifier.cpp +++ b/libyul/optimiser/ControlFlowSimplifier.cpp @@ -43,9 +43,9 @@ ExpressionStatement makeDiscardCall( Expression&& _expression ) { - return {_location, FunctionCall{ - _location, - Identifier{_location, _discardFunction.name}, + return {make_shared(_location), FunctionCall{ + make_shared(_location), + Identifier{make_shared(_location), _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->irLocation, *m_dialect.discardFunction(m_dialect.boolType), std::move(*_ifStmt.condition) )); @@ -194,7 +194,7 @@ OptionalStatements ControlFlowSimplifier::reduceNoCaseSwitch(Switch& _switchStmt auto loc = locationOf(*_switchStmt.expression); return make_vector(makeDiscardCall( - loc, + loc->irLocation, *discardFunction, std::move(*_switchStmt.expression) )); @@ -205,17 +205,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); + auto debugData = locationOf(*_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 +228,7 @@ OptionalStatements ControlFlowSimplifier::reduceSingleCaseSwitch(Switch& _switch return make_vector( makeDiscardCall( - loc, + debugData->irLocation, *m_dialect.discardFunction(type), std::move(*_switchStmt.expression) ), diff --git a/libyul/optimiser/ExpressionSimplifier.cpp b/libyul/optimiser/ExpressionSimplifier.cpp index 21107c026..a0f695275 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(locationOf(_expression)->irLocation); } diff --git a/libyul/optimiser/ExpressionSplitter.cpp b/libyul/optimiser/ExpressionSplitter.cpp index 7aad0bd58..a7bf278da 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); + auto const debugData = locationOf(_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..327ac0f5d 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 const debugData = locationOf(*_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..e4c8a378f 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); + auto const debugData = locationOf(*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 6ebab56db..e6c8992b4 100644 --- a/libyul/optimiser/FunctionGrouper.cpp +++ b/libyul/optimiser/FunctionGrouper.cpp @@ -37,7 +37,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..18365c311 100644 --- a/libyul/optimiser/KnowledgeBase.cpp +++ b/libyul/optimiser/KnowledgeBase.cpp @@ -41,11 +41,19 @@ bool KnowledgeBase::knownToBeDifferent(YulString _a, YulString _b) // current values to turn `sub(_a, _b)` into a nonzero constant. // If that fails, try `eq(_a, _b)`. - Expression expr1 = simplify(FunctionCall{{}, {{}, "sub"_yulstring}, util::make_vector(Identifier{{}, _a}, Identifier{{}, _b})}); + Expression expr1 = simplify(FunctionCall{ + make_shared(), + {make_shared(), "sub"_yulstring}, + util::make_vector(Identifier{make_shared(), _a}, Identifier{make_shared(), _b}) + }); if (holds_alternative(expr1)) return valueOfLiteral(std::get(expr1)) != 0; - Expression expr2 = simplify(FunctionCall{{}, {{}, "eq"_yulstring}, util::make_vector(Identifier{{}, _a}, Identifier{{}, _b})}); + Expression expr2 = simplify(FunctionCall{ + make_shared(), + {make_shared(), "eq"_yulstring}, + util::make_vector(Identifier{make_shared(), _a}, Identifier{{}, _b}) + }); if (holds_alternative(expr2)) return valueOfLiteral(std::get(expr2)) == 0; @@ -57,7 +65,11 @@ bool KnowledgeBase::knownToBeDifferentByAtLeast32(YulString _a, YulString _b) // Try to use the simplification rules together with the // current values to turn `sub(_a, _b)` into a constant whose absolute value is at least 32. - Expression expr1 = simplify(FunctionCall{{}, {{}, "sub"_yulstring}, util::make_vector(Identifier{{}, _a}, Identifier{{}, _b})}); + Expression expr1 = simplify(FunctionCall{ + make_shared(), + {make_shared(), "sub"_yulstring}, + util::make_vector(Identifier{make_shared(), _a}, Identifier{make_shared(), _b}) + }); if (holds_alternative(expr1)) { u256 val = valueOfLiteral(std::get(expr1)); @@ -84,7 +96,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(locationOf(_expression)->irLocation)); return _expression; } 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 f61bee321..de67ce4d0 100644 --- a/libyul/optimiser/ReasoningBasedSimplifier.cpp +++ b/libyul/optimiser/ReasoningBasedSimplifier.cpp @@ -80,7 +80,7 @@ void ReasoningBasedSimplifier::operator()(If& _if) if (result == CheckResult::UNSATISFIABLE) { Literal trueCondition = m_dialect.trueLiteral(); - trueCondition.location = locationOf(*_if.condition); + trueCondition.debugData = locationOf(*_if.condition); _if.condition = make_unique(move(trueCondition)); } else @@ -92,7 +92,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 = locationOf(*_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..fcd28e96e 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; + auto 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,23 @@ 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; + auto 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, + 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); @@ -236,11 +236,12 @@ void IntroduceControlFlowSSA::operator()(Block& _block) vector toPrepend; for (YulString toReassign: m_variablesToReassign) { + auto const debugData(locationOf(_s)); 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}) + debugData, + {TypedName{debugData, newName, m_typeInfo.typeOfVariable(toReassign)}}, + make_unique(Identifier{debugData, toReassign}) }); assignedVariables.insert(toReassign); } diff --git a/libyul/optimiser/SimplificationRules.cpp b/libyul/optimiser/SimplificationRules.cpp index 8e55e8c5e..1bfc3c244 100644 --- a/libyul/optimiser/SimplificationRules.cpp +++ b/libyul/optimiser/SimplificationRules.cpp @@ -241,7 +241,12 @@ Expression Pattern::toExpression(SourceLocation const& _location) const 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{ + make_shared(_location), + LiteralKind::Number, + YulString{util::formatNumber(*m_data)}, + {} + }; } else if (m_kind == PatternKind::Operation) { @@ -252,9 +257,10 @@ Expression Pattern::toExpression(SourceLocation const& _location) const string name = instructionInfo(m_instruction).name; transform(begin(name), end(name), begin(name), [](auto _c) { return tolower(_c); }); + auto const debugData = make_shared(_location); return FunctionCall{ - _location, - Identifier{_location, YulString{name}}, + debugData, + Identifier{debugData, YulString{name}}, std::move(arguments) }; } diff --git a/libyul/optimiser/StackToMemoryMover.cpp b/libyul/optimiser/StackToMemoryMover.cpp index 25eb25cd5..1157c6557 100644 --- a/libyul/optimiser/StackToMemoryMover.cpp +++ b/libyul/optimiser/StackToMemoryMover.cpp @@ -36,14 +36,15 @@ vector generateMemoryStore( Expression _value ) { + auto const debugData = make_shared(_loc); 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) } }}); @@ -52,13 +53,14 @@ vector generateMemoryStore( FunctionCall generateMemoryLoad(Dialect const& _dialect, langutil::SourceLocation const& _loc, YulString _mpos) { + auto const debugData = make_shared(_loc); 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,7 +125,7 @@ void StackToMemoryMover::operator()(Block& _block) if (!leftHandSideNeedsMoving) return {}; - langutil::SourceLocation loc = _stmt.location; + langutil::SourceLocation loc = _stmt.debugData->irLocation; if (_variables.size() == 1) { @@ -133,29 +135,29 @@ void StackToMemoryMover::operator()(Block& _block) m_context.dialect, loc, *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, *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 +193,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->irLocation, *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..c82abb873 100644 --- a/libyul/optimiser/VarDeclInitializer.cpp +++ b/libyul/optimiser/VarDeclInitializer.cpp @@ -47,11 +47,11 @@ void VarDeclInitializer::operator()(Block& _block) else { OptionalStatements ret{vector{}}; - langutil::SourceLocation loc{std::move(_varDecl.location)}; + shared_ptr const debugData{std::move(_varDecl.debugData)}; 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{debugData, {std::move(var)}, std::move(expr)}); } return ret; }