diff --git a/libsolidity/interface/StandardCompiler.cpp b/libsolidity/interface/StandardCompiler.cpp index 6c98b36020d7..3e7ca6fe52d5 100644 --- a/libsolidity/interface/StandardCompiler.cpp +++ b/libsolidity/interface/StandardCompiler.cpp @@ -1326,10 +1326,11 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu if (_inputsAndSettings.debugInfoSelection.has_value() && _inputsAndSettings.debugInfoSelection->ethdebug && - !isIRRequested(_inputsAndSettings.outputSelection) + !(isIRRequested(_inputsAndSettings.outputSelection) || _inputsAndSettings.viaIR) ) errors.emplace_back(formatError(Error::Type::FatalError, "general", "debug.debugInfo setting for ethdebug only valid, if 'ir', 'irAst', 'irOptimized' or 'irOptimizedAst' where requested.")); + bool const binariesRequested = isBinaryRequested(_inputsAndSettings.outputSelection); try @@ -1435,7 +1436,7 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu Json output; if (errors.size() > 0) - output["errors"] = std::move(errors); + output["errors"] = std::move(errors); if (!compilerStack.unhandledSMTLib2Queries().empty()) for (std::string const& query: compilerStack.unhandledSMTLib2Queries()) @@ -1488,6 +1489,10 @@ Json StandardCompiler::compileSolidity(StandardCompiler::InputsAndSettings _inpu if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "irOptimizedAst", wildcardMatchesExperimental)) contractData["irOptimizedAst"] = compilerStack.yulIROptimizedAst(contractName); + // ethdebug + if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "ethdebug", wildcardMatchesExperimental)) + contractData["ethdebug"] = Json::object(); + // EVM Json evmData; if (compilationSuccess && isArtifactRequested(_inputsAndSettings.outputSelection, file, name, "evm.assembly", wildcardMatchesExperimental)) diff --git a/solc/CommandLineInterface.cpp b/solc/CommandLineInterface.cpp index 367434c93f2a..f7560e92acfc 100644 --- a/solc/CommandLineInterface.cpp +++ b/solc/CommandLineInterface.cpp @@ -133,6 +133,7 @@ static std::string const g_strSignatureHashes = "hashes"; static std::string const g_strSourceList = "sourceList"; static std::string const g_strSources = "sources"; static std::string const g_strSrcMap = "srcmap"; +static std::string const g_strEthdebug = "ethdebug"; static std::string const g_strSrcMapRuntime = "srcmap-runtime"; static std::string const g_strStorageLayout = "storage-layout"; static std::string const g_strVersion = "version"; @@ -995,6 +996,8 @@ void CommandLineInterface::handleCombinedJSON() contractData[g_strFunDebugRuntime] = StandardCompiler::formatFunctionDebugData( m_assemblyStack->runtimeObject(contractName).functionDebugData ); + if (m_options.compiler.combinedJsonRequests->ethdebug) + contractData[g_strEthdebug] = Json::object(); } } diff --git a/solc/CommandLineParser.cpp b/solc/CommandLineParser.cpp index 737e3dcbae4b..1b900d72d483 100644 --- a/solc/CommandLineParser.cpp +++ b/solc/CommandLineParser.cpp @@ -776,7 +776,13 @@ General Information)").c_str(), ) ( g_strCombinedJson.c_str(), - po::value()->value_name(util::joinHumanReadable(CombinedJsonRequests::componentMap() | ranges::views::keys, ",")), + po::value()->value_name( + util::joinHumanReadable( + CombinedJsonRequests::componentMap() | ranges::views::keys | + ranges::views::filter([](std::string const& key) { return key != "ethdebug"; }) | + ranges::to(), "," + ) + ), "Output a single json document containing the specified information." ) ; @@ -1452,6 +1458,11 @@ void CommandLineParser::processArgs() "--debug-info ethdebug can only be used with --" + g_strViaIR + ", --" + CompilerOutputs::componentName(&CompilerOutputs::ir) + " and/or --" + CompilerOutputs::componentName(&CompilerOutputs::irOptimized) + "." ); + + if (m_options.compiler.combinedJsonRequests.has_value() && m_options.compiler.combinedJsonRequests->ethdebug && + !(m_options.output.debugInfoSelection.has_value() && m_options.output.debugInfoSelection->ethdebug) + ) + solThrow(CommandLineValidationError, "--combined-json ethdebug can only be used together with --debug-info ethdebug."); } void CommandLineParser::parseCombinedJsonOption() diff --git a/solc/CommandLineParser.h b/solc/CommandLineParser.h index b95973562e51..c731537754fd 100644 --- a/solc/CommandLineParser.h +++ b/solc/CommandLineParser.h @@ -135,6 +135,7 @@ struct CombinedJsonRequests {"devdoc", &CombinedJsonRequests::natspecDev}, {"userdoc", &CombinedJsonRequests::natspecUser}, {"ast", &CombinedJsonRequests::ast}, + {"ethdebug", &CombinedJsonRequests::ethdebug}, }; return components; } @@ -156,6 +157,7 @@ struct CombinedJsonRequests bool natspecDev = false; bool natspecUser = false; bool ast = false; + bool ethdebug = false; }; struct CommandLineOptions diff --git a/test/cmdlineTests/combined_json_ethdebug_with_ethdebug_debug_info/args b/test/cmdlineTests/combined_json_ethdebug_with_ethdebug_debug_info/args new file mode 100644 index 000000000000..5829a7cd71c3 --- /dev/null +++ b/test/cmdlineTests/combined_json_ethdebug_with_ethdebug_debug_info/args @@ -0,0 +1 @@ +--combined-json ethdebug --pretty-json --json-indent 3 diff --git a/test/cmdlineTests/combined_json_ethdebug_with_ethdebug_debug_info/err b/test/cmdlineTests/combined_json_ethdebug_with_ethdebug_debug_info/err new file mode 100644 index 000000000000..d14cb3461102 --- /dev/null +++ b/test/cmdlineTests/combined_json_ethdebug_with_ethdebug_debug_info/err @@ -0,0 +1 @@ +Error: --combined-json ethdebug can only be used together with --debug-info ethdebug. diff --git a/test/cmdlineTests/combined_json_ethdebug_with_ethdebug_debug_info/exit b/test/cmdlineTests/combined_json_ethdebug_with_ethdebug_debug_info/exit new file mode 100644 index 000000000000..d00491fd7e5b --- /dev/null +++ b/test/cmdlineTests/combined_json_ethdebug_with_ethdebug_debug_info/exit @@ -0,0 +1 @@ +1 diff --git a/test/cmdlineTests/combined_json_ethdebug_with_ethdebug_debug_info/input.sol b/test/cmdlineTests/combined_json_ethdebug_with_ethdebug_debug_info/input.sol new file mode 100644 index 000000000000..625af568280c --- /dev/null +++ b/test/cmdlineTests/combined_json_ethdebug_with_ethdebug_debug_info/input.sol @@ -0,0 +1,3 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract C {} diff --git a/test/cmdlineTests/combined_json_ethdebug_without_ethdebug_debug_info/args b/test/cmdlineTests/combined_json_ethdebug_without_ethdebug_debug_info/args new file mode 100644 index 000000000000..d17da0440233 --- /dev/null +++ b/test/cmdlineTests/combined_json_ethdebug_without_ethdebug_debug_info/args @@ -0,0 +1 @@ +--via-ir --debug-info ethdebug --combined-json ethdebug --pretty-json --json-indent 3 diff --git a/test/cmdlineTests/combined_json_ethdebug_without_ethdebug_debug_info/input.sol b/test/cmdlineTests/combined_json_ethdebug_without_ethdebug_debug_info/input.sol new file mode 100644 index 000000000000..625af568280c --- /dev/null +++ b/test/cmdlineTests/combined_json_ethdebug_without_ethdebug_debug_info/input.sol @@ -0,0 +1,3 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.0; +contract C {} diff --git a/test/cmdlineTests/combined_json_ethdebug_without_ethdebug_debug_info/output b/test/cmdlineTests/combined_json_ethdebug_without_ethdebug_debug_info/output new file mode 100644 index 000000000000..6c534ba5467b --- /dev/null +++ b/test/cmdlineTests/combined_json_ethdebug_without_ethdebug_debug_info/output @@ -0,0 +1,8 @@ +{ + "contracts": { + "combined_json_ethdebug_without_ethdebug_debug_info/input.sol:C": { + "ethdebug": {} + } + }, + "version": "" +} diff --git a/test/cmdlineTests/standard_ethdebug_requested_with_ethdebug_debug_info/input.json b/test/cmdlineTests/standard_ethdebug_requested_with_ethdebug_debug_info/input.json new file mode 100644 index 000000000000..306ab2bd9b78 --- /dev/null +++ b/test/cmdlineTests/standard_ethdebug_requested_with_ethdebug_debug_info/input.json @@ -0,0 +1,19 @@ +{ + "language": "Solidity", + "sources": + { + "A": + { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() public pure {} }" + } + }, + "settings": + { + "viaIR": true, + "debug": {"debugInfo": ["ethdebug"]}, + "outputSelection": + { + "*": { "*": ["ethdebug", "evm.bytecode.object"] } + } + } +} diff --git a/test/cmdlineTests/standard_ethdebug_requested_with_ethdebug_debug_info/output.json b/test/cmdlineTests/standard_ethdebug_requested_with_ethdebug_debug_info/output.json new file mode 100644 index 000000000000..5a38c22492d0 --- /dev/null +++ b/test/cmdlineTests/standard_ethdebug_requested_with_ethdebug_debug_info/output.json @@ -0,0 +1,19 @@ +{ + "contracts": { + "A": { + "C": { + "ethdebug": {}, + "evm": { + "bytecode": { + "object": "" + } + } + } + } + }, + "sources": { + "A": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_ethdebug_requested_without_ethdebug_debug_info/input.json b/test/cmdlineTests/standard_ethdebug_requested_without_ethdebug_debug_info/input.json new file mode 100644 index 000000000000..12dd728f614b --- /dev/null +++ b/test/cmdlineTests/standard_ethdebug_requested_without_ethdebug_debug_info/input.json @@ -0,0 +1,17 @@ +{ + "language": "Solidity", + "sources": + { + "A": + { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() public pure {} }" + } + }, + "settings": + { + "outputSelection": + { + "*": { "*": ["ethdebug", "evm.bytecode.object"] } + } + } +} diff --git a/test/cmdlineTests/standard_ethdebug_requested_without_ethdebug_debug_info/output.json b/test/cmdlineTests/standard_ethdebug_requested_without_ethdebug_debug_info/output.json new file mode 100644 index 000000000000..5a38c22492d0 --- /dev/null +++ b/test/cmdlineTests/standard_ethdebug_requested_without_ethdebug_debug_info/output.json @@ -0,0 +1,19 @@ +{ + "contracts": { + "A": { + "C": { + "ethdebug": {}, + "evm": { + "bytecode": { + "object": "" + } + } + } + } + }, + "sources": { + "A": { + "id": 0 + } + } +} diff --git a/test/cmdlineTests/standard_ethdebug_requested_without_requesting_binary/input.json b/test/cmdlineTests/standard_ethdebug_requested_without_requesting_binary/input.json new file mode 100644 index 000000000000..dd81ab8c40c1 --- /dev/null +++ b/test/cmdlineTests/standard_ethdebug_requested_without_requesting_binary/input.json @@ -0,0 +1,19 @@ +{ + "language": "Solidity", + "sources": + { + "A": + { + "content": "// SPDX-License-Identifier: GPL-3.0\npragma solidity >=0.0; pragma abicoder v2; contract C { function f() public pure {} }" + } + }, + "settings": + { + "viaIR": true, + "debug": {"debugInfo": ["ethdebug"]}, + "outputSelection": + { + "*": { "*": ["ethdebug"] } + } + } +} diff --git a/test/cmdlineTests/standard_ethdebug_requested_without_requesting_binary/output.json b/test/cmdlineTests/standard_ethdebug_requested_without_requesting_binary/output.json new file mode 100644 index 000000000000..f047ff70a9eb --- /dev/null +++ b/test/cmdlineTests/standard_ethdebug_requested_without_requesting_binary/output.json @@ -0,0 +1,7 @@ +{ + "sources": { + "A": { + "id": 0 + } + } +}