Merge pull request #11944 from ethereum/debug-info-selection

Debug info selection
This commit is contained in:
chriseth 2021-10-12 16:39:50 +02:00 committed by GitHub
commit adc58c67b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
109 changed files with 2427 additions and 91 deletions

View File

@ -6,8 +6,10 @@ Language Features:
Compiler Features:
* Commandline Interface: Accept nested brackets in step sequences passed to ``--yul-optimizations``.
* Commandline Interface: Add ``--debug-info`` option for selecting how much extra debug information should be included in the produced EVM assembly and Yul code.
* SMTChecker: Output values for ``block.*``, ``msg.*`` and ``tx.*`` variables that are present in the called functions.
* Standard JSON: Accept nested brackets in step sequences passed to ``settings.optimizer.details.yulDetails.optimizerSteps``.
* 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.
Bugfixes:

View File

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

View File

@ -96,13 +96,13 @@ public:
m_out(_out), m_prefix(_prefix), m_sourceCodes(_sourceCodes), m_assembly(_assembly)
{}
void feed(AssemblyItem const& _item)
void feed(AssemblyItem const& _item, DebugInfoSelection const& _debugInfoSelection)
{
if (_item.location().isValid() && _item.location() != m_location)
{
flush();
m_location = _item.location();
printLocation();
printLocation(_debugInfoSelection);
}
string expression = _item.toAssemblyText(m_assembly);
@ -142,16 +142,29 @@ public:
m_pending.clear();
}
void printLocation()
void printLocation(DebugInfoSelection const& _debugInfoSelection)
{
if (!m_location.isValid())
if (!m_location.isValid() || (!_debugInfoSelection.location && !_debugInfoSelection.snippet))
return;
m_out << m_prefix << " /*";
if (m_location.sourceName)
m_out << " " + escapeAndQuoteString(*m_location.sourceName);
if (m_location.hasText())
m_out << ":" << to_string(m_location.start) + ":" + to_string(m_location.end);
m_out << " " << locationFromSources(m_sourceCodes, m_location);
if (_debugInfoSelection.location)
{
if (m_location.sourceName)
m_out << " " + escapeAndQuoteString(*m_location.sourceName);
if (m_location.hasText())
m_out << ":" << to_string(m_location.start) + ":" + to_string(m_location.end);
}
if (_debugInfoSelection.snippet)
{
if (_debugInfoSelection.location)
m_out << " ";
m_out << locationFromSources(m_sourceCodes, m_location);
}
m_out << " */" << endl;
}
@ -167,12 +180,17 @@ private:
}
void Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMap const& _sourceCodes) const
void Assembly::assemblyStream(
ostream& _out,
DebugInfoSelection const& _debugInfoSelection,
string const& _prefix,
StringMap const& _sourceCodes
) const
{
Functionalizer f(_out, _prefix, _sourceCodes, *this);
for (auto const& i: m_items)
f.feed(i);
f.feed(i, _debugInfoSelection);
f.flush();
if (!m_data.empty() || !m_subs.empty())
@ -185,7 +203,7 @@ void Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMap co
for (size_t i = 0; i < m_subs.size(); ++i)
{
_out << endl << _prefix << "sub_" << i << ": assembly {\n";
m_subs[i]->assemblyStream(_out, _prefix + " ", _sourceCodes);
m_subs[i]->assemblyStream(_out, _debugInfoSelection, _prefix + " ", _sourceCodes);
_out << _prefix << "}" << endl;
}
}
@ -194,10 +212,13 @@ void Assembly::assemblyStream(ostream& _out, string const& _prefix, StringMap co
_out << endl << _prefix << "auxdata: 0x" << util::toHex(m_auxiliaryData) << endl;
}
string Assembly::assemblyString(StringMap const& _sourceCodes) const
string Assembly::assemblyString(
DebugInfoSelection const& _debugInfoSelection,
StringMap const& _sourceCodes
) const
{
ostringstream tmp;
assemblyStream(tmp, "", _sourceCodes);
assemblyStream(tmp, _debugInfoSelection, "", _sourceCodes);
return tmp.str();
}

View File

@ -24,6 +24,7 @@
#include <libevmasm/LinkerObject.h>
#include <libevmasm/Exceptions.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/EVMVersion.h>
#include <libsolutil/Common.h>
@ -142,10 +143,12 @@ public:
/// Create a text representation of the assembly.
std::string assemblyString(
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
StringMap const& _sourceCodes = StringMap()
) const;
void assemblyStream(
std::ostream& _out,
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
std::string const& _prefix = "",
StringMap const& _sourceCodes = StringMap()
) const;

View File

@ -3,6 +3,8 @@ set(sources
Common.h
CharStream.cpp
CharStream.h
DebugInfoSelection.cpp
DebugInfoSelection.h
ErrorReporter.cpp
ErrorReporter.h
EVMVersion.h

View File

@ -0,0 +1,157 @@
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/Exceptions.h>
#include <libsolutil/StringUtils.h>
#include <boost/algorithm/string/trim.hpp>
#include <range/v3/range/conversion.hpp>
#include <range/v3/view/map.hpp>
#include <range/v3/view/split.hpp>
#include <vector>
using namespace std;
using namespace solidity;
using namespace solidity::langutil;
using namespace solidity::util;
DebugInfoSelection const DebugInfoSelection::All(bool _value) noexcept
{
DebugInfoSelection result;
for (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)
result.*member = _value;
return result;
}
DebugInfoSelection const DebugInfoSelection::Only(bool DebugInfoSelection::* _member) noexcept
{
DebugInfoSelection result{};
result.*_member = true;
return result;
}
optional<DebugInfoSelection> DebugInfoSelection::fromString(string_view _input)
{
// TODO: Make more stuff constexpr and make it a static_assert().
solAssert(componentMap().count("all") == 0, "");
solAssert(componentMap().count("none") == 0, "");
if (_input == "all")
return All();
if (_input == "none")
return None();
return fromComponents(_input | ranges::views::split(',') | ranges::to<vector<string>>);
}
optional<DebugInfoSelection> DebugInfoSelection::fromComponents(
vector<string> const& _componentNames,
bool _acceptWildcards
)
{
solAssert(componentMap().count("*") == 0, "");
DebugInfoSelection selection;
for (auto const& component: _componentNames)
{
if (component == "*")
return (_acceptWildcards ? make_optional(DebugInfoSelection::All()) : nullopt);
if (!selection.enable(component))
return nullopt;
}
return selection;
}
bool DebugInfoSelection::enable(string _component)
{
auto memberIt = componentMap().find(boost::trim_copy(_component));
if (memberIt == componentMap().end())
return false;
this->*(memberIt->second) = true;
return true;
}
bool DebugInfoSelection::any() const noexcept
{
for (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)
if (this->*member)
return true;
return false;
}
bool DebugInfoSelection::all() const noexcept
{
for (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)
if (!(this->*member))
return false;
return true;
}
DebugInfoSelection& DebugInfoSelection::operator&=(DebugInfoSelection const& _other)
{
for (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)
this->*member &= _other.*member;
return *this;
}
DebugInfoSelection& DebugInfoSelection::operator|=(DebugInfoSelection const& _other)
{
for (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)
this->*member |= _other.*member;
return *this;
}
DebugInfoSelection DebugInfoSelection::operator&(DebugInfoSelection _other) const noexcept
{
_other &= *this;
return _other;
}
DebugInfoSelection DebugInfoSelection::operator|(DebugInfoSelection _other) const noexcept
{
_other |= *this;
return _other;
}
bool DebugInfoSelection::operator==(DebugInfoSelection const& _other) const noexcept
{
for (bool DebugInfoSelection::* member: componentMap() | ranges::views::values)
if (this->*member != _other.*member)
return false;
return true;
}
ostream& langutil::operator<<(ostream& _stream, DebugInfoSelection const& _selection)
{
vector<string> selectedComponentNames;
for (auto const& [name, member]: _selection.componentMap())
if (_selection.*member)
selectedComponentNames.push_back(name);
return _stream << joinHumanReadable(selectedComponentNames, ",");
}

View File

@ -0,0 +1,86 @@
/*
This file is part of solidity.
solidity is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
solidity is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with solidity. If not, see <http://www.gnu.org/licenses/>.
*/
// SPDX-License-Identifier: GPL-3.0
/**
* Handles selections of debug info components.
*/
#pragma once
#include <map>
#include <optional>
#include <ostream>
#include <string>
#include <string_view>
#include <vector>
namespace solidity::langutil
{
/**
* Represents a set of flags corresponding to components of debug info selected for some purpose.
*
* Provides extra functionality for enumerating the components and serializing/deserializing the
* selection to/from a comma-separated string.
*/
struct DebugInfoSelection
{
static DebugInfoSelection const All(bool _value = true) noexcept;
static DebugInfoSelection const None() noexcept { return All(false); }
static DebugInfoSelection const Only(bool DebugInfoSelection::* _member) noexcept;
static DebugInfoSelection const Default() noexcept { return All(); }
static std::optional<DebugInfoSelection> fromString(std::string_view _input);
static std::optional<DebugInfoSelection> fromComponents(
std::vector<std::string> const& _componentNames,
bool _acceptWildcards = false
);
bool enable(std::string _component);
bool all() const noexcept;
bool any() const noexcept;
bool none() const noexcept { return !any(); }
bool only(bool DebugInfoSelection::* _member) const noexcept { return *this == Only(_member); }
DebugInfoSelection& operator&=(DebugInfoSelection const& _other);
DebugInfoSelection& operator|=(DebugInfoSelection const& _other);
DebugInfoSelection operator&(DebugInfoSelection _other) const noexcept;
DebugInfoSelection operator|(DebugInfoSelection _other) const noexcept;
bool operator!=(DebugInfoSelection const& _other) const noexcept { return !(*this == _other); }
bool operator==(DebugInfoSelection const& _other) const noexcept;
friend std::ostream& operator<<(std::ostream& _stream, DebugInfoSelection const& _selection);
static auto const& componentMap()
{
static std::map<std::string, bool DebugInfoSelection::*> const components = {
{"location", &DebugInfoSelection::location},
{"snippet", &DebugInfoSelection::snippet},
{"ast-id", &DebugInfoSelection::astID},
};
return components;
}
bool location = false; ///< Include source location. E.g. `@src 3:50:100`
bool snippet = false; ///< Include source code snippet next to location. E.g. `@src 3:50:100 "contract C {..."`
bool astID = false; ///< Include ID of the Solidity AST node. E.g. `@ast-id 15`
};
std::ostream& operator<<(std::ostream& _stream, DebugInfoSelection const& _selection);
}

View File

@ -135,11 +135,15 @@ string dispenseLocationComment(langutil::SourceLocation const& _location, IRGene
{
solAssert(_location.sourceName, "");
_context.markSourceUsed(*_location.sourceName);
return "/// " + AsmPrinter::formatSourceLocation(
string debugInfo = AsmPrinter::formatSourceLocation(
_location,
_context.sourceIndices(),
_context.debugInfoSelection(),
_context.soliditySourceProvider()
);
return debugInfo.empty() ? "" : "/// " + debugInfo;
}
string dispenseLocationComment(ASTNode const& _node, IRGenerationContext& _context)

View File

@ -30,6 +30,7 @@
#include <libsolidity/codegen/ir/Common.h>
#include <liblangutil/CharStreamProvider.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/EVMVersion.h>
#include <libsolutil/Common.h>
@ -74,6 +75,7 @@ public:
RevertStrings _revertStrings,
OptimiserSettings _optimiserSettings,
std::map<std::string, unsigned> _sourceIndices,
langutil::DebugInfoSelection const& _debugInfoSelection,
langutil::CharStreamProvider const* _soliditySourceProvider
):
m_evmVersion(_evmVersion),
@ -81,6 +83,7 @@ public:
m_revertStrings(_revertStrings),
m_optimiserSettings(std::move(_optimiserSettings)),
m_sourceIndices(std::move(_sourceIndices)),
m_debugInfoSelection(_debugInfoSelection),
m_soliditySourceProvider(_soliditySourceProvider)
{}
@ -174,6 +177,7 @@ public:
bool immutableRegistered(VariableDeclaration const& _varDecl) const { return m_immutableVariables.count(&_varDecl); }
langutil::DebugInfoSelection debugInfoSelection() const { return m_debugInfoSelection; }
langutil::CharStreamProvider const* soliditySourceProvider() const { return m_soliditySourceProvider; }
private:
@ -220,6 +224,7 @@ private:
std::set<ContractDefinition const*, ASTNode::CompareByID> m_subObjects;
langutil::DebugInfoSelection m_debugInfoSelection = {};
langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr;
};

View File

@ -95,7 +95,12 @@ pair<string, string> IRGenerator::run(
{
string const ir = yul::reindent(generate(_contract, _cborMetadata, _otherYulSources));
yul::AssemblyStack asmStack(m_evmVersion, yul::AssemblyStack::Language::StrictAssembly, m_optimiserSettings);
yul::AssemblyStack asmStack(
m_evmVersion,
yul::AssemblyStack::Language::StrictAssembly,
m_optimiserSettings,
m_context.debugInfoSelection()
);
if (!asmStack.parseAndAnalyze("", ir))
{
string errorMessage;
@ -340,8 +345,7 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function)
return m_context.functionCollector().createFunction(functionName, [&]() {
m_context.resetLocalVariables();
Whiskers t(R"(
/// @ast-id <astID>
<sourceLocationComment>
<astIDComment><sourceLocationComment>
function <functionName>(<params>)<?+retParams> -> <retParams></+retParams> {
<retInit>
<body>
@ -349,7 +353,10 @@ string IRGenerator::generateFunction(FunctionDefinition const& _function)
<contractSourceLocationComment>
)");
t("astID", to_string(_function.id()));
if (m_context.debugInfoSelection().astID)
t("astIDComment", "/// @ast-id " + to_string(_function.id()) + "\n");
else
t("astIDComment", "");
t("sourceLocationComment", dispenseLocationComment(_function));
t(
"contractSourceLocationComment",
@ -409,8 +416,7 @@ string IRGenerator::generateModifier(
return m_context.functionCollector().createFunction(functionName, [&]() {
m_context.resetLocalVariables();
Whiskers t(R"(
/// @ast-id <astID>
<sourceLocationComment>
<astIDComment><sourceLocationComment>
function <functionName>(<params>)<?+retParams> -> <retParams></+retParams> {
<assignRetParams>
<evalArgs>
@ -418,6 +424,7 @@ string IRGenerator::generateModifier(
}
<contractSourceLocationComment>
)");
t("functionName", functionName);
vector<string> retParamsIn;
for (auto const& varDecl: _function.returnParameters())
@ -440,7 +447,11 @@ string IRGenerator::generateModifier(
_modifierInvocation.name().annotation().referencedDeclaration
);
solAssert(modifier, "");
t("astID", to_string(modifier->id()));
if (m_context.debugInfoSelection().astID)
t("astIDComment", "/// @ast-id " + to_string(modifier->id()) + "\n");
else
t("astIDComment", "");
t("sourceLocationComment", dispenseLocationComment(*modifier));
t(
"contractSourceLocationComment",
@ -546,14 +557,18 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
solAssert(paramTypes.empty(), "");
solUnimplementedAssert(type->sizeOnStack() == 1);
return Whiskers(R"(
/// @ast-id <astID>
<sourceLocationComment>
<astIDComment><sourceLocationComment>
function <functionName>() -> rval {
rval := loadimmutable("<id>")
}
<contractSourceLocationComment>
)")
("astID", to_string(_varDecl.id()))
(
"astIDComment",
m_context.debugInfoSelection().astID ?
"/// @ast-id " + to_string(_varDecl.id()) + "\n" :
""
)
("sourceLocationComment", dispenseLocationComment(_varDecl))
(
"contractSourceLocationComment",
@ -567,14 +582,18 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
{
solAssert(paramTypes.empty(), "");
return Whiskers(R"(
/// @ast-id <astID>
<sourceLocationComment>
<astIDComment><sourceLocationComment>
function <functionName>() -> <ret> {
<ret> := <constantValueFunction>()
}
<contractSourceLocationComment>
)")
("astID", to_string(_varDecl.id()))
(
"astIDComment",
m_context.debugInfoSelection().astID ?
"/// @ast-id " + to_string(_varDecl.id()) + "\n" :
""
)
("sourceLocationComment", dispenseLocationComment(_varDecl))
(
"contractSourceLocationComment",
@ -691,8 +710,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
}
return Whiskers(R"(
/// @ast-id <astID>
<sourceLocationComment>
<astIDComment><sourceLocationComment>
function <functionName>(<params>) -> <retVariables> {
<code>
}
@ -702,7 +720,12 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
("params", joinHumanReadable(parameters))
("retVariables", joinHumanReadable(returnVariables))
("code", std::move(code))
("astID", to_string(_varDecl.id()))
(
"astIDComment",
m_context.debugInfoSelection().astID ?
"/// @ast-id " + to_string(_varDecl.id()) + "\n" :
""
)
("sourceLocationComment", dispenseLocationComment(_varDecl))
(
"contractSourceLocationComment",
@ -829,7 +852,7 @@ void IRGenerator::generateConstructors(ContractDefinition const& _contract)
for (ASTPointer<VariableDeclaration> const& varDecl: contract->constructor()->parameters())
params += m_context.addLocalVariable(*varDecl).stackSlots();
if (contract->constructor())
if (m_context.debugInfoSelection().astID && contract->constructor())
t("astIDComment", "/// @ast-id " + to_string(contract->constructor()->id()) + "\n");
else
t("astIDComment", "");
@ -1085,6 +1108,7 @@ void IRGenerator::resetContext(ContractDefinition const& _contract, ExecutionCon
m_context.revertStrings(),
m_optimiserSettings,
m_context.sourceIndices(),
m_context.debugInfoSelection(),
m_context.soliditySourceProvider()
);
newContext.copyFunctionIDsFrom(m_context);

View File

@ -49,6 +49,7 @@ public:
RevertStrings _revertStrings,
OptimiserSettings _optimiserSettings,
std::map<std::string, unsigned> _sourceIndices,
langutil::DebugInfoSelection const& _debugInfoSelection,
langutil::CharStreamProvider const* _soliditySourceProvider
):
m_evmVersion(_evmVersion),
@ -59,6 +60,7 @@ public:
_revertStrings,
std::move(_optimiserSettings),
std::move(_sourceIndices),
_debugInfoSelection,
_soliditySourceProvider
),
m_utils(_evmVersion, m_context.revertStrings(), m_context.functionCollector())

View File

@ -271,6 +271,13 @@ void CompilerStack::setMetadataHash(MetadataHash _metadataHash)
m_metadataHash = _metadataHash;
}
void CompilerStack::selectDebugInfo(DebugInfoSelection _debugInfoSelection)
{
if (m_stackState >= CompilationSuccessful)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Must select debug info components before compilation."));
m_debugInfoSelection = _debugInfoSelection;
}
void CompilerStack::addSMTLib2Response(h256 const& _hash, string const& _response)
{
if (m_stackState >= ParsedAndImported)
@ -882,7 +889,7 @@ string CompilerStack::assemblyString(string const& _contractName, StringMap cons
Contract const& currentContract = contract(_contractName);
if (currentContract.evmAssembly)
return currentContract.evmAssembly->assemblyString(_sourceCodes);
return currentContract.evmAssembly->assemblyString(m_debugInfoSelection, _sourceCodes);
else
return string();
}
@ -1319,7 +1326,7 @@ void CompilerStack::generateIR(ContractDefinition const& _contract)
for (auto const& pair: m_contracts)
otherYulSources.emplace(pair.second.contract, pair.second.yulIR);
IRGenerator generator(m_evmVersion, m_revertStrings, m_optimiserSettings, sourceIndices(), this);
IRGenerator generator(m_evmVersion, m_revertStrings, m_optimiserSettings, sourceIndices(), m_debugInfoSelection, this);
tie(compiledContract.yulIR, compiledContract.yulIROptimized) = generator.run(
_contract,
createCBORMetadata(compiledContract, /* _forIR */ true),
@ -1342,7 +1349,12 @@ void CompilerStack::generateEVMFromIR(ContractDefinition const& _contract)
return;
// Re-parse the Yul IR in EVM dialect
yul::AssemblyStack stack(m_evmVersion, yul::AssemblyStack::Language::StrictAssembly, m_optimiserSettings);
yul::AssemblyStack stack(
m_evmVersion,
yul::AssemblyStack::Language::StrictAssembly,
m_optimiserSettings,
m_debugInfoSelection
);
stack.parseAndAnalyze("", compiledContract.yulIROptimized);
stack.optimize();
@ -1369,7 +1381,12 @@ void CompilerStack::generateEwasm(ContractDefinition const& _contract)
return;
// Re-parse the Yul IR in EVM dialect
yul::AssemblyStack stack(m_evmVersion, yul::AssemblyStack::Language::StrictAssembly, m_optimiserSettings);
yul::AssemblyStack stack(
m_evmVersion,
yul::AssemblyStack::Language::StrictAssembly,
m_optimiserSettings,
m_debugInfoSelection
);
stack.parseAndAnalyze("", compiledContract.yulIROptimized);
stack.optimize();

View File

@ -35,10 +35,11 @@
#include <libsmtutil/SolverInterface.h>
#include <liblangutil/CharStreamProvider.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/ErrorReporter.h>
#include <liblangutil/EVMVersion.h>
#include <liblangutil/SourceLocation.h>
#include <liblangutil/CharStreamProvider.h>
#include <libevmasm/LinkerObject.h>
@ -203,6 +204,9 @@ public:
/// @param _metadataHash can be IPFS, Bzzr1, None
void setMetadataHash(MetadataHash _metadataHash);
/// Select components of debug info that should be included in comments in generated assembly.
void selectDebugInfo(langutil::DebugInfoSelection _debugInfoSelection);
/// Sets the sources. Must be set before parsing.
void setSources(StringMap _sources);
@ -505,6 +509,7 @@ private:
langutil::ErrorReporter m_errorReporter;
bool m_metadataLiteralSources = false;
MetadataHash m_metadataHash = MetadataHash::IPFS;
langutil::DebugInfoSelection m_debugInfoSelection = langutil::DebugInfoSelection::Default();
bool m_parserErrorRecovery = false;
State m_stackState = Empty;
bool m_importedSources = false;

View File

@ -28,9 +28,13 @@
#include <libyul/AssemblyStack.h>
#include <libyul/Exceptions.h>
#include <libyul/optimiser/Suite.h>
#include <liblangutil/SourceReferenceFormatter.h>
#include <libevmasm/Instruction.h>
#include <libsmtutil/Exceptions.h>
#include <liblangutil/SourceReferenceFormatter.h>
#include <libsolutil/JSON.h>
#include <libsolutil/Keccak256.h>
#include <libsolutil/CommonData.h>
@ -793,7 +797,7 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
if (settings.isMember("debug"))
{
if (auto result = checkKeys(settings["debug"], {"revertStrings"}, "settings.debug"))
if (auto result = checkKeys(settings["debug"], {"revertStrings", "debugInfo"}, "settings.debug"))
return *result;
if (settings["debug"].isMember("revertStrings"))
@ -810,6 +814,31 @@ std::variant<StandardCompiler::InputsAndSettings, Json::Value> StandardCompiler:
);
ret.revertStrings = *revertStrings;
}
if (settings["debug"].isMember("debugInfo"))
{
if (!settings["debug"]["debugInfo"].isArray())
return formatFatalError("JSONError", "settings.debug.debugInfo must be an array.");
vector<string> components;
for (Json::Value const& arrayValue: settings["debug"]["debugInfo"])
components.push_back(arrayValue.asString());
optional<DebugInfoSelection> debugInfoSelection = DebugInfoSelection::fromComponents(
components,
true /* _acceptWildcards */
);
if (!debugInfoSelection.has_value())
return formatFatalError("JSONError", "Invalid value in settings.debug.debugInfo.");
if (debugInfoSelection->snippet && !debugInfoSelection->location)
return formatFatalError(
"JSONError",
"To use 'snippet' with settings.debug.debugInfo you must select also 'location'."
);
ret.debugInfoSelection = debugInfoSelection.value();
}
}
if (settings.isMember("remappings") && !settings["remappings"].isArray())
@ -1029,6 +1058,8 @@ Json::Value StandardCompiler::compileSolidity(StandardCompiler::InputsAndSetting
compilerStack.setRemappings(move(_inputsAndSettings.remappings));
compilerStack.setOptimiserSettings(std::move(_inputsAndSettings.optimiserSettings));
compilerStack.setRevertStringBehaviour(_inputsAndSettings.revertStrings);
if (_inputsAndSettings.debugInfoSelection.has_value())
compilerStack.selectDebugInfo(_inputsAndSettings.debugInfoSelection.value());
compilerStack.setLibraries(_inputsAndSettings.libraries);
compilerStack.useMetadataLiteralSources(_inputsAndSettings.metadataLiteralSources);
compilerStack.setMetadataHash(_inputsAndSettings.metadataHash);
@ -1358,7 +1389,10 @@ Json::Value StandardCompiler::compileYul(InputsAndSettings _inputsAndSettings)
AssemblyStack stack(
_inputsAndSettings.evmVersion,
AssemblyStack::Language::StrictAssembly,
_inputsAndSettings.optimiserSettings
_inputsAndSettings.optimiserSettings,
_inputsAndSettings.debugInfoSelection.has_value() ?
_inputsAndSettings.debugInfoSelection.value() :
DebugInfoSelection::Default()
);
string const& sourceName = _inputsAndSettings.sources.begin()->first;
string const& sourceContents = _inputsAndSettings.sources.begin()->second;

View File

@ -26,6 +26,8 @@
#include <libsolidity/interface/CompilerStack.h>
#include <libsolutil/JSON.h>
#include <liblangutil/DebugInfoSelection.h>
#include <optional>
#include <utility>
#include <variant>
@ -78,6 +80,7 @@ private:
std::vector<ImportRemapper::Remapping> remappings;
RevertStrings revertStrings = RevertStrings::Default;
OptimiserSettings optimiserSettings = OptimiserSettings::minimal();
std::optional<langutil::DebugInfoSelection> debugInfoSelection;
std::map<std::string, util::h160> libraries;
bool metadataLiteralSources = false;
CompilerStack::MetadataHash metadataHash = CompilerStack::MetadataHash::IPFS;

View File

@ -261,10 +261,16 @@ string AsmPrinter::appendTypeName(YulString _type, bool _isBoolLiteral) const
string AsmPrinter::formatSourceLocation(
SourceLocation const& _location,
map<string, unsigned> const& _nameToSourceIndex,
DebugInfoSelection const& _debugInfoSelection,
CharStreamProvider const* _soliditySourceProvider
)
{
yulAssert(!_nameToSourceIndex.empty(), "");
if (_debugInfoSelection.snippet)
yulAssert(_debugInfoSelection.location, "@src tag must always contain the source location");
if (_debugInfoSelection.none())
return "";
string sourceIndex = "-1";
string solidityCodeSnippet = "";
@ -272,7 +278,7 @@ string AsmPrinter::formatSourceLocation(
{
sourceIndex = to_string(_nameToSourceIndex.at(*_location.sourceName));
if (_soliditySourceProvider)
if (_debugInfoSelection.snippet && _soliditySourceProvider)
{
solidityCodeSnippet = escapeAndQuoteString(
_soliditySourceProvider->charStream(*_location.sourceName).singleLineSnippet(_location)
@ -298,12 +304,13 @@ string AsmPrinter::formatSourceLocation(
string AsmPrinter::formatDebugData(shared_ptr<DebugData const> const& _debugData, bool _statement)
{
if (!_debugData)
if (!_debugData || m_debugInfoSelection.none())
return "";
vector<string> items;
if (auto id = _debugData->astID)
items.emplace_back("@ast-id " + to_string(*id));
if (m_debugInfoSelection.astID)
items.emplace_back("@ast-id " + to_string(*id));
if (
m_lastLocation != _debugData->originLocation &&
@ -315,6 +322,7 @@ string AsmPrinter::formatDebugData(shared_ptr<DebugData const> const& _debugData
items.emplace_back(formatSourceLocation(
_debugData->originLocation,
m_nameToSourceIndex,
m_debugInfoSelection,
m_soliditySourceProvider
));
}

View File

@ -29,6 +29,7 @@
#include <libsolutil/CommonData.h>
#include <liblangutil/CharStreamProvider.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/SourceLocation.h>
#include <map>
@ -48,9 +49,11 @@ public:
explicit AsmPrinter(
Dialect const* _dialect = nullptr,
std::optional<std::map<unsigned, std::shared_ptr<std::string const>>> _sourceIndexToName = {},
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
langutil::CharStreamProvider const* _soliditySourceProvider = nullptr
):
m_dialect(_dialect),
m_debugInfoSelection(_debugInfoSelection),
m_soliditySourceProvider(_soliditySourceProvider)
{
if (_sourceIndexToName)
@ -58,12 +61,12 @@ public:
m_nameToSourceIndex[*name] = index;
}
explicit AsmPrinter(
Dialect const& _dialect,
std::optional<std::map<unsigned, std::shared_ptr<std::string const>>> _sourceIndexToName = {},
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
langutil::CharStreamProvider const* _soliditySourceProvider = nullptr
): AsmPrinter(&_dialect, _sourceIndexToName, _soliditySourceProvider) {}
): AsmPrinter(&_dialect, _sourceIndexToName, _debugInfoSelection, _soliditySourceProvider) {}
std::string operator()(Literal const& _literal);
std::string operator()(Identifier const& _identifier);
@ -83,6 +86,7 @@ public:
static std::string formatSourceLocation(
langutil::SourceLocation const& _location,
std::map<std::string, unsigned> const& _nameToSourceIndex,
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr
);
@ -100,6 +104,7 @@ private:
Dialect const* const m_dialect = nullptr;
std::map<std::string, unsigned> m_nameToSourceIndex;
langutil::SourceLocation m_lastLocation = {};
langutil::DebugInfoSelection m_debugInfoSelection = {};
langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr;
};

View File

@ -249,7 +249,7 @@ AssemblyStack::assembleWithDeployed(optional<string_view> _deployName) const
MachineAssemblyObject creationObject;
creationObject.bytecode = make_shared<evmasm::LinkerObject>(creationAssembly->assemble());
yulAssert(creationObject.bytecode->immutableReferences.empty(), "Leftover immutables.");
creationObject.assembly = creationAssembly->assemblyString();
creationObject.assembly = creationAssembly->assemblyString(m_debugInfoSelection);
creationObject.sourceMappings = make_unique<string>(
evmasm::AssemblyItem::computeSourceMapping(
creationAssembly->items(),
@ -261,7 +261,7 @@ AssemblyStack::assembleWithDeployed(optional<string_view> _deployName) const
if (deployedAssembly)
{
deployedObject.bytecode = make_shared<evmasm::LinkerObject>(deployedAssembly->assemble());
deployedObject.assembly = deployedAssembly->assemblyString();
deployedObject.assembly = deployedAssembly->assemblyString(m_debugInfoSelection);
deployedObject.sourceMappings = make_unique<string>(
evmasm::AssemblyItem::computeSourceMapping(
deployedAssembly->items(),
@ -314,11 +314,13 @@ AssemblyStack::assembleEVMWithDeployed(optional<string_view> _deployName) const
return {make_shared<evmasm::Assembly>(assembly), {}};
}
string AssemblyStack::print(CharStreamProvider const* _soliditySourceProvider) const
string AssemblyStack::print(
CharStreamProvider const* _soliditySourceProvider
) const
{
yulAssert(m_parserResult, "");
yulAssert(m_parserResult->code, "");
return m_parserResult->toString(&languageToDialect(m_language, m_evmVersion), _soliditySourceProvider) + "\n";
return m_parserResult->toString(&languageToDialect(m_language, m_evmVersion), m_debugInfoSelection, _soliditySourceProvider) + "\n";
}
shared_ptr<Object> AssemblyStack::parserResult() const

View File

@ -22,9 +22,10 @@
#pragma once
#include <liblangutil/CharStreamProvider.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/ErrorReporter.h>
#include <liblangutil/EVMVersion.h>
#include <liblangutil/CharStreamProvider.h>
#include <libyul/Object.h>
#include <libyul/ObjectParser.h>
@ -69,12 +70,24 @@ public:
enum class Machine { EVM, Ewasm };
AssemblyStack():
AssemblyStack(langutil::EVMVersion{}, Language::Assembly, solidity::frontend::OptimiserSettings::none())
AssemblyStack(
langutil::EVMVersion{},
Language::Assembly,
solidity::frontend::OptimiserSettings::none(),
langutil::DebugInfoSelection::Default()
)
{}
AssemblyStack(langutil::EVMVersion _evmVersion, Language _language, solidity::frontend::OptimiserSettings _optimiserSettings):
AssemblyStack(
langutil::EVMVersion _evmVersion,
Language _language,
solidity::frontend::OptimiserSettings _optimiserSettings,
langutil::DebugInfoSelection const& _debugInfoSelection
):
m_language(_language),
m_evmVersion(_evmVersion),
m_optimiserSettings(std::move(_optimiserSettings)),
m_debugInfoSelection(_debugInfoSelection),
m_errorReporter(m_errors)
{}
@ -116,7 +129,9 @@ public:
langutil::ErrorList const& errors() const { return m_errors; }
/// Pretty-print the input after having parsed it.
std::string print(langutil::CharStreamProvider const* _soliditySourceProvider = nullptr) const;
std::string print(
langutil::CharStreamProvider const* _soliditySourceProvider = nullptr
) const;
/// Return the parsed and analyzed object.
std::shared_ptr<Object> parserResult() const;
@ -132,6 +147,7 @@ private:
Language m_language = Language::Assembly;
langutil::EVMVersion m_evmVersion;
solidity::frontend::OptimiserSettings m_optimiserSettings;
langutil::DebugInfoSelection m_debugInfoSelection{};
std::unique_ptr<langutil::CharStream> m_charStream;

View File

@ -51,13 +51,14 @@ string indent(std::string const& _input)
}
string Data::toString(Dialect const*, CharStreamProvider const*) const
string Data::toString(Dialect const*, DebugInfoSelection const&, CharStreamProvider const*) const
{
return "data \"" + name.str() + "\" hex\"" + util::toHex(data) + "\"";
}
string Object::toString(
Dialect const* _dialect,
DebugInfoSelection const& _debugInfoSelection,
CharStreamProvider const* _soliditySourceProvider
) const
{
@ -74,10 +75,15 @@ string Object::toString(
})) +
"\n";
string inner = "code " + AsmPrinter{_dialect, debugData->sourceNames, _soliditySourceProvider}(*code);
string inner = "code " + AsmPrinter(
_dialect,
debugData->sourceNames,
_debugInfoSelection,
_soliditySourceProvider
)(*code);
for (auto const& obj: subObjects)
inner += "\n" + obj->toString(_dialect, _soliditySourceProvider);
inner += "\n" + obj->toString(_dialect, _debugInfoSelection, _soliditySourceProvider);
return useSrcComment + "object \"" + name.str() + "\" {\n" + indent(inner) + "\n}";
}

View File

@ -25,6 +25,7 @@
#include <libyul/YulString.h>
#include <liblangutil/CharStreamProvider.h>
#include <liblangutil/DebugInfoSelection.h>
#include <libsolutil/Common.h>
@ -54,6 +55,7 @@ struct ObjectNode
YulString name;
virtual std::string toString(
Dialect const* _dialect,
langutil::DebugInfoSelection const& _debugInfoSelection,
langutil::CharStreamProvider const* _soliditySourceProvider
) const = 0;
};
@ -69,6 +71,7 @@ struct Data: public ObjectNode
std::string toString(
Dialect const* _dialect,
langutil::DebugInfoSelection const& _debugInfoSelection,
langutil::CharStreamProvider const* _soliditySourceProvider
) const override;
};
@ -89,6 +92,7 @@ public:
/// @returns a (parseable) string representation.
std::string toString(
Dialect const* _dialect,
langutil::DebugInfoSelection const& _debugInfoSelection = langutil::DebugInfoSelection::Default(),
langutil::CharStreamProvider const* _soliditySourceProvider = nullptr
) const;

View File

@ -23,7 +23,6 @@
#include <libyul/AST.h>
#include <libyul/Exceptions.h>
#include <libyul/Utilities.h>
#include <libyul/AsmPrinter.h>
#include <libsolutil/cxx20.h>
#include <libsolutil/Visitor.h>

View File

@ -631,6 +631,8 @@ bool CommandLineInterface::compile()
m_compiler->setViaIR(m_options.output.experimentalViaIR);
m_compiler->setEVMVersion(m_options.output.evmVersion);
m_compiler->setRevertStringBehaviour(m_options.output.revertStrings);
if (m_options.output.debugInfoSelection.has_value())
m_compiler->selectDebugInfo(m_options.output.debugInfoSelection.value());
// TODO: Perhaps we should not compile unless requested
m_compiler->enableIRGeneration(m_options.compiler.outputs.ir || m_options.compiler.outputs.irOptimized);
@ -972,7 +974,10 @@ bool CommandLineInterface::assemble(yul::AssemblyStack::Language _language, yul:
auto& stack = assemblyStacks[src.first] = yul::AssemblyStack(
m_options.output.evmVersion,
_language,
m_options.optimiserSettings()
m_options.optimiserSettings(),
m_options.output.debugInfoSelection.has_value() ?
m_options.output.debugInfoSelection.value() :
DebugInfoSelection::Default()
);
if (!stack.parseAndAnalyze(src.first, src.second))

View File

@ -67,6 +67,7 @@ static string const g_strImportAst = "import-ast";
static string const g_strInputFile = "input-file";
static string const g_strYul = "yul";
static string const g_strYulDialect = "yul-dialect";
static string const g_strDebugInfo = "debug-info";
static string const g_strIPFS = "ipfs";
static string const g_strLicense = "license";
static string const g_strLibraries = "libraries";
@ -252,6 +253,7 @@ bool CommandLineOptions::operator==(CommandLineOptions const& _other) const noex
output.evmVersion == _other.output.evmVersion &&
output.experimentalViaIR == _other.output.experimentalViaIR &&
output.revertStrings == _other.output.revertStrings &&
output.debugInfoSelection == _other.output.debugInfoSelection &&
output.stopAfter == _other.output.stopAfter &&
input.mode == _other.input.mode &&
assembly.targetMachine == _other.assembly.targetMachine &&
@ -595,6 +597,13 @@ General Information)").c_str(),
po::value<string>()->value_name(joinHumanReadable(g_revertStringsArgs, ",")),
"Strip revert (and require) reason strings or add additional debugging information."
)
(
g_strDebugInfo.c_str(),
po::value<string>()->default_value(toString(DebugInfoSelection::Default())),
("Debug info components to be included in the produced EVM assembly and Yul code. "
"Value can be all, none or a comma-separated list containing one or more of the "
"following components: " + joinHumanReadable(DebugInfoSelection::componentMap() | ranges::views::keys) + ".").c_str()
)
(
g_strStopAfter.c_str(),
po::value<string>()->value_name("stage"),
@ -935,6 +944,12 @@ bool CommandLineParser::processArgs()
serr() << "Option --" << option << " is only valid in compiler and assembler modes." << endl;
return false;
}
if (!m_args[g_strDebugInfo].defaulted())
{
serr() << "Option --" << g_strDebugInfo << " is only valid in compiler and assembler modes." << endl;
return false;
}
}
if (m_args.count(g_strColor) > 0)
@ -961,6 +976,23 @@ bool CommandLineParser::processArgs()
m_options.output.revertStrings = *revertStrings;
}
if (!m_args[g_strDebugInfo].defaulted())
{
string optionValue = m_args[g_strDebugInfo].as<string>();
m_options.output.debugInfoSelection = DebugInfoSelection::fromString(optionValue);
if (!m_options.output.debugInfoSelection.has_value())
{
serr() << "Invalid value for --" << g_strDebugInfo << " option: " << optionValue << endl;
return false;
}
if (m_options.output.debugInfoSelection->snippet && !m_options.output.debugInfoSelection->location)
{
serr() << "To use 'snippet' with --" << g_strDebugInfo << " you must select also 'location'." << endl;
return false;
}
}
if (!parseCombinedJsonOption())
return false;

View File

@ -24,8 +24,12 @@
#include <libsolidity/interface/DebugSettings.h>
#include <libsolidity/interface/FileReader.h>
#include <libsolidity/interface/ImportRemapper.h>
#include <libyul/AssemblyStack.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/EVMVersion.h>
#include <libsolutil/JSON.h>
#include <boost/program_options.hpp>
@ -174,6 +178,7 @@ struct CommandLineOptions
langutil::EVMVersion evmVersion;
bool experimentalViaIR = false;
RevertStrings revertStrings = RevertStrings::Default;
std::optional<langutil::DebugInfoSelection> debugInfoSelection;
CompilerStack::State stopAfter = CompilerStack::State::CompilationSuccessful;
} output;

View File

@ -0,0 +1 @@
--ir --ir-optimized --asm --optimize --debug-info all

View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
pragma solidity >=0.0;
contract C {
function f() public {}
}

View File

@ -0,0 +1,213 @@
======= debug_info_in_yul_and_evm_asm_print_all/input.sol:C =======
EVM assembly:
/* "debug_info_in_yul_and_evm_asm_print_all/input.sol":60:101 contract C {... */
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
dataSize(sub_0)
dup1
dataOffset(sub_0)
0x00
codecopy
0x00
return
stop
sub_0: assembly {
/* "debug_info_in_yul_and_evm_asm_print_all/input.sol":60:101 contract C {... */
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
jumpi(tag_2, lt(calldatasize, 0x04))
shr(0xe0, calldataload(0x00))
dup1
0x26121ff0
eq
tag_3
jumpi
tag_2:
0x00
dup1
revert
/* "debug_info_in_yul_and_evm_asm_print_all/input.sol":77:99 function f() public {} */
tag_3:
stop
auxdata: <AUXDATA REMOVED>
}
IR:
/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol"
object "C_6" {
code {
/// @src 0:60:101 "contract C {..."
mstore(64, 128)
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
constructor_C_6()
let _1 := allocate_unbounded()
codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed"))
return(_1, datasize("C_6_deployed"))
function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}
/// @src 0:60:101 "contract C {..."
function constructor_C_6() {
/// @src 0:60:101 "contract C {..."
}
/// @src 0:60:101 "contract C {..."
}
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101 "contract C {..."
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
switch selector
case 0x26121ff0
{
// f()
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
abi_decode_tuple_(4, calldatasize())
fun_f_5()
let memPos := allocate_unbounded()
let memEnd := abi_encode_tuple__to__fromStack(memPos )
return(memPos, sub(memEnd, memPos))
}
default {}
}
if iszero(calldatasize()) { }
revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()
function shift_right_224_unsigned(value) -> newValue {
newValue :=
shr(224, value)
}
function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}
function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
revert(0, 0)
}
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }
}
function abi_encode_tuple__to__fromStack(headStart ) -> tail {
tail := add(headStart, 0)
}
function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
revert(0, 0)
}
/// @ast-id 5
/// @src 0:77:99 "function f() public {}"
function fun_f_5() {
}
/// @src 0:60:101 "contract C {..."
}
data ".metadata" hex"<BYTECODE REMOVED>"
}
}
Optimized IR:
/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol"
object "C_6" {
code {
{
/// @src 0:60:101 "contract C {..."
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize("C_6_deployed")
codecopy(128, dataoffset("C_6_deployed"), _1)
return(128, _1)
}
}
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_all/input.sol"
object "C_6_deployed" {
code {
{
/// @src 0:60:101 "contract C {..."
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let _1 := 0
if eq(0x26121ff0, shr(224, calldataload(_1)))
{
if callvalue() { revert(_1, _1) }
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
return(128, _1)
}
}
revert(0, 0)
}
}
data ".metadata" hex"<BYTECODE REMOVED>"
}
}

View File

@ -0,0 +1 @@
--ir --ir-optimized --asm --optimize --debug-info location,all,none

View File

@ -0,0 +1 @@
Invalid value for --debug-info option: location,all,none

View File

@ -0,0 +1 @@
--ir --ir-optimized --asm --optimize --debug-info location

View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
pragma solidity >=0.0;
contract C {
function f() public {}
}

View File

@ -0,0 +1,212 @@
======= debug_info_in_yul_and_evm_asm_print_location_only/input.sol:C =======
EVM assembly:
/* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":60:101 */
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
dataSize(sub_0)
dup1
dataOffset(sub_0)
0x00
codecopy
0x00
return
stop
sub_0: assembly {
/* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":60:101 */
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
jumpi(tag_2, lt(calldatasize, 0x04))
shr(0xe0, calldataload(0x00))
dup1
0x26121ff0
eq
tag_3
jumpi
tag_2:
0x00
dup1
revert
/* "debug_info_in_yul_and_evm_asm_print_location_only/input.sol":77:99 */
tag_3:
stop
auxdata: <AUXDATA REMOVED>
}
IR:
/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol"
object "C_6" {
code {
/// @src 0:60:101
mstore(64, 128)
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
constructor_C_6()
let _1 := allocate_unbounded()
codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed"))
return(_1, datasize("C_6_deployed"))
function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}
/// @src 0:60:101
function constructor_C_6() {
/// @src 0:60:101
}
/// @src 0:60:101
}
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
switch selector
case 0x26121ff0
{
// f()
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
abi_decode_tuple_(4, calldatasize())
fun_f_5()
let memPos := allocate_unbounded()
let memEnd := abi_encode_tuple__to__fromStack(memPos )
return(memPos, sub(memEnd, memPos))
}
default {}
}
if iszero(calldatasize()) { }
revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()
function shift_right_224_unsigned(value) -> newValue {
newValue :=
shr(224, value)
}
function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}
function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
revert(0, 0)
}
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }
}
function abi_encode_tuple__to__fromStack(headStart ) -> tail {
tail := add(headStart, 0)
}
function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
revert(0, 0)
}
/// @src 0:77:99
function fun_f_5() {
}
/// @src 0:60:101
}
data ".metadata" hex"<BYTECODE REMOVED>"
}
}
Optimized IR:
/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol"
object "C_6" {
code {
{
/// @src 0:60:101
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize("C_6_deployed")
codecopy(128, dataoffset("C_6_deployed"), _1)
return(128, _1)
}
}
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_location_only/input.sol"
object "C_6_deployed" {
code {
{
/// @src 0:60:101
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let _1 := 0
if eq(0x26121ff0, shr(224, calldataload(_1)))
{
if callvalue() { revert(_1, _1) }
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
return(128, _1)
}
}
revert(0, 0)
}
}
data ".metadata" hex"<BYTECODE REMOVED>"
}
}

View File

@ -0,0 +1 @@
--ir --ir-optimized --asm --optimize --debug-info none

View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
pragma solidity >=0.0;
contract C {
function f() public {}
}

View File

@ -0,0 +1,201 @@
======= debug_info_in_yul_and_evm_asm_print_none/input.sol:C =======
EVM assembly:
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
dataSize(sub_0)
dup1
dataOffset(sub_0)
0x00
codecopy
0x00
return
stop
sub_0: assembly {
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
jumpi(tag_2, lt(calldatasize, 0x04))
shr(0xe0, calldataload(0x00))
dup1
0x26121ff0
eq
tag_3
jumpi
tag_2:
0x00
dup1
revert
tag_3:
stop
auxdata: <AUXDATA REMOVED>
}
IR:
/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol"
object "C_6" {
code {
mstore(64, 128)
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
constructor_C_6()
let _1 := allocate_unbounded()
codecopy(_1, dataoffset("C_6_deployed"), datasize("C_6_deployed"))
return(_1, datasize("C_6_deployed"))
function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}
function constructor_C_6() {
}
}
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol"
object "C_6_deployed" {
code {
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
switch selector
case 0x26121ff0
{
// f()
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
abi_decode_tuple_(4, calldatasize())
fun_f_5()
let memPos := allocate_unbounded()
let memEnd := abi_encode_tuple__to__fromStack(memPos )
return(memPos, sub(memEnd, memPos))
}
default {}
}
if iszero(calldatasize()) { }
revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()
function shift_right_224_unsigned(value) -> newValue {
newValue :=
shr(224, value)
}
function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}
function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
revert(0, 0)
}
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }
}
function abi_encode_tuple__to__fromStack(headStart ) -> tail {
tail := add(headStart, 0)
}
function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
revert(0, 0)
}
function fun_f_5() {
}
}
data ".metadata" hex"<BYTECODE REMOVED>"
}
}
Optimized IR:
/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol"
object "C_6" {
code {
{
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize("C_6_deployed")
codecopy(128, dataoffset("C_6_deployed"), _1)
return(128, _1)
}
}
/// @use-src 0:"debug_info_in_yul_and_evm_asm_print_none/input.sol"
object "C_6_deployed" {
code {
{
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let _1 := 0
if eq(0x26121ff0, shr(224, calldataload(_1)))
{
if callvalue() { revert(_1, _1) }
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
return(128, _1)
}
}
revert(0, 0)
}
}
data ".metadata" hex"<BYTECODE REMOVED>"
}
}

View File

@ -0,0 +1 @@
--ir --ir-optimized --asm --optimize --debug-info snippet

View File

@ -0,0 +1 @@
To use 'snippet' with --debug-info you must select also 'location'.

View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
pragma solidity >=0.0;
contract C {
function f() public {}
}

View File

@ -0,0 +1 @@
--pretty-json --json-indent 4 --allow-paths .

View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
pragma solidity >=0.0;
contract C {
function f() public {}
}

View File

@ -0,0 +1,13 @@
{
"language": "Solidity",
"sources": {
"C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_all/in.sol"]}
},
"settings": {
"debug": {"debugInfo": ["*"]},
"optimizer": {"enabled": true},
"outputSelection": {
"*": {"*": ["ir", "irOptimized", "evm.assembly"]}
}
}
}

View File

@ -0,0 +1,230 @@
{
"contracts":
{
"C":
{
"C":
{
"evm":
{
"assembly": " /* \"C\":60:101 contract C {... */
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
dataSize(sub_0)
dup1
dataOffset(sub_0)
0x00
codecopy
0x00
return
stop
sub_0: assembly {
/* \"C\":60:101 contract C {... */
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
jumpi(tag_2, lt(calldatasize, 0x04))
shr(0xe0, calldataload(0x00))
dup1
0x26121ff0
eq
tag_3
jumpi
tag_2:
0x00
dup1
revert
/* \"C\":77:99 function f() public {} */
tag_3:
stop
auxdata: <AUXDATA REMOVED>
}
"
},
"ir": "/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:\"C\"
object \"C_6\" {
code {
/// @src 0:60:101 \"contract C {...\"
mstore(64, 128)
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
constructor_C_6()
let _1 := allocate_unbounded()
codecopy(_1, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))
return(_1, datasize(\"C_6_deployed\"))
function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}
/// @src 0:60:101 \"contract C {...\"
function constructor_C_6() {
/// @src 0:60:101 \"contract C {...\"
}
/// @src 0:60:101 \"contract C {...\"
}
/// @use-src 0:\"C\"
object \"C_6_deployed\" {
code {
/// @src 0:60:101 \"contract C {...\"
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
switch selector
case 0x26121ff0
{
// f()
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
abi_decode_tuple_(4, calldatasize())
fun_f_5()
let memPos := allocate_unbounded()
let memEnd := abi_encode_tuple__to__fromStack(memPos )
return(memPos, sub(memEnd, memPos))
}
default {}
}
if iszero(calldatasize()) { }
revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()
function shift_right_224_unsigned(value) -> newValue {
newValue :=
shr(224, value)
}
function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}
function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
revert(0, 0)
}
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }
}
function abi_encode_tuple__to__fromStack(headStart ) -> tail {
tail := add(headStart, 0)
}
function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
revert(0, 0)
}
/// @ast-id 5
/// @src 0:77:99 \"function f() public {}\"
function fun_f_5() {
}
/// @src 0:60:101 \"contract C {...\"
}
data \".metadata\" hex\"<BYTECODE REMOVED>\"
}
}
",
"irOptimized": "/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:\"C\"
object \"C_6\" {
code {
{
/// @src 0:60:101 \"contract C {...\"
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize(\"C_6_deployed\")
codecopy(128, dataoffset(\"C_6_deployed\"), _1)
return(128, _1)
}
}
/// @use-src 0:\"C\"
object \"C_6_deployed\" {
code {
{
/// @src 0:60:101 \"contract C {...\"
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let _1 := 0
if eq(0x26121ff0, shr(224, calldataload(_1)))
{
if callvalue() { revert(_1, _1) }
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
return(128, _1)
}
}
revert(0, 0)
}
}
data \".metadata\" hex\"<BYTECODE REMOVED>\"
}
}
"
}
}
},
"sources":
{
"C":
{
"id": 0
}
}
}

View File

@ -0,0 +1 @@
--pretty-json --json-indent 4 --allow-paths .

View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
pragma solidity >=0.0;
contract C {
function f() public {}
}

View File

@ -0,0 +1,13 @@
{
"language": "Solidity",
"sources": {
"C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_location_only/in.sol"]}
},
"settings": {
"debug": {"debugInfo": ["location"]},
"optimizer": {"enabled": true},
"outputSelection": {
"*": {"*": ["ir", "irOptimized", "evm.assembly"]}
}
}
}

View File

@ -0,0 +1,229 @@
{
"contracts":
{
"C":
{
"C":
{
"evm":
{
"assembly": " /* \"C\":60:101 */
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
dataSize(sub_0)
dup1
dataOffset(sub_0)
0x00
codecopy
0x00
return
stop
sub_0: assembly {
/* \"C\":60:101 */
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
jumpi(tag_2, lt(calldatasize, 0x04))
shr(0xe0, calldataload(0x00))
dup1
0x26121ff0
eq
tag_3
jumpi
tag_2:
0x00
dup1
revert
/* \"C\":77:99 */
tag_3:
stop
auxdata: <AUXDATA REMOVED>
}
"
},
"ir": "/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:\"C\"
object \"C_6\" {
code {
/// @src 0:60:101
mstore(64, 128)
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
constructor_C_6()
let _1 := allocate_unbounded()
codecopy(_1, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))
return(_1, datasize(\"C_6_deployed\"))
function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}
/// @src 0:60:101
function constructor_C_6() {
/// @src 0:60:101
}
/// @src 0:60:101
}
/// @use-src 0:\"C\"
object \"C_6_deployed\" {
code {
/// @src 0:60:101
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
switch selector
case 0x26121ff0
{
// f()
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
abi_decode_tuple_(4, calldatasize())
fun_f_5()
let memPos := allocate_unbounded()
let memEnd := abi_encode_tuple__to__fromStack(memPos )
return(memPos, sub(memEnd, memPos))
}
default {}
}
if iszero(calldatasize()) { }
revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()
function shift_right_224_unsigned(value) -> newValue {
newValue :=
shr(224, value)
}
function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}
function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
revert(0, 0)
}
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }
}
function abi_encode_tuple__to__fromStack(headStart ) -> tail {
tail := add(headStart, 0)
}
function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
revert(0, 0)
}
/// @src 0:77:99
function fun_f_5() {
}
/// @src 0:60:101
}
data \".metadata\" hex\"<BYTECODE REMOVED>\"
}
}
",
"irOptimized": "/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:\"C\"
object \"C_6\" {
code {
{
/// @src 0:60:101
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize(\"C_6_deployed\")
codecopy(128, dataoffset(\"C_6_deployed\"), _1)
return(128, _1)
}
}
/// @use-src 0:\"C\"
object \"C_6_deployed\" {
code {
{
/// @src 0:60:101
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let _1 := 0
if eq(0x26121ff0, shr(224, calldataload(_1)))
{
if callvalue() { revert(_1, _1) }
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
return(128, _1)
}
}
revert(0, 0)
}
}
data \".metadata\" hex\"<BYTECODE REMOVED>\"
}
}
"
}
}
},
"sources":
{
"C":
{
"id": 0
}
}
}

View File

@ -0,0 +1 @@
--pretty-json --json-indent 4 --allow-paths .

View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
pragma solidity >=0.0;
contract C {
function f() public {}
}

View File

@ -0,0 +1,13 @@
{
"language": "Solidity",
"sources": {
"C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_none/in.sol"]}
},
"settings": {
"debug": {"debugInfo": []},
"optimizer": {"enabled": true},
"outputSelection": {
"*": {"*": ["ir", "irOptimized", "evm.assembly"]}
}
}
}

View File

@ -0,0 +1,218 @@
{
"contracts":
{
"C":
{
"C":
{
"evm":
{
"assembly": " mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
dataSize(sub_0)
dup1
dataOffset(sub_0)
0x00
codecopy
0x00
return
stop
sub_0: assembly {
mstore(0x40, 0x80)
callvalue
dup1
iszero
tag_1
jumpi
0x00
dup1
revert
tag_1:
pop
jumpi(tag_2, lt(calldatasize, 0x04))
shr(0xe0, calldataload(0x00))
dup1
0x26121ff0
eq
tag_3
jumpi
tag_2:
0x00
dup1
revert
tag_3:
stop
auxdata: <AUXDATA REMOVED>
}
"
},
"ir": "/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:\"C\"
object \"C_6\" {
code {
mstore(64, 128)
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
constructor_C_6()
let _1 := allocate_unbounded()
codecopy(_1, dataoffset(\"C_6_deployed\"), datasize(\"C_6_deployed\"))
return(_1, datasize(\"C_6_deployed\"))
function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}
function constructor_C_6() {
}
}
/// @use-src 0:\"C\"
object \"C_6_deployed\" {
code {
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let selector := shift_right_224_unsigned(calldataload(0))
switch selector
case 0x26121ff0
{
// f()
if callvalue() { revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() }
abi_decode_tuple_(4, calldatasize())
fun_f_5()
let memPos := allocate_unbounded()
let memEnd := abi_encode_tuple__to__fromStack(memPos )
return(memPos, sub(memEnd, memPos))
}
default {}
}
if iszero(calldatasize()) { }
revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74()
function shift_right_224_unsigned(value) -> newValue {
newValue :=
shr(224, value)
}
function allocate_unbounded() -> memPtr {
memPtr := mload(64)
}
function revert_error_ca66f745a3ce8ff40e2ccaf1ad45db7774001b90d25810abd9040049be7bf4bb() {
revert(0, 0)
}
function revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() {
revert(0, 0)
}
function abi_decode_tuple_(headStart, dataEnd) {
if slt(sub(dataEnd, headStart), 0) { revert_error_dbdddcbe895c83990c08b3492a0e83918d802a52331272ac6fdb6a7c4aea3b1b() }
}
function abi_encode_tuple__to__fromStack(headStart ) -> tail {
tail := add(headStart, 0)
}
function revert_error_42b3090547df1d2001c96683413b8cf91c1b902ef5e3cb8d9f6f304cf7446f74() {
revert(0, 0)
}
function fun_f_5() {
}
}
data \".metadata\" hex\"<BYTECODE REMOVED>\"
}
}
",
"irOptimized": "/*=====================================================*
* WARNING *
* Solidity to Yul compilation is still EXPERIMENTAL *
* It can result in LOSS OF FUNDS or worse *
* !USE AT YOUR OWN RISK! *
*=====================================================*/
/// @use-src 0:\"C\"
object \"C_6\" {
code {
{
mstore(64, 128)
if callvalue() { revert(0, 0) }
let _1 := datasize(\"C_6_deployed\")
codecopy(128, dataoffset(\"C_6_deployed\"), _1)
return(128, _1)
}
}
/// @use-src 0:\"C\"
object \"C_6_deployed\" {
code {
{
mstore(64, 128)
if iszero(lt(calldatasize(), 4))
{
let _1 := 0
if eq(0x26121ff0, shr(224, calldataload(_1)))
{
if callvalue() { revert(_1, _1) }
if slt(add(calldatasize(), not(3)), _1) { revert(_1, _1) }
return(128, _1)
}
}
revert(0, 0)
}
}
data \".metadata\" hex\"<BYTECODE REMOVED>\"
}
}
"
}
}
},
"sources":
{
"C":
{
"id": 0
}
}
}

View File

@ -0,0 +1 @@
--pretty-json --json-indent 4 --allow-paths .

View File

@ -0,0 +1,6 @@
// SPDX-License-Identifier: GPL-2.0
pragma solidity >=0.0;
contract C {
function f() public {}
}

View File

@ -0,0 +1,13 @@
{
"language": "Solidity",
"sources": {
"C": {"urls": ["standard_debug_info_in_yul_and_evm_asm_print_snippet_only/in.sol"]}
},
"settings": {
"debug": {"debugInfo": ["snippet"]},
"optimizer": {"enabled": true},
"outputSelection": {
"*": {"*": ["ir", "irOptimized", "evm.assembly"]}
}
}
}

View File

@ -0,0 +1,12 @@
{
"errors":
[
{
"component": "general",
"formattedMessage": "To use 'snippet' with settings.debug.debugInfo you must select also 'location'.",
"message": "To use 'snippet' with settings.debug.debugInfo you must select also 'location'.",
"severity": "error",
"type": "JSONError"
}
]
}

View File

@ -0,0 +1 @@
--pretty-json --json-indent 4 --allow-paths .

View File

@ -0,0 +1,15 @@
/// @use-src 0:"input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101 "contract C {..."
mstore(64, 128)
// f()
fun_f_5()
/// @src 0:77:99 "function f() public {}"
function fun_f_5() {
}
/// @src 0:60:101 "contract C {..."
}
}

View File

@ -0,0 +1,12 @@
{
"language": "Yul",
"sources": {
"C": {"urls": ["standard_yul_debug_info_print_all/in.yul"]}
},
"settings": {
"debug": {"debugInfo": ["*"]},
"outputSelection": {
"*": {"*": ["evm.assembly"]}
}
}
}

View File

@ -0,0 +1,36 @@
{
"contracts":
{
"C":
{
"C_6_deployed":
{
"evm":
{
"assembly": " /* \"input.sol\":60:101 */
mstore(0x40, 0x80)
tag_2
tag_1
jump\t// in
tag_2:
/* \"input.sol\":77:99 */
jump(tag_3)
tag_1:
jump\t// out
tag_3:
"
}
}
}
},
"errors":
[
{
"component": "general",
"formattedMessage": "Yul is still experimental. Please use the output with care.",
"message": "Yul is still experimental. Please use the output with care.",
"severity": "warning",
"type": "Warning"
}
]
}

View File

@ -0,0 +1 @@
--pretty-json --json-indent 4 --allow-paths .

View File

@ -0,0 +1,15 @@
/// @use-src 0:"input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101 "contract C {..."
mstore(64, 128)
// f()
fun_f_5()
/// @src 0:77:99 "function f() public {}"
function fun_f_5() {
}
/// @src 0:60:101 "contract C {..."
}
}

View File

@ -0,0 +1,12 @@
{
"language": "Yul",
"sources": {
"C": {"urls": ["standard_yul_debug_info_print_location_only/in.yul"]}
},
"settings": {
"debug": {"debugInfo": ["location"]},
"outputSelection": {
"*": {"*": ["evm.assembly"]}
}
}
}

View File

@ -0,0 +1,36 @@
{
"contracts":
{
"C":
{
"C_6_deployed":
{
"evm":
{
"assembly": " /* \"input.sol\":60:101 */
mstore(0x40, 0x80)
tag_2
tag_1
jump\t// in
tag_2:
/* \"input.sol\":77:99 */
jump(tag_3)
tag_1:
jump\t// out
tag_3:
"
}
}
}
},
"errors":
[
{
"component": "general",
"formattedMessage": "Yul is still experimental. Please use the output with care.",
"message": "Yul is still experimental. Please use the output with care.",
"severity": "warning",
"type": "Warning"
}
]
}

View File

@ -0,0 +1 @@
--pretty-json --json-indent 4 --allow-paths .

View File

@ -0,0 +1,15 @@
/// @use-src 0:"input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101 "contract C {..."
mstore(64, 128)
// f()
fun_f_5()
/// @src 0:77:99 "function f() public {}"
function fun_f_5() {
}
/// @src 0:60:101 "contract C {..."
}
}

View File

@ -0,0 +1,12 @@
{
"language": "Yul",
"sources": {
"C": {"urls": ["standard_yul_debug_info_print_none/in.yul"]}
},
"settings": {
"debug": {"debugInfo": []},
"outputSelection": {
"*": {"*": ["evm.assembly"]}
}
}
}

View File

@ -0,0 +1,34 @@
{
"contracts":
{
"C":
{
"C_6_deployed":
{
"evm":
{
"assembly": " mstore(0x40, 0x80)
tag_2
tag_1
jump\t// in
tag_2:
jump(tag_3)
tag_1:
jump\t// out
tag_3:
"
}
}
}
},
"errors":
[
{
"component": "general",
"formattedMessage": "Yul is still experimental. Please use the output with care.",
"message": "Yul is still experimental. Please use the output with care.",
"severity": "warning",
"type": "Warning"
}
]
}

View File

@ -0,0 +1 @@
--pretty-json --json-indent 4 --allow-paths .

View File

@ -0,0 +1,15 @@
/// @use-src 0:"input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101 "contract C {..."
mstore(64, 128)
// f()
fun_f_5()
/// @src 0:77:99 "function f() public {}"
function fun_f_5() {
}
/// @src 0:60:101 "contract C {..."
}
}

View File

@ -0,0 +1,12 @@
{
"language": "Yul",
"sources": {
"C": {"urls": ["standard_yul_debug_info_print_snippet_only/in.yul"]}
},
"settings": {
"debug": {"debugInfo": ["snippet"]},
"outputSelection": {
"*": {"*": ["evm.assembly"]}
}
}
}

View File

@ -0,0 +1,12 @@
{
"errors":
[
{
"component": "general",
"formattedMessage": "To use 'snippet' with settings.debug.debugInfo you must select also 'location'.",
"message": "To use 'snippet' with settings.debug.debugInfo you must select also 'location'.",
"severity": "error",
"type": "JSONError"
}
]
}

View File

@ -0,0 +1 @@
--strict-assembly --debug-info all

View File

@ -0,0 +1 @@
Warning: Yul is still experimental. Please use the output with care.

View File

@ -0,0 +1,15 @@
/// @use-src 0:"input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101 "contract C {..."
mstore(64, 128)
// f()
fun_f_5()
/// @src 0:77:99 "function f() public {}"
function fun_f_5() {
}
/// @src 0:60:101 "contract C {..."
}
}

View File

@ -0,0 +1,32 @@
======= strict_asm_debug_info_print_all/input.yul (EVM) =======
Pretty printed source:
/// @use-src 0:"input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101
mstore(64, 128)
fun_f_5()
/// @src 0:77:99
function fun_f_5()
{ }
}
}
Binary representation:
6080604052600a600e565b6010565b565b
Text representation:
/* "input.sol":60:101 */
mstore(0x40, 0x80)
tag_2
tag_1
jump // in
tag_2:
/* "input.sol":77:99 */
jump(tag_3)
tag_1:
jump // out
tag_3:

View File

@ -0,0 +1 @@
--strict-assembly --debug-info location

View File

@ -0,0 +1 @@
Warning: Yul is still experimental. Please use the output with care.

View File

@ -0,0 +1,15 @@
/// @use-src 0:"input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101 "contract C {..."
mstore(64, 128)
// f()
fun_f_5()
/// @src 0:77:99 "function f() public {}"
function fun_f_5() {
}
/// @src 0:60:101 "contract C {..."
}
}

View File

@ -0,0 +1,32 @@
======= strict_asm_debug_info_print_location_only/input.yul (EVM) =======
Pretty printed source:
/// @use-src 0:"input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101
mstore(64, 128)
fun_f_5()
/// @src 0:77:99
function fun_f_5()
{ }
}
}
Binary representation:
6080604052600a600e565b6010565b565b
Text representation:
/* "input.sol":60:101 */
mstore(0x40, 0x80)
tag_2
tag_1
jump // in
tag_2:
/* "input.sol":77:99 */
jump(tag_3)
tag_1:
jump // out
tag_3:

View File

@ -0,0 +1 @@
--strict-assembly --debug-info none

View File

@ -0,0 +1 @@
Warning: Yul is still experimental. Please use the output with care.

View File

@ -0,0 +1,15 @@
/// @use-src 0:"input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101 "contract C {..."
mstore(64, 128)
// f()
fun_f_5()
/// @src 0:77:99 "function f() public {}"
function fun_f_5() {
}
/// @src 0:60:101 "contract C {..."
}
}

View File

@ -0,0 +1,28 @@
======= strict_asm_debug_info_print_none/input.yul (EVM) =======
Pretty printed source:
/// @use-src 0:"input.sol"
object "C_6_deployed" {
code {
mstore(64, 128)
fun_f_5()
function fun_f_5()
{ }
}
}
Binary representation:
6080604052600a600e565b6010565b565b
Text representation:
mstore(0x40, 0x80)
tag_2
tag_1
jump // in
tag_2:
jump(tag_3)
tag_1:
jump // out
tag_3:

View File

@ -0,0 +1 @@
--strict-assembly --debug-info snippet

View File

@ -0,0 +1 @@
To use 'snippet' with --debug-info you must select also 'location'.

View File

@ -0,0 +1 @@
1

View File

@ -0,0 +1,15 @@
/// @use-src 0:"input.sol"
object "C_6_deployed" {
code {
/// @src 0:60:101 "contract C {..."
mstore(64, 128)
// f()
fun_f_5()
/// @src 0:77:99 "function f() public {}"
function fun_f_5() {
}
/// @src 0:60:101 "contract C {..."
}
}

View File

@ -28,8 +28,9 @@
#include <libyul/AssemblyStack.h>
#include <liblangutil/Scanner.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/Exceptions.h>
#include <liblangutil/Scanner.h>
#include <liblangutil/SourceReferenceFormatter.h>
#include <libevmasm/Assembly.h>
@ -59,7 +60,12 @@ std::optional<Error> parseAndReturnFirstError(
AssemblyStack::Machine _machine = AssemblyStack::Machine::EVM
)
{
AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), _language, solidity::frontend::OptimiserSettings::none());
AssemblyStack stack(
solidity::test::CommonOptions::get().evmVersion(),
_language,
solidity::frontend::OptimiserSettings::none(),
DebugInfoSelection::None()
);
bool success = false;
try
{
@ -125,7 +131,12 @@ Error expectError(
void parsePrintCompare(string const& _source, bool _canWarn = false)
{
AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), AssemblyStack::Language::Assembly, OptimiserSettings::none());
AssemblyStack stack(
solidity::test::CommonOptions::get().evmVersion(),
AssemblyStack::Language::Assembly,
OptimiserSettings::none(),
DebugInfoSelection::None()
);
BOOST_REQUIRE(stack.parseAndAnalyze("", _source));
if (_canWarn)
BOOST_REQUIRE(!Error::containsErrors(stack.errors()));
@ -210,7 +221,12 @@ BOOST_AUTO_TEST_CASE(print_string_literal_unicode)
{
string source = "{ let x := \"\\u1bac\" }";
string parsed = "object \"object\" {\n code { let x := \"\\xe1\\xae\\xac\" }\n}\n";
AssemblyStack stack(solidity::test::CommonOptions::get().evmVersion(), AssemblyStack::Language::Assembly, OptimiserSettings::none());
AssemblyStack stack(
solidity::test::CommonOptions::get().evmVersion(),
AssemblyStack::Language::Assembly,
OptimiserSettings::none(),
DebugInfoSelection::None()
);
BOOST_REQUIRE(stack.parseAndAnalyze("", source));
BOOST_REQUIRE(stack.errors().empty());
BOOST_CHECK_EQUAL(stack.print(), parsed);

View File

@ -21,17 +21,22 @@
* Framework for executing Solidity contracts and testing them against C++ implementation.
*/
#include <cstdlib>
#include <iostream>
#include <boost/test/framework.hpp>
#include <test/libsolidity/SolidityExecutionFramework.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/Exceptions.h>
#include <liblangutil/SourceReferenceFormatter.h>
#include <boost/test/framework.hpp>
#include <cstdlib>
#include <iostream>
using namespace solidity;
using namespace solidity::test;
using namespace solidity::frontend;
using namespace solidity::frontend::test;
using namespace solidity::langutil;
using namespace solidity::test;
using namespace std;
bytes SolidityExecutionFramework::multiSourceCompileContract(
@ -91,8 +96,12 @@ bytes SolidityExecutionFramework::multiSourceCompileContract(
else if (forceEnableOptimizer)
optimiserSettings = OptimiserSettings::full();
yul::AssemblyStack
asmStack(m_evmVersion, yul::AssemblyStack::Language::StrictAssembly, optimiserSettings);
yul::AssemblyStack asmStack(
m_evmVersion,
yul::AssemblyStack::Language::StrictAssembly,
optimiserSettings,
DebugInfoSelection::All()
);
bool analysisSuccessful = asmStack.parseAndAnalyze("", m_compiler.yulIROptimized(contractName));
solAssert(analysisSuccessful, "Code that passed analysis in CompilerStack can't have errors");

View File

@ -23,8 +23,6 @@
#include <test/Common.h>
#include <liblangutil/SourceReferenceFormatter.h>
#include <libyul/optimiser/Disambiguator.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/AsmPrinter.h>
@ -33,8 +31,10 @@
#include <libyul/backends/evm/EVMDialect.h>
#include <libyul/backends/wasm/WasmDialect.h>
#include <liblangutil/Scanner.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/ErrorReporter.h>
#include <liblangutil/Scanner.h>
#include <liblangutil/SourceReferenceFormatter.h>
#include <boost/test/unit_test.hpp>
@ -60,7 +60,8 @@ pair<shared_ptr<Block>, shared_ptr<yul::AsmAnalysisInfo>> yul::test::parse(strin
_yul ? AssemblyStack::Language::Yul : AssemblyStack::Language::StrictAssembly,
solidity::test::CommonOptions::get().optimize ?
solidity::frontend::OptimiserSettings::standard() :
solidity::frontend::OptimiserSettings::minimal()
solidity::frontend::OptimiserSettings::minimal(),
DebugInfoSelection::All()
);
if (!stack.parseAndAnalyze("", _source) || !stack.errors().empty())
BOOST_FAIL("Invalid source.");

View File

@ -47,7 +47,12 @@ TestCase::TestResult EVMCodeTransformTest::run(ostream& _stream, string const& _
solidity::frontend::OptimiserSettings settings = solidity::frontend::OptimiserSettings::none();
settings.runYulOptimiser = false;
settings.optimizeStackAllocation = m_stackOpt;
AssemblyStack stack(EVMVersion{}, AssemblyStack::Language::StrictAssembly, settings);
AssemblyStack stack(
EVMVersion{},
AssemblyStack::Language::StrictAssembly,
settings,
DebugInfoSelection::All()
);
if (!stack.parseAndAnalyze("", m_source))
{
AnsiColorized(_stream, _formatted, {formatting::BOLD, formatting::RED}) << _linePrefix << "Error parsing source." << endl;

View File

@ -30,6 +30,7 @@
#include <libyul/AST.h>
#include <libyul/Object.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/ErrorReporter.h>
#include <liblangutil/SourceReferenceFormatter.h>
@ -82,7 +83,8 @@ bool EwasmTranslationTest::parse(ostream& _stream, string const& _linePrefix, bo
m_stack = AssemblyStack(
solidity::test::CommonOptions::get().evmVersion(),
AssemblyStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::none()
solidity::frontend::OptimiserSettings::none(),
DebugInfoSelection::All()
);
if (m_stack.parseAndAnalyze("", m_source))
{

View File

@ -27,7 +27,6 @@
#include <libyul/optimiser/FullInliner.h>
#include <libyul/optimiser/FunctionHoister.h>
#include <libyul/optimiser/FunctionGrouper.h>
#include <libyul/AsmPrinter.h>
#include <libyul/AST.h>
#include <boost/test/unit_test.hpp>

View File

@ -26,6 +26,7 @@
#include <libevmasm/Instruction.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/SourceReferenceFormatter.h>
#include <boost/algorithm/string.hpp>
@ -64,7 +65,8 @@ TestCase::TestResult ObjectCompilerTest::run(ostream& _stream, string const& _li
AssemblyStack stack(
EVMVersion(),
m_wasm ? AssemblyStack::Language::Ewasm : AssemblyStack::Language::StrictAssembly,
OptimiserSettings::preset(m_optimisationPreset)
OptimiserSettings::preset(m_optimisationPreset),
DebugInfoSelection::All()
);
if (!stack.parseAndAnalyze("source", m_source))
{

View File

@ -23,6 +23,7 @@
#include <test/libsolidity/ErrorCheck.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/Scanner.h>
#include <libyul/AssemblyStack.h>
@ -60,7 +61,8 @@ pair<bool, ErrorList> parse(string const& _source)
AssemblyStack asmStack(
solidity::test::CommonOptions::get().evmVersion(),
AssemblyStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::none()
solidity::frontend::OptimiserSettings::none(),
DebugInfoSelection::All()
);
bool success = asmStack.parseAndAnalyze("source", _source);
return {success, asmStack.errors()};
@ -181,7 +183,8 @@ BOOST_AUTO_TEST_CASE(to_string)
AssemblyStack asmStack(
solidity::test::CommonOptions::get().evmVersion(),
AssemblyStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::none()
solidity::frontend::OptimiserSettings::none(),
DebugInfoSelection::All()
);
BOOST_REQUIRE(asmStack.parseAndAnalyze("source", code));
BOOST_CHECK_EQUAL(asmStack.print(), expectation);

View File

@ -26,6 +26,7 @@
#include <libyul/AssemblyStack.h>
#include <libyul/AsmAnalysisInfo.h>
#include <liblangutil/DebugInfoSelection.h>
#include <liblangutil/ErrorReporter.h>
#include <liblangutil/SourceReferenceFormatter.h>
@ -67,7 +68,8 @@ bool YulInterpreterTest::parse(ostream& _stream, string const& _linePrefix, bool
AssemblyStack stack(
solidity::test::CommonOptions::get().evmVersion(),
AssemblyStack::Language::StrictAssembly,
solidity::frontend::OptimiserSettings::none()
solidity::frontend::OptimiserSettings::none(),
DebugInfoSelection::All()
);
if (stack.parseAndAnalyze("", m_source))
{

View File

@ -61,7 +61,6 @@
#include <libyul/backends/evm/EVMMetrics.h>
#include <libyul/backends/wasm/WordSizeTransform.h>
#include <libyul/backends/wasm/WasmDialect.h>
#include <libyul/AsmPrinter.h>
#include <libyul/AsmAnalysis.h>
#include <libyul/CompilabilityChecker.h>

Some files were not shown because too many files have changed in this diff Show More