diff --git a/libsolidity/codegen/ir/IRGenerator.cpp b/libsolidity/codegen/ir/IRGenerator.cpp index 418d112e0..47a57eb08 100644 --- a/libsolidity/codegen/ir/IRGenerator.cpp +++ b/libsolidity/codegen/ir/IRGenerator.cpp @@ -133,7 +133,7 @@ string IRGenerator::generate( }; Whiskers t(R"( - /// @use-src + /// @use-src object "" { code { @@ -147,6 +147,7 @@ string IRGenerator::generate( } + /// @use-src object "" { code { @@ -177,7 +178,7 @@ string IRGenerator::generate( ", " ); - t("useSrcMap", useSrcMap); + t("useSrcMapCreation", useSrcMap); t("sourceLocationComment", sourceLocationComment(_contract, m_context)); t("CreationObject", IRNames::creationObject(_contract)); @@ -219,6 +220,7 @@ string IRGenerator::generate( m_context.initializeInternalDispatch(move(internalDispatchMap)); // Do not register immutables to avoid assignment. + t("useSrcMapDeployed", useSrcMap); t("DeployedObject", IRNames::deployedObject(_contract)); t("library_address", IRNames::libraryAddressImmutable()); t("dispatch", dispatchRoutine(_contract)); diff --git a/libyul/Object.cpp b/libyul/Object.cpp index 05ad9cb82..a87281cac 100644 --- a/libyul/Object.cpp +++ b/libyul/Object.cpp @@ -50,38 +50,32 @@ string indent(std::string const& _input) } -string Data::toString(Dialect const*, optional) const +string Data::toString(Dialect const*) const { return "data \"" + name.str() + "\" hex\"" + util::toHex(data) + "\""; } string Object::toString(Dialect const* _dialect) const { + yulAssert(code, "No code"); + yulAssert(debugData, "No debug data"); + string useSrcComment; - if (debugData && debugData->sourceNames) + if (debugData->sourceNames) useSrcComment = "/// @use-src " + joinHumanReadable(ranges::views::transform(*debugData->sourceNames, [](auto&& _pair) { return to_string(_pair.first) + ":" + util::escapeAndQuoteString(*_pair.second); })) + "\n"; - return useSrcComment + toString(_dialect, debugData ? debugData->sourceNames : optional{}); -} -string Object::toString(Dialect const* _dialect, std::optional _sourceNames) const -{ - yulAssert(code, "No code"); - string inner = "code " + AsmPrinter{_dialect, _sourceNames}(*code); + string inner = "code " + AsmPrinter{_dialect, debugData->sourceNames}(*code); for (auto const& obj: subObjects) - { - if (auto const* o = dynamic_cast(obj.get())) - yulAssert(!o->debugData || !o->debugData->sourceNames, ""); - inner += "\n" + obj->toString(_dialect, _sourceNames); - } + inner += "\n" + obj->toString(_dialect); - return "object \"" + name.str() + "\" {\n" + indent(inner) + "\n}"; + return useSrcComment + "object \"" + name.str() + "\" {\n" + indent(inner) + "\n}"; } set Object::qualifiedDataNames() const diff --git a/libyul/Object.h b/libyul/Object.h index 9b7519b1e..39fb092d3 100644 --- a/libyul/Object.h +++ b/libyul/Object.h @@ -49,11 +49,8 @@ struct ObjectNode /// Name of the object. /// Can be empty since .yul files can also just contain code, without explicitly placing it in an object. YulString name; -protected: - virtual std::string toString(Dialect const* _dialect, std::optional _sourceNames) const = 0; - /// Object should have access to toString - friend struct Object; + virtual std::string toString(Dialect const* _dialect) const = 0; }; /** @@ -65,8 +62,7 @@ struct Data: public ObjectNode bytes data; -protected: - std::string toString(Dialect const* _dialect, std::optional _sourceNames) const override; + std::string toString(Dialect const* _dialect) const override; }; @@ -114,8 +110,6 @@ public: /// @returns the name of the special metadata data object. static std::string metadataName() { return ".metadata"; } -protected: - std::string toString(Dialect const* _dialect, std::optional _sourceNames) const override; }; } diff --git a/libyul/ObjectParser.cpp b/libyul/ObjectParser.cpp index 8ce5896cf..afd4b7d94 100644 --- a/libyul/ObjectParser.cpp +++ b/libyul/ObjectParser.cpp @@ -45,14 +45,15 @@ shared_ptr ObjectParser::parse(shared_ptr const& _scanner, bool { shared_ptr object; m_scanner = _scanner; - m_sourceNameMapping = tryParseSourceNameMapping(); if (currentToken() == Token::LBrace) { // Special case: Code-only form. object = make_shared(); object->name = "object"_yulstring; - object->code = parseBlock(); + auto sourceNameMapping = tryParseSourceNameMapping(); + object->debugData = make_shared(ObjectDebugData{sourceNameMapping}); + object->code = parseBlock(sourceNameMapping); if (!object->code) return nullptr; } @@ -60,7 +61,6 @@ shared_ptr ObjectParser::parse(shared_ptr const& _scanner, bool object = parseObject(); if (!_reuseScanner) expectToken(Token::EOS); - object->debugData = make_shared(ObjectDebugData{m_sourceNameMapping}); return object; } catch (FatalError const&) @@ -75,16 +75,20 @@ shared_ptr ObjectParser::parseObject(Object* _containingObject) { RecursionGuard guard(*this); + shared_ptr ret = make_shared(); + + auto sourceNameMapping = tryParseSourceNameMapping(); + ret->debugData = make_shared(ObjectDebugData{sourceNameMapping}); + if (currentToken() != Token::Identifier || currentLiteral() != "object") fatalParserError(4294_error, "Expected keyword \"object\"."); advance(); - shared_ptr ret = make_shared(); ret->name = parseUniqueName(_containingObject); expectToken(Token::LBrace); - ret->code = parseCode(); + ret->code = parseCode(move(sourceNameMapping)); while (currentToken() != Token::RBrace) { @@ -103,13 +107,13 @@ shared_ptr ObjectParser::parseObject(Object* _containingObject) return ret; } -shared_ptr ObjectParser::parseCode() +shared_ptr ObjectParser::parseCode(optional _sourceNames) { if (currentToken() != Token::Identifier || currentLiteral() != "code") fatalParserError(4846_error, "Expected keyword \"code\"."); advance(); - return parseBlock(); + return parseBlock(move(_sourceNames)); } optional ObjectParser::tryParseSourceNameMapping() const @@ -166,9 +170,9 @@ optional ObjectParser::tryParseSourceNameMapping() const return nullopt; } -shared_ptr ObjectParser::parseBlock() +shared_ptr ObjectParser::parseBlock(optional _sourceNames) { - Parser parser(m_errorReporter, m_dialect, m_sourceNameMapping); + Parser parser(m_errorReporter, m_dialect, move(_sourceNames)); shared_ptr block = parser.parseInline(m_scanner); yulAssert(block || m_errorReporter.hasErrors(), "Invalid block but no error!"); return block; diff --git a/libyul/ObjectParser.h b/libyul/ObjectParser.h index 86a5ef77c..716a191ea 100644 --- a/libyul/ObjectParser.h +++ b/libyul/ObjectParser.h @@ -55,13 +55,11 @@ public: /// @returns an empty shared pointer on error. std::shared_ptr parse(std::shared_ptr const& _scanner, bool _reuseScanner); - std::optional const& sourceNameMapping() const noexcept { return m_sourceNameMapping; } - private: std::optional tryParseSourceNameMapping() const; std::shared_ptr parseObject(Object* _containingObject = nullptr); - std::shared_ptr parseCode(); - std::shared_ptr parseBlock(); + std::shared_ptr parseCode(std::optional _sourceNames); + std::shared_ptr parseBlock(std::optional _sourceNames); void parseData(Object& _containingObject); /// Tries to parse a name that is non-empty and unique inside the containing object. @@ -69,8 +67,6 @@ private: void addNamedSubObject(Object& _container, YulString _name, std::shared_ptr _subObject); Dialect const& m_dialect; - - std::optional m_sourceNameMapping; }; } diff --git a/libyul/backends/wasm/EVMToEwasmTranslator.cpp b/libyul/backends/wasm/EVMToEwasmTranslator.cpp index a5d355ede..eb7a60a32 100644 --- a/libyul/backends/wasm/EVMToEwasmTranslator.cpp +++ b/libyul/backends/wasm/EVMToEwasmTranslator.cpp @@ -93,6 +93,7 @@ Object EVMToEwasmTranslator::run(Object const& _object) Object ret; ret.name = _object.name; ret.code = make_shared(move(ast)); + ret.debugData = _object.debugData; ret.analysisInfo = make_shared(); ErrorList errors; diff --git a/test/cmdlineTests/constant_optimizer_yul/output b/test/cmdlineTests/constant_optimizer_yul/output index 7fdb98670..46df0ba95 100644 --- a/test/cmdlineTests/constant_optimizer_yul/output +++ b/test/cmdlineTests/constant_optimizer_yul/output @@ -21,6 +21,7 @@ object "C_12" { return(128, _1) } } + /// @use-src 0:"constant_optimizer_yul/input.sol", 1:"#utility.yul" object "C_12_deployed" { code { { diff --git a/test/cmdlineTests/exp_base_literal/output b/test/cmdlineTests/exp_base_literal/output index 1872afbe4..4b1484e3d 100644 --- a/test/cmdlineTests/exp_base_literal/output +++ b/test/cmdlineTests/exp_base_literal/output @@ -38,6 +38,7 @@ object "C_81" { } } + /// @use-src 0:"exp_base_literal/input.sol", 1:"#utility.yul" object "C_81_deployed" { code { /// @src 0:82:370 diff --git a/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output b/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output index 1af925406..541dac88b 100644 --- a/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output +++ b/test/cmdlineTests/ir_compiler_inheritance_nosubobjects/output @@ -18,6 +18,7 @@ object "C_7" { return(128, _1) } } + /// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol", 1:"#utility.yul" object "C_7_deployed" { code { { @@ -50,6 +51,7 @@ object "D_10" { return(128, _1) } } + /// @use-src 0:"ir_compiler_inheritance_nosubobjects/input.sol", 1:"#utility.yul" object "D_10_deployed" { code { { diff --git a/test/cmdlineTests/ir_compiler_subobjects/output b/test/cmdlineTests/ir_compiler_subobjects/output index ba93e6886..8de953f11 100644 --- a/test/cmdlineTests/ir_compiler_subobjects/output +++ b/test/cmdlineTests/ir_compiler_subobjects/output @@ -18,6 +18,7 @@ object "C_3" { return(128, _1) } } + /// @use-src 0:"ir_compiler_subobjects/input.sol", 1:"#utility.yul" object "C_3_deployed" { code { { @@ -50,6 +51,7 @@ object "D_16" { return(128, _1) } } + /// @use-src 0:"ir_compiler_subobjects/input.sol", 1:"#utility.yul" object "D_16_deployed" { code { { @@ -88,6 +90,7 @@ object "D_16" { revert(0, 0) } } + /// @use-src 0:"ir_compiler_subobjects/input.sol", 1:"#utility.yul" object "C_3" { code { { @@ -99,6 +102,7 @@ object "D_16" { return(128, _1) } } + /// @use-src 0:"ir_compiler_subobjects/input.sol", 1:"#utility.yul" object "C_3_deployed" { code { { diff --git a/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output b/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output index 89ee1b5d9..b7cdc74e9 100644 --- a/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output +++ b/test/cmdlineTests/ir_with_assembly_no_memoryguard_creation/output @@ -18,6 +18,7 @@ object "D_12" { return(128, _1) } } + /// @use-src 0:"ir_with_assembly_no_memoryguard_creation/input.sol", 1:"#utility.yul" object "D_12_deployed" { code { { diff --git a/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output b/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output index 1fcf2fcc8..0dece56bd 100644 --- a/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output +++ b/test/cmdlineTests/ir_with_assembly_no_memoryguard_runtime/output @@ -18,6 +18,7 @@ object "D_8" { return(128, _1) } } + /// @use-src 0:"ir_with_assembly_no_memoryguard_runtime/input.sol", 1:"#utility.yul" object "D_8_deployed" { code { { diff --git a/test/cmdlineTests/keccak_optimization_deploy_code/output b/test/cmdlineTests/keccak_optimization_deploy_code/output index 83c7c3929..4e80153d4 100644 --- a/test/cmdlineTests/keccak_optimization_deploy_code/output +++ b/test/cmdlineTests/keccak_optimization_deploy_code/output @@ -22,6 +22,7 @@ object "C_12" { return(128, _1) } } + /// @use-src 0:"keccak_optimization_deploy_code/input.sol", 1:"#utility.yul" object "C_12_deployed" { code { { diff --git a/test/cmdlineTests/keccak_optimization_low_runs/output b/test/cmdlineTests/keccak_optimization_low_runs/output index 203600cfa..2632b38df 100644 --- a/test/cmdlineTests/keccak_optimization_low_runs/output +++ b/test/cmdlineTests/keccak_optimization_low_runs/output @@ -18,6 +18,7 @@ object "C_7" { return(128, _1) } } + /// @use-src 0:"keccak_optimization_low_runs/input.sol", 1:"#utility.yul" object "C_7_deployed" { code { { diff --git a/test/cmdlineTests/name_simplifier/output b/test/cmdlineTests/name_simplifier/output index be3cb3780..b8c202c53 100644 --- a/test/cmdlineTests/name_simplifier/output +++ b/test/cmdlineTests/name_simplifier/output @@ -18,6 +18,7 @@ object "C_59" { return(128, _1) } } + /// @use-src 0:"name_simplifier/input.sol", 1:"#utility.yul" object "C_59_deployed" { code { { diff --git a/test/cmdlineTests/optimizer_array_sload/output b/test/cmdlineTests/optimizer_array_sload/output index 36dc23663..2355d5993 100644 --- a/test/cmdlineTests/optimizer_array_sload/output +++ b/test/cmdlineTests/optimizer_array_sload/output @@ -18,6 +18,7 @@ object "Arraysum_34" { return(128, _1) } } + /// @use-src 0:"optimizer_array_sload/input.sol", 1:"#utility.yul" object "Arraysum_34_deployed" { code { { diff --git a/test/cmdlineTests/revert_strings/output b/test/cmdlineTests/revert_strings/output index 6fa650eb1..8a9bc748c 100644 --- a/test/cmdlineTests/revert_strings/output +++ b/test/cmdlineTests/revert_strings/output @@ -53,6 +53,7 @@ object "C_15" { } } + /// @use-src 0:"revert_strings/input.sol", 1:"#utility.yul" object "C_15_deployed" { code { /// @src 0:59:147 diff --git a/test/cmdlineTests/standard_irOptimized_requested/output.json b/test/cmdlineTests/standard_irOptimized_requested/output.json index 8b9ada71a..bb5b9de14 100644 --- a/test/cmdlineTests/standard_irOptimized_requested/output.json +++ b/test/cmdlineTests/standard_irOptimized_requested/output.json @@ -25,6 +25,7 @@ object \"C_7\" { function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { revert(0, 0) } } + /// @use-src 0:\"A\", 1:\"#utility.yul\" object \"C_7_deployed\" { code { /// @src 0:79:121 diff --git a/test/cmdlineTests/standard_ir_requested/output.json b/test/cmdlineTests/standard_ir_requested/output.json index 2eb815d33..3d9bb9135 100644 --- a/test/cmdlineTests/standard_ir_requested/output.json +++ b/test/cmdlineTests/standard_ir_requested/output.json @@ -37,6 +37,7 @@ object \"C_7\" { } } + /// @use-src 0:\"A\", 1:\"#utility.yul\" object \"C_7_deployed\" { code { /// @src 0:79:121 diff --git a/test/cmdlineTests/standard_viair_requested/output.json b/test/cmdlineTests/standard_viair_requested/output.json index dca052187..aa3291a25 100644 --- a/test/cmdlineTests/standard_viair_requested/output.json +++ b/test/cmdlineTests/standard_viair_requested/output.json @@ -37,6 +37,7 @@ object \"C_3\" { } } + /// @use-src 0:\"A\", 1:\"#utility.yul\" object \"C_3_deployed\" { code { /// @src 0:79:92 @@ -113,6 +114,7 @@ object \"D_16\" { } } + /// @use-src 0:\"A\", 1:\"#utility.yul\" object \"D_16_deployed\" { code { /// @src 0:93:146 @@ -244,6 +246,7 @@ object \"D_16\" { } } + /// @use-src 0:\"A\", 1:\"#utility.yul\" object \"C_3_deployed\" { code { /// @src 0:79:92 diff --git a/test/cmdlineTests/viair_abicoder_v1/output b/test/cmdlineTests/viair_abicoder_v1/output index d42a032f8..ca9bbdc5e 100644 --- a/test/cmdlineTests/viair_abicoder_v1/output +++ b/test/cmdlineTests/viair_abicoder_v1/output @@ -38,6 +38,7 @@ object "test_11" { } } + /// @use-src 0:"viair_abicoder_v1/input.sol", 1:"#utility.yul" object "test_11_deployed" { code { /// @src 0:79:169 diff --git a/test/cmdlineTests/viair_subobjects/output b/test/cmdlineTests/viair_subobjects/output index 9ca620d06..bfdec9087 100644 --- a/test/cmdlineTests/viair_subobjects/output +++ b/test/cmdlineTests/viair_subobjects/output @@ -24,6 +24,7 @@ object "C_3" { return(128, _1) } } + /// @use-src 0:"viair_subobjects/input.sol", 1:"#utility.yul" object "C_3_deployed" { code { { @@ -62,6 +63,7 @@ object "D_16" { return(128, _1) } } + /// @use-src 0:"viair_subobjects/input.sol", 1:"#utility.yul" object "D_16_deployed" { code { { @@ -100,6 +102,7 @@ object "D_16" { revert(0, 0) } } + /// @use-src 0:"viair_subobjects/input.sol", 1:"#utility.yul" object "C_3" { code { { @@ -111,6 +114,7 @@ object "D_16" { return(128, _1) } } + /// @use-src 0:"viair_subobjects/input.sol", 1:"#utility.yul" object "C_3_deployed" { code { { diff --git a/test/cmdlineTests/yul_optimizer_steps/output b/test/cmdlineTests/yul_optimizer_steps/output index af9ef0988..bdd97296d 100644 --- a/test/cmdlineTests/yul_optimizer_steps/output +++ b/test/cmdlineTests/yul_optimizer_steps/output @@ -25,6 +25,7 @@ object "C_7" { function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() { revert(0, 0) } } + /// @use-src 0:"yul_optimizer_steps/input.sol", 1:"#utility.yul" object "C_7_deployed" { code { { diff --git a/test/cmdlineTests/yul_source_locations/output.json b/test/cmdlineTests/yul_source_locations/output.json index 100249924..c5d04aebb 100644 --- a/test/cmdlineTests/yul_source_locations/output.json +++ b/test/cmdlineTests/yul_source_locations/output.json @@ -156,6 +156,7 @@ object \"C_54\" { } } + /// @use-src 0:\"C\", 1:\"D\", 2:\"#utility.yul\" object \"C_54_deployed\" { code { /// @src 0:79:428 @@ -780,6 +781,7 @@ object \"D_72\" { } } + /// @use-src 0:\"C\", 1:\"D\", 2:\"#utility.yul\" object \"D_72_deployed\" { code { /// @src 1:91:166 diff --git a/test/cmdlineTests/yul_string_format_ascii/output.json b/test/cmdlineTests/yul_string_format_ascii/output.json index a48cc0d68..d6bce8b6a 100644 --- a/test/cmdlineTests/yul_string_format_ascii/output.json +++ b/test/cmdlineTests/yul_string_format_ascii/output.json @@ -37,6 +37,7 @@ object \"C_11\" { } } + /// @use-src 0:\"A\", 1:\"#utility.yul\" object \"C_11_deployed\" { code { /// @src 0:78:164 diff --git a/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json b/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json index 6dabd7fdd..ccf999086 100644 --- a/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_bytes32/output.json @@ -37,6 +37,7 @@ object \"C_11\" { } } + /// @use-src 0:\"A\", 1:\"#utility.yul\" object \"C_11_deployed\" { code { /// @src 0:78:158 diff --git a/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json b/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json index e02016c0e..f29e4347e 100644 --- a/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_bytes32_from_number/output.json @@ -37,6 +37,7 @@ object \"C_11\" { } } + /// @use-src 0:\"A\", 1:\"#utility.yul\" object \"C_11_deployed\" { code { /// @src 0:78:159 diff --git a/test/cmdlineTests/yul_string_format_ascii_long/output.json b/test/cmdlineTests/yul_string_format_ascii_long/output.json index f9110a134..d701ce599 100644 --- a/test/cmdlineTests/yul_string_format_ascii_long/output.json +++ b/test/cmdlineTests/yul_string_format_ascii_long/output.json @@ -37,6 +37,7 @@ object \"C_11\" { } } + /// @use-src 0:\"A\", 1:\"#utility.yul\" object \"C_11_deployed\" { code { /// @src 0:78:243 diff --git a/test/cmdlineTests/yul_string_format_hex/output.json b/test/cmdlineTests/yul_string_format_hex/output.json index 0bce08e79..ac437ccec 100644 --- a/test/cmdlineTests/yul_string_format_hex/output.json +++ b/test/cmdlineTests/yul_string_format_hex/output.json @@ -37,6 +37,7 @@ object \"C_11\" { } } + /// @use-src 0:\"A\", 1:\"#utility.yul\" object \"C_11_deployed\" { code { /// @src 0:78:159 diff --git a/test/libyul/ObjectParser.cpp b/test/libyul/ObjectParser.cpp index 1d4e0abc7..987933a9f 100644 --- a/test/libyul/ObjectParser.cpp +++ b/test/libyul/ObjectParser.cpp @@ -121,8 +121,9 @@ tuple, ErrorList> tryGetSourceLocationMapping(string _so Dialect const& dialect = yul::EVMDialect::strictAssemblyForEVM(EVMVersion::berlin()); ObjectParser objectParser{reporter, dialect}; CharStream stream(move(source), ""); - objectParser.parse(make_shared(stream), false); - return {objectParser.sourceNameMapping(), std::move(errors)}; + auto object = objectParser.parse(make_shared(stream), false); + BOOST_REQUIRE(object && object->debugData); + return {object->debugData->sourceNames, std::move(errors)}; } } diff --git a/test/libyul/objectCompiler/sourceLocations.yul b/test/libyul/objectCompiler/sourceLocations.yul index f98f74f77..4e75d05e7 100644 --- a/test/libyul/objectCompiler/sourceLocations.yul +++ b/test/libyul/objectCompiler/sourceLocations.yul @@ -10,6 +10,7 @@ object "a" { datasize("sub") ) } + /// @use-src 3: "abc.sol" , 2: "def.sol" object "sub" { code { /// @src 2:70:72