mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Handle DebugInfoSelection in the code printing Yul and EVM assembly
This commit is contained in:
parent
25eedfafe2
commit
f7c4ed849d
@ -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 (_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);
|
||||
m_out << " " << locationFromSources(m_sourceCodes, m_location);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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>
|
||||
@ -174,6 +175,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 +222,7 @@ private:
|
||||
|
||||
std::set<ContractDefinition const*, ASTNode::CompareByID> m_subObjects;
|
||||
|
||||
langutil::DebugInfoSelection m_debugInfoSelection = langutil::DebugInfoSelection::Default();
|
||||
langutil::CharStreamProvider const* m_soliditySourceProvider = nullptr;
|
||||
};
|
||||
|
||||
|
@ -340,8 +340,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 +348,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 +411,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 +419,7 @@ string IRGenerator::generateModifier(
|
||||
}
|
||||
<contractSourceLocationComment>
|
||||
)");
|
||||
|
||||
t("functionName", functionName);
|
||||
vector<string> retParamsIn;
|
||||
for (auto const& varDecl: _function.returnParameters())
|
||||
@ -440,7 +442,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 +552,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 +577,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 +705,7 @@ string IRGenerator::generateGetter(VariableDeclaration const& _varDecl)
|
||||
}
|
||||
|
||||
return Whiskers(R"(
|
||||
/// @ast-id <astID>
|
||||
<sourceLocationComment>
|
||||
<astIDComment><sourceLocationComment>
|
||||
function <functionName>(<params>) -> <retVariables> {
|
||||
<code>
|
||||
}
|
||||
@ -702,7 +715,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 +847,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", "");
|
||||
|
@ -882,7 +882,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(DebugInfoSelection::Default(), _sourceCodes);
|
||||
else
|
||||
return string();
|
||||
}
|
||||
|
@ -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,11 +304,14 @@ string AsmPrinter::formatSourceLocation(
|
||||
|
||||
string AsmPrinter::formatDebugData(shared_ptr<DebugData const> const& _debugData, bool _statement)
|
||||
{
|
||||
if (!_debugData)
|
||||
DebugInfoSelection debugInfoSelection = DebugInfoSelection::Default();
|
||||
|
||||
if (!_debugData || debugInfoSelection.none())
|
||||
return "";
|
||||
|
||||
vector<string> items;
|
||||
if (auto id = _debugData->astID)
|
||||
if (debugInfoSelection.astID)
|
||||
items.emplace_back("@ast-id " + to_string(*id));
|
||||
|
||||
if (
|
||||
@ -315,6 +324,7 @@ string AsmPrinter::formatDebugData(shared_ptr<DebugData const> const& _debugData
|
||||
items.emplace_back(formatSourceLocation(
|
||||
_debugData->originLocation,
|
||||
m_nameToSourceIndex,
|
||||
debugInfoSelection,
|
||||
m_soliditySourceProvider
|
||||
));
|
||||
}
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include <libsolutil/CommonData.h>
|
||||
|
||||
#include <liblangutil/CharStreamProvider.h>
|
||||
#include <liblangutil/DebugInfoSelection.h>
|
||||
#include <liblangutil/SourceLocation.h>
|
||||
|
||||
#include <map>
|
||||
@ -83,6 +84,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
|
||||
);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user