Skip to content

Commit a9e794c

Browse files
committed
Expose --debug-info/settings.debug.debugInfo option
1 parent bcfefc7 commit a9e794c

File tree

73 files changed

+1913
-5
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+1913
-5
lines changed

Changelog.md

+2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ Language Features:
66

77
Compiler Features:
88
* Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``.
9+
* Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code.
910
* SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions.
1011
* Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``.
12+
* Standard JSON: Add ``settings.debug.debugInfo`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code.
1113

1214

1315
Bugfixes:

docs/using-the-compiler.rst

+12-1
Original file line numberDiff line numberDiff line change
@@ -308,7 +308,18 @@ Input Description
308308
// "strip" removes all revert strings (if possible, i.e. if literals are used) keeping side-effects
309309
// "debug" injects strings for compiler-generated internal reverts, implemented for ABI encoders V1 and V2 for now.
310310
// "verboseDebug" even appends further information to user-supplied revert strings (not yet implemented)
311-
"revertStrings": "default"
311+
"revertStrings": "default",
312+
// Optional: How much extra debug information to include in comments in the produced EVM
313+
// assembly and Yul code. Available components are:
314+
// - `location`: Annotations of the form `@src <index>:<start>:<end>` indicating the
315+
// location of the corresponding element in the original Solidity file, where:
316+
// - `<index>` is the file index matching the `@use-src` annotation,
317+
// - `<start>` is the index of the first byte at that location,
318+
// - `<end>` is the index of the first byte after that location.
319+
// - `snippet`: A single-line code snippet from the location indicated by `@src`.
320+
// The snippet is quoted and follows the corresponding `@src` annotation.
321+
// - `*`: Wildcard value that can be used to request everything.
322+
"debugInfo": ["location", "snippet"]
312323
},
313324
// Metadata settings (optional)
314325
"metadata": {

libsolidity/interface/StandardCompiler.cpp

+31-3
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@
3333

3434
#include <libsmtutil/Exceptions.h>
3535

36-
#include <liblangutil/DebugInfoSelection.h>
3736
#include <liblangutil/SourceReferenceFormatter.h>
3837

3938
#include <libsolutil/JSON.h>
@@ -798,7 +797,7 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
798797

799798
if (settings.isMember("debug"))
800799
{
801-
if (auto result = checkKeys(settings["debug"], {"revertStrings"}, "settings.debug"))
800+
if (auto result = checkKeys(settings["debug"], {"revertStrings", "debugInfo"}, "settings.debug"))
802801
return *result;
803802

804803
if (settings["debug"].isMember("revertStrings"))
@@ -815,6 +814,31 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
815814
);
816815
ret.revertStrings = *revertStrings;
817816
}
817+
818+
if (settings["debug"].isMember("debugInfo"))
819+
{
820+
if (!settings["debug"]["debugInfo"].isArray())
821+
return formatFatalError("JSONError", "settings.debug.debugInfo must be an array.");
822+
823+
vector<string> components;
824+
for (Json::Value const& arrayValue: settings["debug"]["debugInfo"])
825+
components.push_back(arrayValue.asString());
826+
827+
optional<DebugInfoSelection> debugInfoSelection = DebugInfoSelection::fromComponents(
828+
components,
829+
true /* _acceptWildcards */
830+
);
831+
if (!debugInfoSelection.has_value())
832+
return formatFatalError("JSONError", "Invalid value in settings.debug.debugInfo.");
833+
834+
if (debugInfoSelection->snippet && !debugInfoSelection->location)
835+
return formatFatalError(
836+
"JSONError",
837+
"To use 'snippet' with settings.debug.debugInfo you must select also 'location'."
838+
);
839+
840+
ret.debugInfoSelection = debugInfoSelection.value();
841+
}
818842
}
819843

820844
if (settings.isMember("remappings") && !settings["remappings"].isArray())
@@ -1034,6 +1058,8 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
10341058
compilerStack.setRemappings(move(_inputsAndSettings.remappings));
10351059
compilerStack.setOptimiserSettings(std::move(_inputsAndSettings.optimiserSettings));
10361060
compilerStack.setRevertStringBehaviour(_inputsAndSettings.revertStrings);
1061+
if (_inputsAndSettings.debugInfoSelection.has_value())
1062+
compilerStack.selectDebugInfo(_inputsAndSettings.debugInfoSelection.value());
10371063
compilerStack.setLibraries(_inputsAndSettings.libraries);
10381064
compilerStack.useMetadataLiteralSources(_inputsAndSettings.metadataLiteralSources);
10391065
compilerStack.setMetadataHash(_inputsAndSettings.metadataHash);
@@ -1364,7 +1390,9 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
13641390
_inputsAndSettings.evmVersion,
13651391
AssemblyStack::Language::StrictAssembly,
13661392
_inputsAndSettings.optimiserSettings,
1367-
DebugInfoSelection::Default()
1393+
_inputsAndSettings.debugInfoSelection.has_value() ?
1394+
_inputsAndSettings.debugInfoSelection.value() :
1395+
DebugInfoSelection::Default()
13681396
);
13691397
string const& sourceName = _inputsAndSettings.sources.begin()->first;
13701398
string const& sourceContents = _inputsAndSettings.sources.begin()->second;

libsolidity/interface/StandardCompiler.h

+3
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
#include <libsolidity/interface/CompilerStack.h>
2727
#include <libsolutil/JSON.h>
2828

29+
#include <liblangutil/DebugInfoSelection.h>
30+
2931
#include <optional>
3032
#include <utility>
3133
#include <variant>
@@ -78,6 +80,7 @@ class StandardCompiler
7880
std::vector<ImportRemapper::Remapping> remappings;
7981
RevertStrings revertStrings = RevertStrings::Default;
8082
OptimiserSettings optimiserSettings = OptimiserSettings::minimal();
83+
std::optional<langutil::DebugInfoSelection> debugInfoSelection;
8184
std::map<std::string, util::h160> libraries;
8285
bool metadataLiteralSources = false;
8386
CompilerStack::MetadataHash metadataHash = CompilerStack::MetadataHash::IPFS;

solc/CommandLineInterface.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -631,6 +631,8 @@ bool CommandLineInterface::compile()
631631
m_compiler->setViaIR(m_options.output.experimentalViaIR);
632632
m_compiler->setEVMVersion(m_options.output.evmVersion);
633633
m_compiler->setRevertStringBehaviour(m_options.output.revertStrings);
634+
if (m_options.output.debugInfoSelection.has_value())
635+
m_compiler->selectDebugInfo(m_options.output.debugInfoSelection.value());
634636
// TODO: Perhaps we should not compile unless requested
635637

636638
m_compiler->enableIRGeneration(m_options.compiler.outputs.ir || m_options.compiler.outputs.irOptimized);
@@ -973,7 +975,9 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul:
973975
m_options.output.evmVersion,
974976
_language,
975977
m_options.optimiserSettings(),
976-
DebugInfoSelection::Default()
978+
m_options.output.debugInfoSelection.has_value() ?
979+
m_options.output.debugInfoSelection.value() :
980+
DebugInfoSelection::Default()
977981
);
978982

979983
if (!stack.parseAndAnalyze(src.first, src.second))

solc/CommandLineParser.cpp

+32
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ static string const g_strImportAst = "import-ast";
6767
static string const g_strInputFile = "input-file";
6868
static string const g_strYul = "yul";
6969
static string const g_strYulDialect = "yul-dialect";
70+
static string const g_strDebugInfo = "debug-info";
7071
static string const g_strIPFS = "ipfs";
7172
static string const g_strLicense = "license";
7273
static string const g_strLibraries = "libraries";
@@ -252,6 +253,7 @@ bool CommandLineOptions::operator==(CommandLineOptions const& _other) const noex
252253
output.evmVersion == _other.output.evmVersion &&
253254
output.experimentalViaIR == _other.output.experimentalViaIR &&
254255
output.revertStrings == _other.output.revertStrings &&
256+
output.debugInfoSelection == _other.output.debugInfoSelection &&
255257
output.stopAfter == _other.output.stopAfter &&
256258
input.mode == _other.input.mode &&
257259
assembly.targetMachine == _other.assembly.targetMachine &&
@@ -595,6 +597,13 @@ General Information)").c_str(),
595597
po::value<string>()->value_name(joinHumanReadable(g_revertStringsArgs, ",")),
596598
"Strip revert (and require) reason strings or add additional debugging information."
597599
)
600+
(
601+
g_strDebugInfo.c_str(),
602+
po::value<string>()->default_value(toString(DebugInfoSelection::Default())),
603+
("Debug info components to be included in the produced EVM assembly and Yul code. "
604+
"Value can be all, none or a comma-separated list containing one or more of the "
605+
"following components: " + joinHumanReadable(DebugInfoSelection::componentMap() | ranges::views::keys) + ".").c_str()
606+
)
598607
(
599608
g_strStopAfter.c_str(),
600609
po::value<string>()->value_name("stage"),
@@ -935,6 +944,12 @@ bool CommandLineParser::processArgs()
935944
serr() << "Option --" << option << " is only valid in compiler and assembler modes." << endl;
936945
return false;
937946
}
947+
948+
if (!m_args[g_strDebugInfo].defaulted())
949+
{
950+
serr() << "Option --" << g_strDebugInfo << " is only valid in compiler and assembler modes." << endl;
951+
return false;
952+
}
938953
}
939954

940955
if (m_args.count(g_strColor) > 0)
@@ -961,6 +976,23 @@ bool CommandLineParser::processArgs()
961976
m_options.output.revertStrings = *revertStrings;
962977
}
963978

979+
if (!m_args[g_strDebugInfo].defaulted())
980+
{
981+
string optionValue = m_args[g_strDebugInfo].as<string>();
982+
m_options.output.debugInfoSelection = DebugInfoSelection::fromString(optionValue);
983+
if (!m_options.output.debugInfoSelection.has_value())
984+
{
985+
serr() << "Invalid value for --" << g_strDebugInfo << " option: " << optionValue << endl;
986+
return false;
987+
}
988+
989+
if (m_options.output.debugInfoSelection->snippet && !m_options.output.debugInfoSelection->location)
990+
{
991+
serr() << "To use 'snippet' with --" << g_strDebugInfo << " you must select also 'location'." << endl;
992+
return false;
993+
}
994+
}
995+
964996
if (!parseCombinedJsonOption())
965997
return false;
966998

solc/CommandLineParser.h

+5
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,12 @@
2424
#include <libsolidity/interface/DebugSettings.h>
2525
#include <libsolidity/interface/FileReader.h>
2626
#include <libsolidity/interface/ImportRemapper.h>
27+
2728
#include <libyul/AssemblyStack.h>
29+
30+
#include <liblangutil/DebugInfoSelection.h>
2831
#include <liblangutil/EVMVersion.h>
32+
2933
#include <libsolutil/JSON.h>
3034

3135
#include <boost/program_options.hpp>
@@ -174,6 +178,7 @@ struct CommandLineOptions
174178
langutil::EVMVersion evmVersion;
175179
bool experimentalViaIR = false;
176180
RevertStrings revertStrings = RevertStrings::Default;
181+
std::optional<langutil::DebugInfoSelection> debugInfoSelection;
177182
CompilerStack::State stopAfter = CompilerStack::State::CompilationSuccessful;
178183
} output;
179184

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--ir --ir-optimized --asm --optimize --debug-info all
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// SPDX-License-Identifier: GPL-2.0
2+
pragma solidity >=0.0;
3+
4+
contract C {
5+
function f() public {}
6+
}

0 commit comments

Comments
 (0)