Merge pull request #11998 from ethereum/separate-yul-and-sol-locations-in-debug-info

Store both Yul and Solidity locations in debug data
This commit is contained in:
chriseth 2021-09-22 15:27:42 +02:00 committed by GitHub
commit bcdaa0c729
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 339 additions and 248 deletions

View File

@ -409,7 +409,8 @@ bool ControlFlowBuilder::visit(InlineAssembly const& _inlineAssembly)
void ControlFlowBuilder::visit(yul::Statement const& _statement) void ControlFlowBuilder::visit(yul::Statement const& _statement)
{ {
solAssert(m_currentNode && m_inlineAssembly, ""); solAssert(m_currentNode && m_inlineAssembly, "");
m_currentNode->location = langutil::SourceLocation::smallestCovering(m_currentNode->location, locationOf(_statement)); solAssert(nativeLocationOf(_statement) == originLocationOf(_statement), "");
m_currentNode->location = langutil::SourceLocation::smallestCovering(m_currentNode->location, nativeLocationOf(_statement));
ASTWalker::visit(_statement); ASTWalker::visit(_statement);
} }
@ -496,14 +497,15 @@ void ControlFlowBuilder::operator()(yul::Identifier const& _identifier)
solAssert(m_currentNode && m_inlineAssembly, ""); solAssert(m_currentNode && m_inlineAssembly, "");
auto const& externalReferences = m_inlineAssembly->annotation().externalReferences; auto const& externalReferences = m_inlineAssembly->annotation().externalReferences;
if (externalReferences.count(&_identifier)) if (externalReferences.count(&_identifier))
{
if (auto const* declaration = dynamic_cast<VariableDeclaration const*>(externalReferences.at(&_identifier).declaration)) if (auto const* declaration = dynamic_cast<VariableDeclaration const*>(externalReferences.at(&_identifier).declaration))
{
solAssert(nativeLocationOf(_identifier) == originLocationOf(_identifier), "");
m_currentNode->variableOccurrences.emplace_back( m_currentNode->variableOccurrences.emplace_back(
*declaration, *declaration,
VariableOccurrence::Kind::Access, VariableOccurrence::Kind::Access,
_identifier.debugData->location nativeLocationOf(_identifier)
); );
} }
} }
void ControlFlowBuilder::operator()(yul::Assignment const& _assignment) void ControlFlowBuilder::operator()(yul::Assignment const& _assignment)
@ -514,11 +516,14 @@ void ControlFlowBuilder::operator()(yul::Assignment const& _assignment)
for (auto const& variable: _assignment.variableNames) for (auto const& variable: _assignment.variableNames)
if (externalReferences.count(&variable)) if (externalReferences.count(&variable))
if (auto const* declaration = dynamic_cast<VariableDeclaration const*>(externalReferences.at(&variable).declaration)) if (auto const* declaration = dynamic_cast<VariableDeclaration const*>(externalReferences.at(&variable).declaration))
{
solAssert(nativeLocationOf(variable) == originLocationOf(variable), "");
m_currentNode->variableOccurrences.emplace_back( m_currentNode->variableOccurrences.emplace_back(
*declaration, *declaration,
VariableOccurrence::Kind::Assignment, VariableOccurrence::Kind::Assignment,
variable.debugData->location nativeLocationOf(variable)
); );
}
} }
void ControlFlowBuilder::operator()(yul::FunctionCall const& _functionCall) void ControlFlowBuilder::operator()(yul::FunctionCall const& _functionCall)

View File

@ -201,9 +201,13 @@ bool ReferencesResolver::visit(Return const& _return)
void ReferencesResolver::operator()(yul::FunctionDefinition const& _function) void ReferencesResolver::operator()(yul::FunctionDefinition const& _function)
{ {
validateYulIdentifierName(_function.name, _function.debugData->location); solAssert(nativeLocationOf(_function) == originLocationOf(_function), "");
validateYulIdentifierName(_function.name, nativeLocationOf(_function));
for (yul::TypedName const& varName: _function.parameters + _function.returnVariables) for (yul::TypedName const& varName: _function.parameters + _function.returnVariables)
validateYulIdentifierName(varName.name, varName.debugData->location); {
solAssert(nativeLocationOf(varName) == originLocationOf(varName), "");
validateYulIdentifierName(varName.name, nativeLocationOf(varName));
}
bool wasInsideFunction = m_yulInsideFunction; bool wasInsideFunction = m_yulInsideFunction;
m_yulInsideFunction = true; m_yulInsideFunction = true;
@ -213,6 +217,8 @@ void ReferencesResolver::operator()(yul::FunctionDefinition const& _function)
void ReferencesResolver::operator()(yul::Identifier const& _identifier) void ReferencesResolver::operator()(yul::Identifier const& _identifier)
{ {
solAssert(nativeLocationOf(_identifier) == originLocationOf(_identifier), "");
static set<string> suffixes{"slot", "offset", "length"}; static set<string> suffixes{"slot", "offset", "length"};
string suffix; string suffix;
for (string const& s: suffixes) for (string const& s: suffixes)
@ -238,7 +244,7 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
{ {
m_errorReporter.declarationError( m_errorReporter.declarationError(
4718_error, 4718_error,
_identifier.debugData->location, nativeLocationOf(_identifier),
"Multiple matching identifiers. Resolving overloaded identifiers is not supported." "Multiple matching identifiers. Resolving overloaded identifiers is not supported."
); );
return; return;
@ -251,7 +257,7 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
) )
m_errorReporter.declarationError( m_errorReporter.declarationError(
9467_error, 9467_error,
_identifier.debugData->location, nativeLocationOf(_identifier),
"Identifier not found. Use \".slot\" and \".offset\" to access storage variables." "Identifier not found. Use \".slot\" and \".offset\" to access storage variables."
); );
return; return;
@ -261,7 +267,7 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
{ {
m_errorReporter.declarationError( m_errorReporter.declarationError(
6578_error, 6578_error,
_identifier.debugData->location, nativeLocationOf(_identifier),
"Cannot access local Solidity variables from inside an inline assembly function." "Cannot access local Solidity variables from inside an inline assembly function."
); );
return; return;
@ -275,8 +281,8 @@ void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)
{ {
for (auto const& identifier: _varDecl.variables) for (auto const& identifier: _varDecl.variables)
{ {
validateYulIdentifierName(identifier.name, identifier.debugData->location); solAssert(nativeLocationOf(identifier) == originLocationOf(identifier), "");
validateYulIdentifierName(identifier.name, nativeLocationOf(identifier));
if ( if (
auto declarations = m_resolver.nameFromCurrentScope(identifier.name.str()); auto declarations = m_resolver.nameFromCurrentScope(identifier.name.str());
@ -289,7 +295,7 @@ void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)
if (!ssl.infos.empty()) if (!ssl.infos.empty())
m_errorReporter.declarationError( m_errorReporter.declarationError(
3859_error, 3859_error,
identifier.debugData->location, nativeLocationOf(identifier),
ssl, ssl,
"This declaration shadows a declaration outside the inline assembly block." "This declaration shadows a declaration outside the inline assembly block."
); );

View File

@ -772,7 +772,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
solAssert(var->type(), "Expected variable type!"); solAssert(var->type(), "Expected variable type!");
if (var->immutable()) if (var->immutable())
{ {
m_errorReporter.typeError(3773_error, _identifier.debugData->location, "Assembly access to immutable variables is not supported."); m_errorReporter.typeError(3773_error, nativeLocationOf(_identifier), "Assembly access to immutable variables is not supported.");
return false; return false;
} }
if (var->isConstant()) if (var->isConstant())
@ -781,7 +781,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{ {
m_errorReporter.typeError( m_errorReporter.typeError(
3558_error, 3558_error,
_identifier.debugData->location, nativeLocationOf(_identifier),
"Constant variable is circular." "Constant variable is circular."
); );
return false; return false;
@ -791,24 +791,24 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
if (var && !var->value()) if (var && !var->value())
{ {
m_errorReporter.typeError(3224_error, _identifier.debugData->location, "Constant has no value."); m_errorReporter.typeError(3224_error, nativeLocationOf(_identifier), "Constant has no value.");
return false; return false;
} }
else if (_context == yul::IdentifierContext::LValue) else if (_context == yul::IdentifierContext::LValue)
{ {
m_errorReporter.typeError(6252_error, _identifier.debugData->location, "Constant variables cannot be assigned to."); m_errorReporter.typeError(6252_error, nativeLocationOf(_identifier), "Constant variables cannot be assigned to.");
return false; return false;
} }
else if (identifierInfo.suffix == "slot" || identifierInfo.suffix == "offset") else if (identifierInfo.suffix == "slot" || identifierInfo.suffix == "offset")
{ {
m_errorReporter.typeError(6617_error, _identifier.debugData->location, "The suffixes .offset and .slot can only be used on non-constant storage variables."); m_errorReporter.typeError(6617_error, nativeLocationOf(_identifier), "The suffixes .offset and .slot can only be used on non-constant storage variables.");
return false; return false;
} }
else if (var && var->value() && !var->value()->annotation().type && !dynamic_cast<Literal const*>(var->value().get())) else if (var && var->value() && !var->value()->annotation().type && !dynamic_cast<Literal const*>(var->value().get()))
{ {
m_errorReporter.typeError( m_errorReporter.typeError(
2249_error, 2249_error,
_identifier.debugData->location, nativeLocationOf(_identifier),
"Constant variables with non-literal values cannot be forward referenced from inline assembly." "Constant variables with non-literal values cannot be forward referenced from inline assembly."
); );
return false; return false;
@ -818,7 +818,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
type(*var->value())->category() != Type::Category::RationalNumber type(*var->value())->category() != Type::Category::RationalNumber
)) ))
{ {
m_errorReporter.typeError(7615_error, _identifier.debugData->location, "Only direct number constants and references to such constants are supported by inline assembly."); m_errorReporter.typeError(7615_error, nativeLocationOf(_identifier), "Only direct number constants and references to such constants are supported by inline assembly.");
return false; return false;
} }
} }
@ -833,19 +833,19 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{ {
if (suffix != "slot" && suffix != "offset") if (suffix != "slot" && suffix != "offset")
{ {
m_errorReporter.typeError(4656_error, _identifier.debugData->location, "State variables only support \".slot\" and \".offset\"."); m_errorReporter.typeError(4656_error, nativeLocationOf(_identifier), "State variables only support \".slot\" and \".offset\".");
return false; return false;
} }
else if (_context == yul::IdentifierContext::LValue) else if (_context == yul::IdentifierContext::LValue)
{ {
if (var->isStateVariable()) if (var->isStateVariable())
{ {
m_errorReporter.typeError(4713_error, _identifier.debugData->location, "State variables cannot be assigned to - you have to use \"sstore()\"."); m_errorReporter.typeError(4713_error, nativeLocationOf(_identifier), "State variables cannot be assigned to - you have to use \"sstore()\".");
return false; return false;
} }
else if (suffix != "slot") else if (suffix != "slot")
{ {
m_errorReporter.typeError(9739_error, _identifier.debugData->location, "Only .slot can be assigned to."); m_errorReporter.typeError(9739_error, nativeLocationOf(_identifier), "Only .slot can be assigned to.");
return false; return false;
} }
} }
@ -857,13 +857,13 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{ {
if (suffix != "offset" && suffix != "length") if (suffix != "offset" && suffix != "length")
{ {
m_errorReporter.typeError(1536_error, _identifier.debugData->location, "Calldata variables only support \".offset\" and \".length\"."); m_errorReporter.typeError(1536_error, nativeLocationOf(_identifier), "Calldata variables only support \".offset\" and \".length\".");
return false; return false;
} }
} }
else else
{ {
m_errorReporter.typeError(3622_error, _identifier.debugData->location, "The suffix \"." + suffix + "\" is not supported by this variable or type."); m_errorReporter.typeError(3622_error, nativeLocationOf(_identifier), "The suffix \"." + suffix + "\" is not supported by this variable or type.");
return false; return false;
} }
} }
@ -871,14 +871,14 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{ {
m_errorReporter.typeError( m_errorReporter.typeError(
1408_error, 1408_error,
_identifier.debugData->location, nativeLocationOf(_identifier),
"Only local variables are supported. To access storage variables, use the \".slot\" and \".offset\" suffixes." "Only local variables are supported. To access storage variables, use the \".slot\" and \".offset\" suffixes."
); );
return false; return false;
} }
else if (var->type()->dataStoredIn(DataLocation::Storage)) else if (var->type()->dataStoredIn(DataLocation::Storage))
{ {
m_errorReporter.typeError(9068_error, _identifier.debugData->location, "You have to use the \".slot\" or \".offset\" suffix to access storage reference variables."); m_errorReporter.typeError(9068_error, nativeLocationOf(_identifier), "You have to use the \".slot\" or \".offset\" suffix to access storage reference variables.");
return false; return false;
} }
else if (var->type()->sizeOnStack() != 1) else if (var->type()->sizeOnStack() != 1)
@ -887,18 +887,18 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
auto const* arrayType = dynamic_cast<ArrayType const*>(var->type()); auto const* arrayType = dynamic_cast<ArrayType const*>(var->type());
arrayType && arrayType->isDynamicallySized() && arrayType->dataStoredIn(DataLocation::CallData) arrayType && arrayType->isDynamicallySized() && arrayType->dataStoredIn(DataLocation::CallData)
) )
m_errorReporter.typeError(1397_error, _identifier.debugData->location, "Call data elements cannot be accessed directly. Use \".offset\" and \".length\" to access the calldata offset and length of this array and then use \"calldatacopy\"."); m_errorReporter.typeError(1397_error, nativeLocationOf(_identifier), "Call data elements cannot be accessed directly. Use \".offset\" and \".length\" to access the calldata offset and length of this array and then use \"calldatacopy\".");
else else
{ {
solAssert(!var->type()->dataStoredIn(DataLocation::CallData), ""); solAssert(!var->type()->dataStoredIn(DataLocation::CallData), "");
m_errorReporter.typeError(9857_error, _identifier.debugData->location, "Only types that use one stack slot are supported."); m_errorReporter.typeError(9857_error, nativeLocationOf(_identifier), "Only types that use one stack slot are supported.");
} }
return false; return false;
} }
} }
else if (!identifierInfo.suffix.empty()) else if (!identifierInfo.suffix.empty())
{ {
m_errorReporter.typeError(7944_error, _identifier.debugData->location, "The suffixes \".offset\", \".slot\" and \".length\" can only be used with variables."); m_errorReporter.typeError(7944_error, nativeLocationOf(_identifier), "The suffixes \".offset\", \".slot\" and \".length\" can only be used with variables.");
return false; return false;
} }
else if (_context == yul::IdentifierContext::LValue) else if (_context == yul::IdentifierContext::LValue)
@ -906,7 +906,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
if (dynamic_cast<MagicVariableDeclaration const*>(declaration)) if (dynamic_cast<MagicVariableDeclaration const*>(declaration))
return false; return false;
m_errorReporter.typeError(1990_error, _identifier.debugData->location, "Only local variables can be assigned to in inline assembly."); m_errorReporter.typeError(1990_error, nativeLocationOf(_identifier), "Only local variables can be assigned to in inline assembly.");
return false; return false;
} }
@ -915,7 +915,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
solAssert(!!declaration->type(), "Type of declaration required but not yet determined."); solAssert(!!declaration->type(), "Type of declaration required but not yet determined.");
if (dynamic_cast<FunctionDefinition const*>(declaration)) if (dynamic_cast<FunctionDefinition const*>(declaration))
{ {
m_errorReporter.declarationError(2025_error, _identifier.debugData->location, "Access to functions is not allowed in inline assembly."); m_errorReporter.declarationError(2025_error, nativeLocationOf(_identifier), "Access to functions is not allowed in inline assembly.");
return false; return false;
} }
else if (dynamic_cast<VariableDeclaration const*>(declaration)) else if (dynamic_cast<VariableDeclaration const*>(declaration))
@ -925,7 +925,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{ {
if (!contract->isLibrary()) if (!contract->isLibrary())
{ {
m_errorReporter.typeError(4977_error, _identifier.debugData->location, "Expected a library."); m_errorReporter.typeError(4977_error, nativeLocationOf(_identifier), "Expected a library.");
return false; return false;
} }
} }

View File

@ -69,7 +69,7 @@ public:
if (yul::EVMDialect const* dialect = dynamic_cast<decltype(dialect)>(&m_dialect)) if (yul::EVMDialect const* dialect = dynamic_cast<decltype(dialect)>(&m_dialect))
if (yul::BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name)) if (yul::BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name))
if (fun->instruction) if (fun->instruction)
checkInstruction(_funCall.debugData->location, *fun->instruction); checkInstruction(nativeLocationOf(_funCall), *fun->instruction);
for (auto const& arg: _funCall.arguments) for (auto const& arg: _funCall.arguments)
std::visit(*this, arg); std::visit(*this, arg);

View File

@ -171,10 +171,10 @@ void ASTJsonConverter::appendExpressionAttributes(
_attributes += exprAttributes; _attributes += exprAttributes;
} }
Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair<yul::Identifier const* ,InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const Json::Value ASTJsonConverter::inlineAssemblyIdentifierToJson(pair<yul::Identifier const*, InlineAssemblyAnnotation::ExternalIdentifierInfo> _info) const
{ {
Json::Value tuple(Json::objectValue); Json::Value tuple(Json::objectValue);
tuple["src"] = sourceLocationToString(_info.first->debugData->location); tuple["src"] = sourceLocationToString(nativeLocationOf(*_info.first));
tuple["declaration"] = idOrNull(_info.second.declaration); tuple["declaration"] = idOrNull(_info.second.declaration);
tuple["isSlot"] = Json::Value(_info.second.suffix == "slot"); tuple["isSlot"] = Json::Value(_info.second.suffix == "slot");
tuple["isOffset"] = Json::Value(_info.second.suffix == "offset"); tuple["isOffset"] = Json::Value(_info.second.suffix == "offset");

View File

@ -421,7 +421,7 @@ void CompilerContext::appendInlineAssembly(
if (stackDiff < 1 || stackDiff > 16) if (stackDiff < 1 || stackDiff > 16)
BOOST_THROW_EXCEPTION( BOOST_THROW_EXCEPTION(
StackTooDeepError() << StackTooDeepError() <<
errinfo_sourceLocation(_identifier.debugData->location) << errinfo_sourceLocation(nativeLocationOf(_identifier)) <<
util::errinfo_comment("Stack too deep (" + to_string(stackDiff) + "), try removing local variables.") util::errinfo_comment("Stack too deep (" + to_string(stackDiff) + "), try removing local variables.")
); );
if (_context == yul::IdentifierContext::RValue) if (_context == yul::IdentifierContext::RValue)

View File

@ -1326,7 +1326,7 @@ ASTPointer<InlineAssembly> Parser::parseInlineAssembly(ASTPointer<ASTString> con
if (block == nullptr) if (block == nullptr)
BOOST_THROW_EXCEPTION(FatalError()); BOOST_THROW_EXCEPTION(FatalError());
location.end = block->debugData->location.end; location.end = nativeLocationOf(*block).end;
return make_shared<InlineAssembly>(nextID(), location, _docString, dialect, block); return make_shared<InlineAssembly>(nextID(), location, _docString, dialect, block);
} }

View File

@ -38,20 +38,34 @@ using Type = YulString;
struct DebugData struct DebugData
{ {
explicit DebugData(langutil::SourceLocation _location, std::optional<int64_t> _astID = {}): explicit DebugData(
location(std::move(_location)), langutil::SourceLocation _nativeLocation,
langutil::SourceLocation _originLocation = {},
std::optional<int64_t> _astID = {}
):
nativeLocation(std::move(_nativeLocation)),
originLocation(std::move(_originLocation)),
astID(std::move(_astID)) astID(std::move(_astID))
{} {}
static std::shared_ptr<DebugData const> create( static std::shared_ptr<DebugData const> create(
langutil::SourceLocation _location = {}, langutil::SourceLocation _nativeLocation = {},
langutil::SourceLocation _originLocation = {},
std::optional<int64_t> _astID = {} std::optional<int64_t> _astID = {}
) )
{ {
return std::make_shared<DebugData const>(std::move(_location), std::move(_astID)); return std::make_shared<DebugData const>(
std::move(_nativeLocation),
std::move(_originLocation),
std::move(_astID)
);
} }
langutil::SourceLocation location; /// Location in the Yul code.
langutil::SourceLocation nativeLocation;
/// Location in the original source that the Yul code was produced from.
/// Optional. Only present if the Yul source contains location annotations.
langutil::SourceLocation originLocation;
/// ID in the (Solidity) source AST. /// ID in the (Solidity) source AST.
std::optional<int64_t> astID; std::optional<int64_t> astID;
}; };
@ -94,16 +108,28 @@ struct Continue { std::shared_ptr<DebugData const> debugData; };
/// Leave statement (valid within function) /// Leave statement (valid within function)
struct Leave { std::shared_ptr<DebugData const> debugData; }; struct Leave { std::shared_ptr<DebugData const> debugData; };
/// Extracts the source location from a Yul node. /// Extracts the IR source location from a Yul node.
template <class T> inline langutil::SourceLocation locationOf(T const& _node) template <class T> inline langutil::SourceLocation nativeLocationOf(T const& _node)
{ {
return _node.debugData ? _node.debugData->location : langutil::SourceLocation{}; return _node.debugData ? _node.debugData->nativeLocation : langutil::SourceLocation{};
} }
/// Extracts the source location from a Yul node. /// Extracts the IR source location from a Yul node.
template <class... Args> inline langutil::SourceLocation locationOf(std::variant<Args...> const& _node) template <class... Args> inline langutil::SourceLocation nativeLocationOf(std::variant<Args...> const& _node)
{ {
return std::visit([](auto const& _arg) { return locationOf(_arg); }, _node); return std::visit([](auto const& _arg) { return nativeLocationOf(_arg); }, _node);
}
/// Extracts the original source location from a Yul node.
template <class T> inline langutil::SourceLocation originLocationOf(T const& _node)
{
return _node.debugData ? _node.debugData->originLocation : langutil::SourceLocation{};
}
/// Extracts the original source location from a Yul node.
template <class... Args> inline langutil::SourceLocation originLocationOf(std::variant<Args...> const& _node)
{
return std::visit([](auto const& _arg) { return originLocationOf(_arg); }, _node);
} }
/// Extracts the debug data from a Yul node. /// Extracts the debug data from a Yul node.

View File

@ -96,22 +96,22 @@ AsmAnalysisInfo AsmAnalyzer::analyzeStrictAssertCorrect(Dialect const& _dialect,
vector<YulString> AsmAnalyzer::operator()(Literal const& _literal) vector<YulString> AsmAnalyzer::operator()(Literal const& _literal)
{ {
expectValidType(_literal.type, locationOf(_literal)); expectValidType(_literal.type, nativeLocationOf(_literal));
if (_literal.kind == LiteralKind::String && _literal.value.str().size() > 32) if (_literal.kind == LiteralKind::String && _literal.value.str().size() > 32)
m_errorReporter.typeError( m_errorReporter.typeError(
3069_error, 3069_error,
locationOf(_literal), nativeLocationOf(_literal),
"String literal too long (" + to_string(_literal.value.str().size()) + " > 32)" "String literal too long (" + to_string(_literal.value.str().size()) + " > 32)"
); );
else if (_literal.kind == LiteralKind::Number && bigint(_literal.value.str()) > u256(-1)) else if (_literal.kind == LiteralKind::Number && bigint(_literal.value.str()) > u256(-1))
m_errorReporter.typeError(6708_error, locationOf(_literal), "Number literal too large (> 256 bits)"); m_errorReporter.typeError(6708_error, nativeLocationOf(_literal), "Number literal too large (> 256 bits)");
else if (_literal.kind == LiteralKind::Boolean) else if (_literal.kind == LiteralKind::Boolean)
yulAssert(_literal.value == "true"_yulstring || _literal.value == "false"_yulstring, ""); yulAssert(_literal.value == "true"_yulstring || _literal.value == "false"_yulstring, "");
if (!m_dialect.validTypeForLiteral(_literal.kind, _literal.value, _literal.type)) if (!m_dialect.validTypeForLiteral(_literal.kind, _literal.value, _literal.type))
m_errorReporter.typeError( m_errorReporter.typeError(
5170_error, 5170_error,
locationOf(_literal), nativeLocationOf(_literal),
"Invalid type \"" + _literal.type.str() + "\" for literal \"" + _literal.value.str() + "\"." "Invalid type \"" + _literal.type.str() + "\" for literal \"" + _literal.value.str() + "\"."
); );
@ -131,7 +131,7 @@ vector<YulString> AsmAnalyzer::operator()(Identifier const& _identifier)
if (!m_activeVariables.count(&_var)) if (!m_activeVariables.count(&_var))
m_errorReporter.declarationError( m_errorReporter.declarationError(
4990_error, 4990_error,
locationOf(_identifier), nativeLocationOf(_identifier),
"Variable " + _identifier.name.str() + " used before it was declared." "Variable " + _identifier.name.str() + " used before it was declared."
); );
type = _var.type; type = _var.type;
@ -140,7 +140,7 @@ vector<YulString> AsmAnalyzer::operator()(Identifier const& _identifier)
{ {
m_errorReporter.typeError( m_errorReporter.typeError(
6041_error, 6041_error,
locationOf(_identifier), nativeLocationOf(_identifier),
"Function " + _identifier.name.str() + " used without being called." "Function " + _identifier.name.str() + " used without being called."
); );
} }
@ -165,7 +165,7 @@ vector<YulString> AsmAnalyzer::operator()(Identifier const& _identifier)
// Only add an error message if the callback did not do it. // Only add an error message if the callback did not do it.
m_errorReporter.declarationError( m_errorReporter.declarationError(
8198_error, 8198_error,
locationOf(_identifier), nativeLocationOf(_identifier),
"Identifier \"" + _identifier.name.str() + "\" not found." "Identifier \"" + _identifier.name.str() + "\" not found."
); );
@ -181,7 +181,7 @@ void AsmAnalyzer::operator()(ExpressionStatement const& _statement)
if (watcher.ok() && !types.empty()) if (watcher.ok() && !types.empty())
m_errorReporter.typeError( m_errorReporter.typeError(
3083_error, 3083_error,
locationOf(_statement), nativeLocationOf(_statement),
"Top-level expressions are not supposed to return values (this expression returns " + "Top-level expressions are not supposed to return values (this expression returns " +
to_string(types.size()) + to_string(types.size()) +
" value" + " value" +
@ -201,7 +201,7 @@ void AsmAnalyzer::operator()(Assignment const& _assignment)
if (!variables.insert(_variableName.name).second) if (!variables.insert(_variableName.name).second)
m_errorReporter.declarationError( m_errorReporter.declarationError(
9005_error, 9005_error,
locationOf(_assignment), nativeLocationOf(_assignment),
"Variable " + "Variable " +
_variableName.name.str() + _variableName.name.str() +
" occurs multiple times on the left-hand side of the assignment." " occurs multiple times on the left-hand side of the assignment."
@ -212,7 +212,7 @@ void AsmAnalyzer::operator()(Assignment const& _assignment)
if (types.size() != numVariables) if (types.size() != numVariables)
m_errorReporter.declarationError( m_errorReporter.declarationError(
8678_error, 8678_error,
locationOf(_assignment), nativeLocationOf(_assignment),
"Variable count for assignment to \"" + "Variable count for assignment to \"" +
joinHumanReadable(applyMap(_assignment.variableNames, [](auto const& _identifier){ return _identifier.name.str(); })) + joinHumanReadable(applyMap(_assignment.variableNames, [](auto const& _identifier){ return _identifier.name.str(); })) +
"\" does not match number of values (" + "\" does not match number of values (" +
@ -240,8 +240,8 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
); );
for (auto const& variable: _varDecl.variables) for (auto const& variable: _varDecl.variables)
{ {
expectValidIdentifier(variable.name, locationOf(variable)); expectValidIdentifier(variable.name, nativeLocationOf(variable));
expectValidType(variable.type, locationOf(variable)); expectValidType(variable.type, nativeLocationOf(variable));
} }
if (_varDecl.value) if (_varDecl.value)
@ -250,7 +250,7 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
if (types.size() != numVariables) if (types.size() != numVariables)
m_errorReporter.declarationError( m_errorReporter.declarationError(
3812_error, 3812_error,
locationOf(_varDecl), nativeLocationOf(_varDecl),
"Variable count mismatch for declaration of \"" + "Variable count mismatch for declaration of \"" +
joinHumanReadable(applyMap(_varDecl.variables, [](auto const& _identifier){ return _identifier.name.str(); })) + joinHumanReadable(applyMap(_varDecl.variables, [](auto const& _identifier){ return _identifier.name.str(); })) +
+ "\": " + + "\": " +
@ -269,7 +269,7 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
if (variable.type != givenType) if (variable.type != givenType)
m_errorReporter.typeError( m_errorReporter.typeError(
3947_error, 3947_error,
locationOf(variable), nativeLocationOf(variable),
"Assigning value of type \"" + givenType.str() + "\" to variable of type \"" + variable.type.str() + "\"." "Assigning value of type \"" + givenType.str() + "\" to variable of type \"" + variable.type.str() + "\"."
); );
} }
@ -284,14 +284,14 @@ void AsmAnalyzer::operator()(VariableDeclaration const& _varDecl)
void AsmAnalyzer::operator()(FunctionDefinition const& _funDef) void AsmAnalyzer::operator()(FunctionDefinition const& _funDef)
{ {
yulAssert(!_funDef.name.empty(), ""); yulAssert(!_funDef.name.empty(), "");
expectValidIdentifier(_funDef.name, locationOf(_funDef)); expectValidIdentifier(_funDef.name, nativeLocationOf(_funDef));
Block const* virtualBlock = m_info.virtualBlocks.at(&_funDef).get(); Block const* virtualBlock = m_info.virtualBlocks.at(&_funDef).get();
yulAssert(virtualBlock, ""); yulAssert(virtualBlock, "");
Scope& varScope = scope(virtualBlock); Scope& varScope = scope(virtualBlock);
for (auto const& var: _funDef.parameters + _funDef.returnVariables) for (auto const& var: _funDef.parameters + _funDef.returnVariables)
{ {
expectValidIdentifier(var.name, locationOf(var)); expectValidIdentifier(var.name, nativeLocationOf(var));
expectValidType(var.type, locationOf(var)); expectValidType(var.type, nativeLocationOf(var));
m_activeVariables.insert(&std::get<Scope::Variable>(varScope.identifiers.at(var.name))); m_activeVariables.insert(&std::get<Scope::Variable>(varScope.identifiers.at(var.name)));
} }
@ -320,7 +320,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
{ {
m_errorReporter.typeError( m_errorReporter.typeError(
4202_error, 4202_error,
locationOf(_funCall.functionName), nativeLocationOf(_funCall.functionName),
"Attempt to call variable instead of function." "Attempt to call variable instead of function."
); );
}, },
@ -344,7 +344,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
if (!validateInstructions(_funCall)) if (!validateInstructions(_funCall))
m_errorReporter.declarationError( m_errorReporter.declarationError(
4619_error, 4619_error,
locationOf(_funCall.functionName), nativeLocationOf(_funCall.functionName),
"Function \"" + _funCall.functionName.name.str() + "\" not found." "Function \"" + _funCall.functionName.name.str() + "\" not found."
); );
yulAssert(!watcher.ok(), "Expected a reported error."); yulAssert(!watcher.ok(), "Expected a reported error.");
@ -353,7 +353,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
if (parameterTypes && _funCall.arguments.size() != parameterTypes->size()) if (parameterTypes && _funCall.arguments.size() != parameterTypes->size())
m_errorReporter.typeError( m_errorReporter.typeError(
7000_error, 7000_error,
locationOf(_funCall.functionName), nativeLocationOf(_funCall.functionName),
"Function \"" + _funCall.functionName.name.str() + "\" expects " + "Function \"" + _funCall.functionName.name.str() + "\" expects " +
to_string(parameterTypes->size()) + to_string(parameterTypes->size()) +
" arguments but got " + " arguments but got " +
@ -373,13 +373,13 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
if (!holds_alternative<Literal>(arg)) if (!holds_alternative<Literal>(arg))
m_errorReporter.typeError( m_errorReporter.typeError(
9114_error, 9114_error,
locationOf(_funCall.functionName), nativeLocationOf(_funCall.functionName),
"Function expects direct literals as arguments." "Function expects direct literals as arguments."
); );
else if (*literalArgumentKind != get<Literal>(arg).kind) else if (*literalArgumentKind != get<Literal>(arg).kind)
m_errorReporter.typeError( m_errorReporter.typeError(
5859_error, 5859_error,
locationOf(arg), nativeLocationOf(arg),
"Function expects " + to_string(*literalArgumentKind) + " literal." "Function expects " + to_string(*literalArgumentKind) + " literal."
); );
else if (*literalArgumentKind == LiteralKind::String) else if (*literalArgumentKind == LiteralKind::String)
@ -390,7 +390,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
if (!m_dataNames.count(get<Literal>(arg).value)) if (!m_dataNames.count(get<Literal>(arg).value))
m_errorReporter.typeError( m_errorReporter.typeError(
3517_error, 3517_error,
locationOf(arg), nativeLocationOf(arg),
"Unknown data object \"" + std::get<Literal>(arg).value.str() + "\"." "Unknown data object \"" + std::get<Literal>(arg).value.str() + "\"."
); );
} }
@ -399,7 +399,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
if (get<Literal>(arg).value.empty()) if (get<Literal>(arg).value.empty())
m_errorReporter.typeError( m_errorReporter.typeError(
1844_error, 1844_error,
locationOf(arg), nativeLocationOf(arg),
"The \"verbatim_*\" builtins cannot be used with empty bytecode." "The \"verbatim_*\" builtins cannot be used with empty bytecode."
); );
} }
@ -414,7 +414,7 @@ vector<YulString> AsmAnalyzer::operator()(FunctionCall const& _funCall)
if (parameterTypes && parameterTypes->size() == argTypes.size()) if (parameterTypes && parameterTypes->size() == argTypes.size())
for (size_t i = 0; i < parameterTypes->size(); ++i) for (size_t i = 0; i < parameterTypes->size(); ++i)
expectType((*parameterTypes)[i], argTypes[i], locationOf(_funCall.arguments[i])); expectType((*parameterTypes)[i], argTypes[i], nativeLocationOf(_funCall.arguments[i]));
if (watcher.ok()) if (watcher.ok())
{ {
@ -442,7 +442,7 @@ void AsmAnalyzer::operator()(Switch const& _switch)
if (_switch.cases.size() == 1 && !_switch.cases[0].value) if (_switch.cases.size() == 1 && !_switch.cases[0].value)
m_errorReporter.warning( m_errorReporter.warning(
9592_error, 9592_error,
locationOf(_switch), nativeLocationOf(_switch),
"\"switch\" statement with only a default case." "\"switch\" statement with only a default case."
); );
@ -455,7 +455,7 @@ void AsmAnalyzer::operator()(Switch const& _switch)
{ {
auto watcher = m_errorReporter.errorWatcher(); auto watcher = m_errorReporter.errorWatcher();
expectType(valueType, _case.value->type, locationOf(*_case.value)); expectType(valueType, _case.value->type, nativeLocationOf(*_case.value));
// We cannot use "expectExpression" here because *_case.value is not an // We cannot use "expectExpression" here because *_case.value is not an
// Expression and would be converted to an Expression otherwise. // Expression and would be converted to an Expression otherwise.
@ -465,7 +465,7 @@ void AsmAnalyzer::operator()(Switch const& _switch)
if (watcher.ok() && !cases.insert(valueOfLiteral(*_case.value)).second) if (watcher.ok() && !cases.insert(valueOfLiteral(*_case.value)).second)
m_errorReporter.declarationError( m_errorReporter.declarationError(
6792_error, 6792_error,
locationOf(_case), nativeLocationOf(_case),
"Duplicate case \"" + "Duplicate case \"" +
valueOfLiteral(*_case.value).str() + valueOfLiteral(*_case.value).str() +
"\" defined." "\" defined."
@ -517,7 +517,7 @@ YulString AsmAnalyzer::expectExpression(Expression const& _expr)
if (types.size() != 1) if (types.size() != 1)
m_errorReporter.typeError( m_errorReporter.typeError(
3950_error, 3950_error,
locationOf(_expr), nativeLocationOf(_expr),
"Expected expression to evaluate to one value, but got " + "Expected expression to evaluate to one value, but got " +
to_string(types.size()) + to_string(types.size()) +
" values instead." " values instead."
@ -539,7 +539,7 @@ void AsmAnalyzer::expectBoolExpression(Expression const& _expr)
if (type != m_dialect.boolType) if (type != m_dialect.boolType)
m_errorReporter.typeError( m_errorReporter.typeError(
1733_error, 1733_error,
locationOf(_expr), nativeLocationOf(_expr),
"Expected a value of boolean type \"" + "Expected a value of boolean type \"" +
m_dialect.boolType.str() + m_dialect.boolType.str() +
"\" but got \"" + "\" but got \"" +
@ -565,11 +565,11 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulString _valueT
); );
if (!holds_alternative<Scope::Variable>(*var)) if (!holds_alternative<Scope::Variable>(*var))
m_errorReporter.typeError(2657_error, locationOf(_variable), "Assignment requires variable."); m_errorReporter.typeError(2657_error, nativeLocationOf(_variable), "Assignment requires variable.");
else if (!m_activeVariables.count(&std::get<Scope::Variable>(*var))) else if (!m_activeVariables.count(&std::get<Scope::Variable>(*var)))
m_errorReporter.declarationError( m_errorReporter.declarationError(
1133_error, 1133_error,
locationOf(_variable), nativeLocationOf(_variable),
"Variable " + _variable.name.str() + " used before it was declared." "Variable " + _variable.name.str() + " used before it was declared."
); );
else else
@ -588,11 +588,11 @@ void AsmAnalyzer::checkAssignment(Identifier const& _variable, YulString _valueT
if (!found && watcher.ok()) if (!found && watcher.ok())
// Only add message if the callback did not. // Only add message if the callback did not.
m_errorReporter.declarationError(4634_error, locationOf(_variable), "Variable not found or variable not lvalue."); m_errorReporter.declarationError(4634_error, nativeLocationOf(_variable), "Variable not found or variable not lvalue.");
if (variableType && *variableType != _valueType) if (variableType && *variableType != _valueType)
m_errorReporter.typeError( m_errorReporter.typeError(
9547_error, 9547_error,
locationOf(_variable), nativeLocationOf(_variable),
"Assigning a value of type \"" + "Assigning a value of type \"" +
_valueType.str() + _valueType.str() +
"\" to a variable of type \"" + "\" to a variable of type \"" +
@ -738,5 +738,5 @@ bool AsmAnalyzer::validateInstructions(evmasm::Instruction _instr, SourceLocatio
bool AsmAnalyzer::validateInstructions(FunctionCall const& _functionCall) bool AsmAnalyzer::validateInstructions(FunctionCall const& _functionCall)
{ {
return validateInstructions(_functionCall.functionName.name.str(), locationOf(_functionCall.functionName)); return validateInstructions(_functionCall.functionName.name.str(), nativeLocationOf(_functionCall.functionName));
} }

View File

@ -33,7 +33,7 @@ namespace solidity::yul
Json::Value AsmJsonConverter::operator()(Block const& _node) const Json::Value AsmJsonConverter::operator()(Block const& _node) const
{ {
Json::Value ret = createAstNode(locationOf(_node), "YulBlock"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulBlock");
ret["statements"] = vectorOfVariantsToJson(_node.statements); ret["statements"] = vectorOfVariantsToJson(_node.statements);
return ret; return ret;
} }
@ -41,7 +41,7 @@ Json::Value AsmJsonConverter::operator()(Block const& _node) const
Json::Value AsmJsonConverter::operator()(TypedName const& _node) const Json::Value AsmJsonConverter::operator()(TypedName const& _node) const
{ {
yulAssert(!_node.name.empty(), "Invalid variable name."); yulAssert(!_node.name.empty(), "Invalid variable name.");
Json::Value ret = createAstNode(locationOf(_node), "YulTypedName"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulTypedName");
ret["name"] = _node.name.str(); ret["name"] = _node.name.str();
ret["type"] = _node.type.str(); ret["type"] = _node.type.str();
return ret; return ret;
@ -49,7 +49,7 @@ Json::Value AsmJsonConverter::operator()(TypedName const& _node) const
Json::Value AsmJsonConverter::operator()(Literal const& _node) const Json::Value AsmJsonConverter::operator()(Literal const& _node) const
{ {
Json::Value ret = createAstNode(locationOf(_node), "YulLiteral"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulLiteral");
switch (_node.kind) switch (_node.kind)
{ {
case LiteralKind::Number: case LiteralKind::Number:
@ -76,7 +76,7 @@ Json::Value AsmJsonConverter::operator()(Literal const& _node) const
Json::Value AsmJsonConverter::operator()(Identifier const& _node) const Json::Value AsmJsonConverter::operator()(Identifier const& _node) const
{ {
yulAssert(!_node.name.empty(), "Invalid identifier"); yulAssert(!_node.name.empty(), "Invalid identifier");
Json::Value ret = createAstNode(locationOf(_node), "YulIdentifier"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulIdentifier");
ret["name"] = _node.name.str(); ret["name"] = _node.name.str();
return ret; return ret;
} }
@ -84,7 +84,7 @@ Json::Value AsmJsonConverter::operator()(Identifier const& _node) const
Json::Value AsmJsonConverter::operator()(Assignment const& _node) const Json::Value AsmJsonConverter::operator()(Assignment const& _node) const
{ {
yulAssert(_node.variableNames.size() >= 1, "Invalid assignment syntax"); yulAssert(_node.variableNames.size() >= 1, "Invalid assignment syntax");
Json::Value ret = createAstNode(locationOf(_node), "YulAssignment"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulAssignment");
for (auto const& var: _node.variableNames) for (auto const& var: _node.variableNames)
ret["variableNames"].append((*this)(var)); ret["variableNames"].append((*this)(var));
ret["value"] = _node.value ? std::visit(*this, *_node.value) : Json::nullValue; ret["value"] = _node.value ? std::visit(*this, *_node.value) : Json::nullValue;
@ -93,7 +93,7 @@ Json::Value AsmJsonConverter::operator()(Assignment const& _node) const
Json::Value AsmJsonConverter::operator()(FunctionCall const& _node) const Json::Value AsmJsonConverter::operator()(FunctionCall const& _node) const
{ {
Json::Value ret = createAstNode(locationOf(_node), "YulFunctionCall"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulFunctionCall");
ret["functionName"] = (*this)(_node.functionName); ret["functionName"] = (*this)(_node.functionName);
ret["arguments"] = vectorOfVariantsToJson(_node.arguments); ret["arguments"] = vectorOfVariantsToJson(_node.arguments);
return ret; return ret;
@ -101,14 +101,14 @@ Json::Value AsmJsonConverter::operator()(FunctionCall const& _node) const
Json::Value AsmJsonConverter::operator()(ExpressionStatement const& _node) const Json::Value AsmJsonConverter::operator()(ExpressionStatement const& _node) const
{ {
Json::Value ret = createAstNode(locationOf(_node), "YulExpressionStatement"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulExpressionStatement");
ret["expression"] = std::visit(*this, _node.expression); ret["expression"] = std::visit(*this, _node.expression);
return ret; return ret;
} }
Json::Value AsmJsonConverter::operator()(VariableDeclaration const& _node) const Json::Value AsmJsonConverter::operator()(VariableDeclaration const& _node) const
{ {
Json::Value ret = createAstNode(locationOf(_node), "YulVariableDeclaration"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulVariableDeclaration");
for (auto const& var: _node.variables) for (auto const& var: _node.variables)
ret["variables"].append((*this)(var)); ret["variables"].append((*this)(var));
@ -120,7 +120,7 @@ Json::Value AsmJsonConverter::operator()(VariableDeclaration const& _node) const
Json::Value AsmJsonConverter::operator()(FunctionDefinition const& _node) const Json::Value AsmJsonConverter::operator()(FunctionDefinition const& _node) const
{ {
yulAssert(!_node.name.empty(), "Invalid function name."); yulAssert(!_node.name.empty(), "Invalid function name.");
Json::Value ret = createAstNode(locationOf(_node), "YulFunctionDefinition"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulFunctionDefinition");
ret["name"] = _node.name.str(); ret["name"] = _node.name.str();
for (auto const& var: _node.parameters) for (auto const& var: _node.parameters)
ret["parameters"].append((*this)(var)); ret["parameters"].append((*this)(var));
@ -133,7 +133,7 @@ Json::Value AsmJsonConverter::operator()(FunctionDefinition const& _node) const
Json::Value AsmJsonConverter::operator()(If const& _node) const Json::Value AsmJsonConverter::operator()(If const& _node) const
{ {
yulAssert(_node.condition, "Invalid if condition."); yulAssert(_node.condition, "Invalid if condition.");
Json::Value ret = createAstNode(locationOf(_node), "YulIf"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulIf");
ret["condition"] = std::visit(*this, *_node.condition); ret["condition"] = std::visit(*this, *_node.condition);
ret["body"] = (*this)(_node.body); ret["body"] = (*this)(_node.body);
return ret; return ret;
@ -142,7 +142,7 @@ Json::Value AsmJsonConverter::operator()(If const& _node) const
Json::Value AsmJsonConverter::operator()(Switch const& _node) const Json::Value AsmJsonConverter::operator()(Switch const& _node) const
{ {
yulAssert(_node.expression, "Invalid expression pointer."); yulAssert(_node.expression, "Invalid expression pointer.");
Json::Value ret = createAstNode(locationOf(_node), "YulSwitch"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulSwitch");
ret["expression"] = std::visit(*this, *_node.expression); ret["expression"] = std::visit(*this, *_node.expression);
for (auto const& var: _node.cases) for (auto const& var: _node.cases)
ret["cases"].append((*this)(var)); ret["cases"].append((*this)(var));
@ -151,7 +151,7 @@ Json::Value AsmJsonConverter::operator()(Switch const& _node) const
Json::Value AsmJsonConverter::operator()(Case const& _node) const Json::Value AsmJsonConverter::operator()(Case const& _node) const
{ {
Json::Value ret = createAstNode(locationOf(_node), "YulCase"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulCase");
ret["value"] = _node.value ? (*this)(*_node.value) : "default"; ret["value"] = _node.value ? (*this)(*_node.value) : "default";
ret["body"] = (*this)(_node.body); ret["body"] = (*this)(_node.body);
return ret; return ret;
@ -160,7 +160,7 @@ Json::Value AsmJsonConverter::operator()(Case const& _node) const
Json::Value AsmJsonConverter::operator()(ForLoop const& _node) const Json::Value AsmJsonConverter::operator()(ForLoop const& _node) const
{ {
yulAssert(_node.condition, "Invalid for loop condition."); yulAssert(_node.condition, "Invalid for loop condition.");
Json::Value ret = createAstNode(locationOf(_node), "YulForLoop"); Json::Value ret = createAstNode(nativeLocationOf(_node), "YulForLoop");
ret["pre"] = (*this)(_node.pre); ret["pre"] = (*this)(_node.pre);
ret["condition"] = std::visit(*this, *_node.condition); ret["condition"] = std::visit(*this, *_node.condition);
ret["post"] = (*this)(_node.post); ret["post"] = (*this)(_node.post);
@ -170,17 +170,17 @@ Json::Value AsmJsonConverter::operator()(ForLoop const& _node) const
Json::Value AsmJsonConverter::operator()(Break const& _node) const Json::Value AsmJsonConverter::operator()(Break const& _node) const
{ {
return createAstNode(locationOf(_node), "YulBreak"); return createAstNode(nativeLocationOf(_node), "YulBreak");
} }
Json::Value AsmJsonConverter::operator()(Continue const& _node) const Json::Value AsmJsonConverter::operator()(Continue const& _node) const
{ {
return createAstNode(locationOf(_node), "YulContinue"); return createAstNode(nativeLocationOf(_node), "YulContinue");
} }
Json::Value AsmJsonConverter::operator()(Leave const& _node) const Json::Value AsmJsonConverter::operator()(Leave const& _node) const
{ {
return createAstNode(locationOf(_node), "YulLeave"); return createAstNode(nativeLocationOf(_node), "YulLeave");
} }
Json::Value AsmJsonConverter::createAstNode(langutil::SourceLocation const& _location, string _nodeType) const Json::Value AsmJsonConverter::createAstNode(langutil::SourceLocation const& _location, string _nodeType) const

View File

@ -53,9 +53,12 @@ template <class T>
T AsmJsonImporter::createAsmNode(Json::Value const& _node) T AsmJsonImporter::createAsmNode(Json::Value const& _node)
{ {
T r; T r;
SourceLocation location = createSourceLocation(_node); SourceLocation nativeLocation = createSourceLocation(_node);
yulAssert(location.hasText(), "Invalid source location in Asm AST"); yulAssert(nativeLocation.hasText(), "Invalid source location in Asm AST");
r.debugData = DebugData::create(location); // TODO: We should add originLocation to the AST.
// While it's not included, we'll use nativeLocation for it because we only support importing
// inline assembly as a part of a Solidity AST and there these locations are always the same.
r.debugData = DebugData::create(nativeLocation, nativeLocation);
return r; return r;
} }

View File

@ -46,17 +46,6 @@ using namespace solidity::yul;
namespace namespace
{ {
[[nodiscard]]
shared_ptr<DebugData const> updateLocationEndFrom(
shared_ptr<DebugData const> const& _debugData,
langutil::SourceLocation const& _location
)
{
SourceLocation updatedLocation = _debugData ? _debugData->location : langutil::SourceLocation{};
updatedLocation.end = _location.end;
return make_shared<DebugData const>(updatedLocation);
}
optional<int> toInt(string const& _value) optional<int> toInt(string const& _value)
{ {
try try
@ -76,15 +65,45 @@ std::shared_ptr<DebugData const> Parser::createDebugData() const
switch (m_useSourceLocationFrom) switch (m_useSourceLocationFrom)
{ {
case UseSourceLocationFrom::Scanner: case UseSourceLocationFrom::Scanner:
return DebugData::create(ParserBase::currentLocation()); return DebugData::create(ParserBase::currentLocation(), ParserBase::currentLocation());
case UseSourceLocationFrom::LocationOverride: case UseSourceLocationFrom::LocationOverride:
return DebugData::create(m_locationOverride); return DebugData::create(m_locationOverride, m_locationOverride);
case UseSourceLocationFrom::Comments: case UseSourceLocationFrom::Comments:
return m_debugDataOverride; return DebugData::create(ParserBase::currentLocation(), m_locationFromComment, m_astIDFromComment);
} }
solAssert(false, ""); solAssert(false, "");
} }
void Parser::updateLocationEndFrom(
shared_ptr<DebugData const>& _debugData,
SourceLocation const& _location
) const
{
solAssert(_debugData, "");
switch (m_useSourceLocationFrom)
{
case UseSourceLocationFrom::Scanner:
{
DebugData updatedDebugData = *_debugData;
updatedDebugData.nativeLocation.end = _location.end;
updatedDebugData.originLocation.end = _location.end;
_debugData = make_shared<DebugData const>(move(updatedDebugData));
break;
}
case UseSourceLocationFrom::LocationOverride:
// Ignore the update. The location we're overriding with is not supposed to change
break;
case UseSourceLocationFrom::Comments:
{
DebugData updatedDebugData = *_debugData;
updatedDebugData.nativeLocation.end = _location.end;
_debugData = make_shared<DebugData const>(move(updatedDebugData));
break;
}
}
}
unique_ptr<Block> Parser::parse(CharStream& _charStream) unique_ptr<Block> Parser::parse(CharStream& _charStream)
{ {
m_scanner = make_shared<Scanner>(_charStream); m_scanner = make_shared<Scanner>(_charStream);
@ -135,7 +154,7 @@ void Parser::fetchDebugDataFromComment()
string_view commentLiteral = m_scanner->currentCommentLiteral(); string_view commentLiteral = m_scanner->currentCommentLiteral();
match_results<string_view::const_iterator> match; match_results<string_view::const_iterator> match;
langutil::SourceLocation sourceLocation = m_debugDataOverride->location; langutil::SourceLocation originLocation = m_locationFromComment;
// Empty for each new node. // Empty for each new node.
optional<int> astID; optional<int> astID;
@ -147,7 +166,7 @@ void Parser::fetchDebugDataFromComment()
if (match[1] == "@src") if (match[1] == "@src")
{ {
if (auto parseResult = parseSrcComment(commentLiteral, m_scanner->currentCommentLocation())) if (auto parseResult = parseSrcComment(commentLiteral, m_scanner->currentCommentLocation()))
tie(commentLiteral, sourceLocation) = *parseResult; tie(commentLiteral, originLocation) = *parseResult;
else else
break; break;
} }
@ -163,7 +182,8 @@ void Parser::fetchDebugDataFromComment()
continue; continue;
} }
m_debugDataOverride = DebugData::create(sourceLocation, astID); m_locationFromComment = originLocation;
m_astIDFromComment = astID;
} }
optional<pair<string_view, SourceLocation>> Parser::parseSrcComment( optional<pair<string_view, SourceLocation>> Parser::parseSrcComment(
@ -270,8 +290,7 @@ Block Parser::parseBlock()
expectToken(Token::LBrace); expectToken(Token::LBrace);
while (currentToken() != Token::RBrace) while (currentToken() != Token::RBrace)
block.statements.emplace_back(parseStatement()); block.statements.emplace_back(parseStatement());
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) updateLocationEndFrom(block.debugData, currentLocation());
block.debugData = updateLocationEndFrom(block.debugData, currentLocation());
advance(); advance();
return block; return block;
} }
@ -293,8 +312,7 @@ Statement Parser::parseStatement()
advance(); advance();
_if.condition = make_unique<Expression>(parseExpression()); _if.condition = make_unique<Expression>(parseExpression());
_if.body = parseBlock(); _if.body = parseBlock();
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) updateLocationEndFrom(_if.debugData, nativeLocationOf(_if.body));
_if.debugData = updateLocationEndFrom(_if.debugData, locationOf(_if.body));
return Statement{move(_if)}; return Statement{move(_if)};
} }
case Token::Switch: case Token::Switch:
@ -312,8 +330,7 @@ Statement Parser::parseStatement()
fatalParserError(4904_error, "Case not allowed after default case."); fatalParserError(4904_error, "Case not allowed after default case.");
if (_switch.cases.empty()) if (_switch.cases.empty())
fatalParserError(2418_error, "Switch statement without any cases."); fatalParserError(2418_error, "Switch statement without any cases.");
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) updateLocationEndFrom(_switch.debugData, nativeLocationOf(_switch.cases.back().body));
_switch.debugData = updateLocationEndFrom(_switch.debugData, locationOf(_switch.cases.back().body));
return Statement{move(_switch)}; return Statement{move(_switch)};
} }
case Token::For: case Token::For:
@ -395,8 +412,7 @@ Statement Parser::parseStatement()
expectToken(Token::AssemblyAssign); expectToken(Token::AssemblyAssign);
assignment.value = make_unique<Expression>(parseExpression()); assignment.value = make_unique<Expression>(parseExpression());
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) updateLocationEndFrom(assignment.debugData, nativeLocationOf(*assignment.value));
assignment.debugData = updateLocationEndFrom(assignment.debugData, locationOf(*assignment.value));
return Statement{move(assignment)}; return Statement{move(assignment)};
} }
@ -426,8 +442,7 @@ Case Parser::parseCase()
else else
yulAssert(false, "Case or default case expected."); yulAssert(false, "Case or default case expected.");
_case.body = parseBlock(); _case.body = parseBlock();
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) updateLocationEndFrom(_case.debugData, nativeLocationOf(_case.body));
_case.debugData = updateLocationEndFrom(_case.debugData, locationOf(_case.body));
return _case; return _case;
} }
@ -447,8 +462,7 @@ ForLoop Parser::parseForLoop()
forLoop.post = parseBlock(); forLoop.post = parseBlock();
m_currentForLoopComponent = ForLoopComponent::ForLoopBody; m_currentForLoopComponent = ForLoopComponent::ForLoopBody;
forLoop.body = parseBlock(); forLoop.body = parseBlock();
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) updateLocationEndFrom(forLoop.debugData, nativeLocationOf(forLoop.body));
forLoop.debugData = updateLocationEndFrom(forLoop.debugData, locationOf(forLoop.body));
m_currentForLoopComponent = outerForLoopComponent; m_currentForLoopComponent = outerForLoopComponent;
@ -468,7 +482,7 @@ Expression Parser::parseExpression()
if (m_dialect.builtin(_identifier.name)) if (m_dialect.builtin(_identifier.name))
fatalParserError( fatalParserError(
7104_error, 7104_error,
locationOf(_identifier), nativeLocationOf(_identifier),
"Builtin function \"" + _identifier.name.str() + "\" must be called." "Builtin function \"" + _identifier.name.str() + "\" must be called."
); );
return move(_identifier); return move(_identifier);
@ -527,8 +541,7 @@ variant<Literal, Identifier> Parser::parseLiteralOrIdentifier()
if (currentToken() == Token::Colon) if (currentToken() == Token::Colon)
{ {
expectToken(Token::Colon); expectToken(Token::Colon);
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) updateLocationEndFrom(literal.debugData, currentLocation());
literal.debugData = updateLocationEndFrom(literal.debugData, currentLocation());
literal.type = expectAsmIdentifier(); literal.type = expectAsmIdentifier();
} }
@ -560,11 +573,10 @@ VariableDeclaration Parser::parseVariableDeclaration()
{ {
expectToken(Token::AssemblyAssign); expectToken(Token::AssemblyAssign);
varDecl.value = make_unique<Expression>(parseExpression()); varDecl.value = make_unique<Expression>(parseExpression());
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) updateLocationEndFrom(varDecl.debugData, nativeLocationOf(*varDecl.value));
varDecl.debugData = updateLocationEndFrom(varDecl.debugData, locationOf(*varDecl.value));
} }
else if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) else
varDecl.debugData = updateLocationEndFrom(varDecl.debugData, locationOf(varDecl.variables.back())); updateLocationEndFrom(varDecl.debugData, nativeLocationOf(varDecl.variables.back()));
return varDecl; return varDecl;
} }
@ -610,8 +622,7 @@ FunctionDefinition Parser::parseFunctionDefinition()
m_insideFunction = true; m_insideFunction = true;
funDef.body = parseBlock(); funDef.body = parseBlock();
m_insideFunction = preInsideFunction; m_insideFunction = preInsideFunction;
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) updateLocationEndFrom(funDef.debugData, nativeLocationOf(funDef.body));
funDef.debugData = updateLocationEndFrom(funDef.debugData, locationOf(funDef.body));
m_currentForLoopComponent = outerForLoopComponent; m_currentForLoopComponent = outerForLoopComponent;
return funDef; return funDef;
@ -638,8 +649,7 @@ FunctionCall Parser::parseCall(variant<Literal, Identifier>&& _initialOp)
ret.arguments.emplace_back(parseExpression()); ret.arguments.emplace_back(parseExpression());
} }
} }
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) updateLocationEndFrom(ret.debugData, currentLocation());
ret.debugData = updateLocationEndFrom(ret.debugData, currentLocation());
expectToken(Token::RParen); expectToken(Token::RParen);
return ret; return ret;
} }
@ -652,8 +662,7 @@ TypedName Parser::parseTypedName()
if (currentToken() == Token::Colon) if (currentToken() == Token::Colon)
{ {
expectToken(Token::Colon); expectToken(Token::Colon);
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) updateLocationEndFrom(typedName.debugData, currentLocation());
typedName.debugData = updateLocationEndFrom(typedName.debugData, currentLocation());
typedName.type = expectAsmIdentifier(); typedName.type = expectAsmIdentifier();
} }
else else

View File

@ -61,7 +61,6 @@ public:
ParserBase(_errorReporter), ParserBase(_errorReporter),
m_dialect(_dialect), m_dialect(_dialect),
m_locationOverride{_locationOverride ? *_locationOverride : langutil::SourceLocation{}}, m_locationOverride{_locationOverride ? *_locationOverride : langutil::SourceLocation{}},
m_debugDataOverride{},
m_useSourceLocationFrom{ m_useSourceLocationFrom{
_locationOverride ? _locationOverride ?
UseSourceLocationFrom::LocationOverride : UseSourceLocationFrom::LocationOverride :
@ -79,7 +78,6 @@ public:
ParserBase(_errorReporter), ParserBase(_errorReporter),
m_dialect(_dialect), m_dialect(_dialect),
m_sourceNames{std::move(_sourceNames)}, m_sourceNames{std::move(_sourceNames)},
m_debugDataOverride{DebugData::create()},
m_useSourceLocationFrom{ m_useSourceLocationFrom{
m_sourceNames.has_value() ? m_sourceNames.has_value() ?
UseSourceLocationFrom::Comments : UseSourceLocationFrom::Comments :
@ -99,9 +97,10 @@ public:
protected: protected:
langutil::SourceLocation currentLocation() const override langutil::SourceLocation currentLocation() const override
{ {
if (m_useSourceLocationFrom == UseSourceLocationFrom::Scanner) if (m_useSourceLocationFrom == UseSourceLocationFrom::LocationOverride)
return ParserBase::currentLocation(); return m_locationOverride;
return m_locationOverride;
return ParserBase::currentLocation();
} }
langutil::Token advance() override; langutil::Token advance() override;
@ -121,6 +120,11 @@ protected:
/// Creates a DebugData object with the correct source location set. /// Creates a DebugData object with the correct source location set.
std::shared_ptr<DebugData const> createDebugData() const; std::shared_ptr<DebugData const> createDebugData() const;
void updateLocationEndFrom(
std::shared_ptr<DebugData const>& _debugData,
langutil::SourceLocation const& _location
) const;
/// Creates an inline assembly node with the current source location. /// Creates an inline assembly node with the current source location.
template <class T> T createWithLocation() const template <class T> T createWithLocation() const
{ {
@ -154,7 +158,8 @@ private:
std::optional<std::map<unsigned, std::shared_ptr<std::string const>>> m_sourceNames; std::optional<std::map<unsigned, std::shared_ptr<std::string const>>> m_sourceNames;
langutil::SourceLocation m_locationOverride; langutil::SourceLocation m_locationOverride;
std::shared_ptr<DebugData const> m_debugDataOverride; langutil::SourceLocation m_locationFromComment;
std::optional<int64_t> m_astIDFromComment;
UseSourceLocationFrom m_useSourceLocationFrom = UseSourceLocationFrom::Scanner; UseSourceLocationFrom m_useSourceLocationFrom = UseSourceLocationFrom::Scanner;
ForLoopComponent m_currentForLoopComponent = ForLoopComponent::None; ForLoopComponent m_currentForLoopComponent = ForLoopComponent::None;
bool m_insideFunction = false; bool m_insideFunction = false;

View File

@ -306,14 +306,14 @@ string AsmPrinter::formatDebugData(shared_ptr<DebugData const> const& _debugData
items.emplace_back("@ast-id " + to_string(*id)); items.emplace_back("@ast-id " + to_string(*id));
if ( if (
m_lastLocation != _debugData->location && m_lastLocation != _debugData->originLocation &&
!m_nameToSourceIndex.empty() !m_nameToSourceIndex.empty()
) )
{ {
m_lastLocation = _debugData->location; m_lastLocation = _debugData->originLocation;
items.emplace_back(formatSourceLocation( items.emplace_back(formatSourceLocation(
_debugData->location, _debugData->originLocation,
m_nameToSourceIndex, m_nameToSourceIndex,
m_soliditySourceProvider m_soliditySourceProvider
)); ));

View File

@ -53,7 +53,7 @@ bool ScopeFiller::operator()(ExpressionStatement const& _expr)
bool ScopeFiller::operator()(VariableDeclaration const& _varDecl) bool ScopeFiller::operator()(VariableDeclaration const& _varDecl)
{ {
for (auto const& variable: _varDecl.variables) for (auto const& variable: _varDecl.variables)
if (!registerVariable(variable, locationOf(_varDecl), *m_currentScope)) if (!registerVariable(variable, nativeLocationOf(_varDecl), *m_currentScope))
return false; return false;
return true; return true;
} }
@ -68,7 +68,7 @@ bool ScopeFiller::operator()(FunctionDefinition const& _funDef)
bool success = true; bool success = true;
for (auto const& var: _funDef.parameters + _funDef.returnVariables) for (auto const& var: _funDef.parameters + _funDef.returnVariables)
if (!registerVariable(var, locationOf(_funDef), varScope)) if (!registerVariable(var, nativeLocationOf(_funDef), varScope))
success = false; success = false;
if (!(*this)(_funDef.body)) if (!(*this)(_funDef.body))
@ -162,7 +162,7 @@ bool ScopeFiller::registerFunction(FunctionDefinition const& _funDef)
//@TODO secondary location //@TODO secondary location
m_errorReporter.declarationError( m_errorReporter.declarationError(
6052_error, 6052_error,
locationOf(_funDef), nativeLocationOf(_funDef),
"Function name " + _funDef.name.str() + " already taken in this scope." "Function name " + _funDef.name.str() + " already taken in this scope."
); );
return false; return false;

View File

@ -145,13 +145,13 @@ void CodeTransform::operator()(VariableDeclaration const& _varDecl)
} }
else else
{ {
m_assembly.setSourceLocation(locationOf(_varDecl)); m_assembly.setSourceLocation(originLocationOf(_varDecl));
size_t variablesLeft = numVariables; size_t variablesLeft = numVariables;
while (variablesLeft--) while (variablesLeft--)
m_assembly.appendConstant(u256(0)); m_assembly.appendConstant(u256(0));
} }
m_assembly.setSourceLocation(locationOf(_varDecl)); m_assembly.setSourceLocation(originLocationOf(_varDecl));
bool atTopOfStack = true; bool atTopOfStack = true;
for (size_t varIndex = 0; varIndex < numVariables; ++varIndex) for (size_t varIndex = 0; varIndex < numVariables; ++varIndex)
{ {
@ -213,13 +213,13 @@ void CodeTransform::operator()(Assignment const& _assignment)
std::visit(*this, *_assignment.value); std::visit(*this, *_assignment.value);
expectDeposit(static_cast<int>(_assignment.variableNames.size()), height); expectDeposit(static_cast<int>(_assignment.variableNames.size()), height);
m_assembly.setSourceLocation(locationOf(_assignment)); m_assembly.setSourceLocation(originLocationOf(_assignment));
generateMultiAssignment(_assignment.variableNames); generateMultiAssignment(_assignment.variableNames);
} }
void CodeTransform::operator()(ExpressionStatement const& _statement) void CodeTransform::operator()(ExpressionStatement const& _statement)
{ {
m_assembly.setSourceLocation(locationOf(_statement)); m_assembly.setSourceLocation(originLocationOf(_statement));
std::visit(*this, _statement.expression); std::visit(*this, _statement.expression);
} }
@ -227,13 +227,13 @@ void CodeTransform::operator()(FunctionCall const& _call)
{ {
yulAssert(m_scope, ""); yulAssert(m_scope, "");
m_assembly.setSourceLocation(locationOf(_call)); m_assembly.setSourceLocation(originLocationOf(_call));
if (BuiltinFunctionForEVM const* builtin = m_dialect.builtin(_call.functionName.name)) if (BuiltinFunctionForEVM const* builtin = m_dialect.builtin(_call.functionName.name))
{ {
for (auto&& [i, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse) for (auto&& [i, arg]: _call.arguments | ranges::views::enumerate | ranges::views::reverse)
if (!builtin->literalArgument(i)) if (!builtin->literalArgument(i))
visitExpression(arg); visitExpression(arg);
m_assembly.setSourceLocation(locationOf(_call)); m_assembly.setSourceLocation(originLocationOf(_call));
builtin->generateCode(_call, m_assembly, m_builtinContext); builtin->generateCode(_call, m_assembly, m_builtinContext);
} }
else else
@ -250,7 +250,7 @@ void CodeTransform::operator()(FunctionCall const& _call)
yulAssert(function->arguments.size() == _call.arguments.size(), ""); yulAssert(function->arguments.size() == _call.arguments.size(), "");
for (auto const& arg: _call.arguments | ranges::views::reverse) for (auto const& arg: _call.arguments | ranges::views::reverse)
visitExpression(arg); visitExpression(arg);
m_assembly.setSourceLocation(locationOf(_call)); m_assembly.setSourceLocation(originLocationOf(_call));
m_assembly.appendJumpTo( m_assembly.appendJumpTo(
functionEntryID(*function), functionEntryID(*function),
static_cast<int>(function->returns.size() - function->arguments.size()) - 1, static_cast<int>(function->returns.size() - function->arguments.size()) - 1,
@ -262,7 +262,7 @@ void CodeTransform::operator()(FunctionCall const& _call)
void CodeTransform::operator()(Identifier const& _identifier) void CodeTransform::operator()(Identifier const& _identifier)
{ {
m_assembly.setSourceLocation(locationOf(_identifier)); m_assembly.setSourceLocation(originLocationOf(_identifier));
// First search internals, then externals. // First search internals, then externals.
yulAssert(m_scope, ""); yulAssert(m_scope, "");
if (m_scope->lookup(_identifier.name, GenericVisitor{ if (m_scope->lookup(_identifier.name, GenericVisitor{
@ -294,19 +294,19 @@ void CodeTransform::operator()(Identifier const& _identifier)
void CodeTransform::operator()(Literal const& _literal) void CodeTransform::operator()(Literal const& _literal)
{ {
m_assembly.setSourceLocation(locationOf(_literal)); m_assembly.setSourceLocation(originLocationOf(_literal));
m_assembly.appendConstant(valueOfLiteral(_literal)); m_assembly.appendConstant(valueOfLiteral(_literal));
} }
void CodeTransform::operator()(If const& _if) void CodeTransform::operator()(If const& _if)
{ {
visitExpression(*_if.condition); visitExpression(*_if.condition);
m_assembly.setSourceLocation(locationOf(_if)); m_assembly.setSourceLocation(originLocationOf(_if));
m_assembly.appendInstruction(evmasm::Instruction::ISZERO); m_assembly.appendInstruction(evmasm::Instruction::ISZERO);
AbstractAssembly::LabelID end = m_assembly.newLabelId(); AbstractAssembly::LabelID end = m_assembly.newLabelId();
m_assembly.appendJumpToIf(end); m_assembly.appendJumpToIf(end);
(*this)(_if.body); (*this)(_if.body);
m_assembly.setSourceLocation(locationOf(_if)); m_assembly.setSourceLocation(originLocationOf(_if));
m_assembly.appendLabel(end); m_assembly.appendLabel(end);
} }
@ -321,7 +321,7 @@ void CodeTransform::operator()(Switch const& _switch)
if (c.value) if (c.value)
{ {
(*this)(*c.value); (*this)(*c.value);
m_assembly.setSourceLocation(locationOf(c)); m_assembly.setSourceLocation(originLocationOf(c));
AbstractAssembly::LabelID bodyLabel = m_assembly.newLabelId(); AbstractAssembly::LabelID bodyLabel = m_assembly.newLabelId();
caseBodies[&c] = bodyLabel; caseBodies[&c] = bodyLabel;
yulAssert(m_assembly.stackHeight() == expressionHeight + 1, ""); yulAssert(m_assembly.stackHeight() == expressionHeight + 1, "");
@ -333,24 +333,24 @@ void CodeTransform::operator()(Switch const& _switch)
// default case // default case
(*this)(c.body); (*this)(c.body);
} }
m_assembly.setSourceLocation(locationOf(_switch)); m_assembly.setSourceLocation(originLocationOf(_switch));
m_assembly.appendJumpTo(end); m_assembly.appendJumpTo(end);
size_t numCases = caseBodies.size(); size_t numCases = caseBodies.size();
for (auto const& c: caseBodies) for (auto const& c: caseBodies)
{ {
m_assembly.setSourceLocation(locationOf(*c.first)); m_assembly.setSourceLocation(originLocationOf(*c.first));
m_assembly.appendLabel(c.second); m_assembly.appendLabel(c.second);
(*this)(c.first->body); (*this)(c.first->body);
// Avoid useless "jump to next" for the last case. // Avoid useless "jump to next" for the last case.
if (--numCases > 0) if (--numCases > 0)
{ {
m_assembly.setSourceLocation(locationOf(*c.first)); m_assembly.setSourceLocation(originLocationOf(*c.first));
m_assembly.appendJumpTo(end); m_assembly.appendJumpTo(end);
} }
} }
m_assembly.setSourceLocation(locationOf(_switch)); m_assembly.setSourceLocation(originLocationOf(_switch));
m_assembly.appendLabel(end); m_assembly.appendLabel(end);
m_assembly.appendInstruction(evmasm::Instruction::POP); m_assembly.appendInstruction(evmasm::Instruction::POP);
} }
@ -371,7 +371,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
m_context->variableStackHeights[&var] = height++; m_context->variableStackHeights[&var] = height++;
} }
m_assembly.setSourceLocation(locationOf(_function)); m_assembly.setSourceLocation(originLocationOf(_function));
int const stackHeightBefore = m_assembly.stackHeight(); int const stackHeightBefore = m_assembly.stackHeight();
m_assembly.appendLabel(functionEntryID(function)); m_assembly.appendLabel(functionEntryID(function));
@ -407,7 +407,7 @@ void CodeTransform::operator()(FunctionDefinition const& _function)
subTransform(_function.body); subTransform(_function.body);
m_assembly.setSourceLocation(locationOf(_function)); m_assembly.setSourceLocation(originLocationOf(_function));
if (!subTransform.m_stackErrors.empty()) if (!subTransform.m_stackErrors.empty())
{ {
m_assembly.markAsInvalid(); m_assembly.markAsInvalid();
@ -498,11 +498,11 @@ void CodeTransform::operator()(ForLoop const& _forLoop)
AbstractAssembly::LabelID postPart = m_assembly.newLabelId(); AbstractAssembly::LabelID postPart = m_assembly.newLabelId();
AbstractAssembly::LabelID loopEnd = m_assembly.newLabelId(); AbstractAssembly::LabelID loopEnd = m_assembly.newLabelId();
m_assembly.setSourceLocation(locationOf(_forLoop)); m_assembly.setSourceLocation(originLocationOf(_forLoop));
m_assembly.appendLabel(loopStart); m_assembly.appendLabel(loopStart);
visitExpression(*_forLoop.condition); visitExpression(*_forLoop.condition);
m_assembly.setSourceLocation(locationOf(_forLoop)); m_assembly.setSourceLocation(originLocationOf(_forLoop));
m_assembly.appendInstruction(evmasm::Instruction::ISZERO); m_assembly.appendInstruction(evmasm::Instruction::ISZERO);
m_assembly.appendJumpToIf(loopEnd); m_assembly.appendJumpToIf(loopEnd);
@ -510,12 +510,12 @@ void CodeTransform::operator()(ForLoop const& _forLoop)
m_context->forLoopStack.emplace(Context::ForLoopLabels{ {postPart, stackHeightBody}, {loopEnd, stackHeightBody} }); m_context->forLoopStack.emplace(Context::ForLoopLabels{ {postPart, stackHeightBody}, {loopEnd, stackHeightBody} });
(*this)(_forLoop.body); (*this)(_forLoop.body);
m_assembly.setSourceLocation(locationOf(_forLoop)); m_assembly.setSourceLocation(originLocationOf(_forLoop));
m_assembly.appendLabel(postPart); m_assembly.appendLabel(postPart);
(*this)(_forLoop.post); (*this)(_forLoop.post);
m_assembly.setSourceLocation(locationOf(_forLoop)); m_assembly.setSourceLocation(originLocationOf(_forLoop));
m_assembly.appendJumpTo(loopStart); m_assembly.appendJumpTo(loopStart);
m_assembly.appendLabel(loopEnd); m_assembly.appendLabel(loopEnd);
@ -535,7 +535,7 @@ int CodeTransform::appendPopUntil(int _targetDepth)
void CodeTransform::operator()(Break const& _break) void CodeTransform::operator()(Break const& _break)
{ {
yulAssert(!m_context->forLoopStack.empty(), "Invalid break-statement. Requires surrounding for-loop in code generation."); yulAssert(!m_context->forLoopStack.empty(), "Invalid break-statement. Requires surrounding for-loop in code generation.");
m_assembly.setSourceLocation(locationOf(_break)); m_assembly.setSourceLocation(originLocationOf(_break));
Context::JumpInfo const& jump = m_context->forLoopStack.top().done; Context::JumpInfo const& jump = m_context->forLoopStack.top().done;
m_assembly.appendJumpTo(jump.label, appendPopUntil(jump.targetStackHeight)); m_assembly.appendJumpTo(jump.label, appendPopUntil(jump.targetStackHeight));
@ -544,7 +544,7 @@ void CodeTransform::operator()(Break const& _break)
void CodeTransform::operator()(Continue const& _continue) void CodeTransform::operator()(Continue const& _continue)
{ {
yulAssert(!m_context->forLoopStack.empty(), "Invalid continue-statement. Requires surrounding for-loop in code generation."); yulAssert(!m_context->forLoopStack.empty(), "Invalid continue-statement. Requires surrounding for-loop in code generation.");
m_assembly.setSourceLocation(locationOf(_continue)); m_assembly.setSourceLocation(originLocationOf(_continue));
Context::JumpInfo const& jump = m_context->forLoopStack.top().post; Context::JumpInfo const& jump = m_context->forLoopStack.top().post;
m_assembly.appendJumpTo(jump.label, appendPopUntil(jump.targetStackHeight)); m_assembly.appendJumpTo(jump.label, appendPopUntil(jump.targetStackHeight));
@ -554,7 +554,7 @@ void CodeTransform::operator()(Leave const& _leaveStatement)
{ {
yulAssert(m_functionExitLabel, "Invalid leave-statement. Requires surrounding function in code generation."); yulAssert(m_functionExitLabel, "Invalid leave-statement. Requires surrounding function in code generation.");
yulAssert(m_functionExitStackHeight, ""); yulAssert(m_functionExitStackHeight, "");
m_assembly.setSourceLocation(locationOf(_leaveStatement)); m_assembly.setSourceLocation(originLocationOf(_leaveStatement));
m_assembly.appendJumpTo(*m_functionExitLabel, appendPopUntil(*m_functionExitStackHeight)); m_assembly.appendJumpTo(*m_functionExitLabel, appendPopUntil(*m_functionExitStackHeight));
} }
@ -683,7 +683,7 @@ void CodeTransform::visitStatements(vector<Statement> const& _statements)
auto const* functionDefinition = std::get_if<FunctionDefinition>(&statement); auto const* functionDefinition = std::get_if<FunctionDefinition>(&statement);
if (functionDefinition && !jumpTarget) if (functionDefinition && !jumpTarget)
{ {
m_assembly.setSourceLocation(locationOf(*functionDefinition)); m_assembly.setSourceLocation(originLocationOf(*functionDefinition));
jumpTarget = m_assembly.newLabelId(); jumpTarget = m_assembly.newLabelId();
m_assembly.appendJumpTo(*jumpTarget, 0); m_assembly.appendJumpTo(*jumpTarget, 0);
} }
@ -704,7 +704,7 @@ void CodeTransform::visitStatements(vector<Statement> const& _statements)
void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartStackHeight) void CodeTransform::finalizeBlock(Block const& _block, optional<int> blockStartStackHeight)
{ {
m_assembly.setSourceLocation(locationOf(_block)); m_assembly.setSourceLocation(originLocationOf(_block));
freeUnusedVariables(); freeUnusedVariables();

View File

@ -85,7 +85,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionCall const& _call)
// Emit code. // Emit code.
{ {
m_assembly.setSourceLocation(locationOf(_call)); m_assembly.setSourceLocation(originLocationOf(_call));
m_assembly.appendJumpTo( m_assembly.appendJumpTo(
getFunctionLabel(_call.function), getFunctionLabel(_call.function),
static_cast<int>(_call.function.get().returns.size() - _call.function.get().arguments.size()) - 1, static_cast<int>(_call.function.get().returns.size() - _call.function.get().arguments.size()) - 1,
@ -128,7 +128,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::BuiltinCall const& _call)
// Emit code. // Emit code.
{ {
m_assembly.setSourceLocation(locationOf(_call)); m_assembly.setSourceLocation(originLocationOf(_call));
static_cast<BuiltinFunctionForEVM const&>(_call.builtin.get()).generateCode( static_cast<BuiltinFunctionForEVM const&>(_call.builtin.get()).generateCode(
_call.functionCall, _call.functionCall,
m_assembly, m_assembly,
@ -231,7 +231,7 @@ void OptimizedEVMCodeTransform::createStackLayout(std::shared_ptr<DebugData cons
yulAssert(m_assembly.stackHeight() == static_cast<int>(m_stack.size()), ""); yulAssert(m_assembly.stackHeight() == static_cast<int>(m_stack.size()), "");
// ::createStackLayout asserts that it has successfully achieved the target layout. // ::createStackLayout asserts that it has successfully achieved the target layout.
langutil::SourceLocation sourceLocation = _debugData ? _debugData->location : langutil::SourceLocation{}; langutil::SourceLocation sourceLocation = _debugData ? _debugData->originLocation : langutil::SourceLocation{};
m_assembly.setSourceLocation(sourceLocation); m_assembly.setSourceLocation(sourceLocation);
::createStackLayout( ::createStackLayout(
m_stack, m_stack,
@ -299,7 +299,7 @@ void OptimizedEVMCodeTransform::createStackLayout(std::shared_ptr<DebugData cons
std::visit(util::GenericVisitor{ std::visit(util::GenericVisitor{
[&](LiteralSlot const& _literal) [&](LiteralSlot const& _literal)
{ {
m_assembly.setSourceLocation(locationOf(_literal)); m_assembly.setSourceLocation(originLocationOf(_literal));
m_assembly.appendConstant(_literal.value); m_assembly.appendConstant(_literal.value);
m_assembly.setSourceLocation(sourceLocation); m_assembly.setSourceLocation(sourceLocation);
}, },
@ -311,7 +311,7 @@ void OptimizedEVMCodeTransform::createStackLayout(std::shared_ptr<DebugData cons
{ {
if (!m_returnLabels.count(&_returnLabel.call.get())) if (!m_returnLabels.count(&_returnLabel.call.get()))
m_returnLabels[&_returnLabel.call.get()] = m_assembly.newLabelId(); m_returnLabels[&_returnLabel.call.get()] = m_assembly.newLabelId();
m_assembly.setSourceLocation(locationOf(_returnLabel.call.get())); m_assembly.setSourceLocation(originLocationOf(_returnLabel.call.get()));
m_assembly.appendLabelReference(m_returnLabels.at(&_returnLabel.call.get())); m_assembly.appendLabelReference(m_returnLabels.at(&_returnLabel.call.get()));
m_assembly.setSourceLocation(sourceLocation); m_assembly.setSourceLocation(sourceLocation);
}, },
@ -319,7 +319,7 @@ void OptimizedEVMCodeTransform::createStackLayout(std::shared_ptr<DebugData cons
{ {
if (m_currentFunctionInfo && util::contains(m_currentFunctionInfo->returnVariables, _variable)) if (m_currentFunctionInfo && util::contains(m_currentFunctionInfo->returnVariables, _variable))
{ {
m_assembly.setSourceLocation(locationOf(_variable)); m_assembly.setSourceLocation(originLocationOf(_variable));
m_assembly.appendConstant(0); m_assembly.appendConstant(0);
m_assembly.setSourceLocation(sourceLocation); m_assembly.setSourceLocation(sourceLocation);
return; return;
@ -351,7 +351,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block)
// Assert that this is the first visit of the block and mark as generated. // Assert that this is the first visit of the block and mark as generated.
yulAssert(m_generated.insert(&_block).second, ""); yulAssert(m_generated.insert(&_block).second, "");
m_assembly.setSourceLocation(locationOf(_block)); m_assembly.setSourceLocation(originLocationOf(_block));
auto const& blockInfo = m_stackLayout.blockInfos.at(&_block); auto const& blockInfo = m_stackLayout.blockInfos.at(&_block);
// Assert that the stack is valid for entering the block. // Assert that the stack is valid for entering the block.
@ -391,7 +391,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::BasicBlock const& _block)
} }
// Exit the block. // Exit the block.
m_assembly.setSourceLocation(locationOf(_block)); m_assembly.setSourceLocation(originLocationOf(_block));
std::visit(util::GenericVisitor{ std::visit(util::GenericVisitor{
[&](CFG::BasicBlock::MainExit const&) [&](CFG::BasicBlock::MainExit const&)
{ {
@ -506,7 +506,7 @@ void OptimizedEVMCodeTransform::operator()(CFG::FunctionInfo const& _functionInf
m_stack.emplace_back(param); m_stack.emplace_back(param);
m_assembly.setStackHeight(static_cast<int>(m_stack.size())); m_assembly.setStackHeight(static_cast<int>(m_stack.size()));
m_assembly.setSourceLocation(locationOf(_functionInfo)); m_assembly.setSourceLocation(originLocationOf(_functionInfo));
m_assembly.appendLabel(getFunctionLabel(_functionInfo.function)); m_assembly.appendLabel(getFunctionLabel(_functionInfo.function));
// Create the entry layout of the function body block and visit. // Create the entry layout of the function body block and visit.

View File

@ -214,7 +214,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_empty_block)
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
CHECK_LOCATION(result->debugData->location, "source0", 234, 543); CHECK_LOCATION(result->debugData->originLocation, "source0", 234, 543);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_block_with_children) BOOST_AUTO_TEST_CASE(customSourceLocations_block_with_children)
@ -232,12 +232,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_with_children)
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result); BOOST_REQUIRE(!!result);
CHECK_LOCATION(result->debugData->location, "source0", 234, 543); CHECK_LOCATION(result->debugData->originLocation, "source0", 234, 543);
BOOST_REQUIRE_EQUAL(3, result->statements.size()); BOOST_REQUIRE_EQUAL(3, result->statements.size());
CHECK_LOCATION(locationOf(result->statements.at(0)), "source0", 234, 543); CHECK_LOCATION(originLocationOf(result->statements.at(0)), "source0", 234, 543);
CHECK_LOCATION(locationOf(result->statements.at(1)), "source0", 123, 432); CHECK_LOCATION(originLocationOf(result->statements.at(1)), "source0", 123, 432);
// [2] is inherited source location // [2] is inherited source location
CHECK_LOCATION(locationOf(result->statements.at(2)), "source0", 123, 432); CHECK_LOCATION(originLocationOf(result->statements.at(2)), "source0", 123, 432);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_block_different_sources) BOOST_AUTO_TEST_CASE(customSourceLocations_block_different_sources)
@ -255,12 +255,12 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_different_sources)
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
CHECK_LOCATION(result->debugData->location, "source0", 234, 543); CHECK_LOCATION(result->debugData->originLocation, "source0", 234, 543);
BOOST_REQUIRE_EQUAL(3, result->statements.size()); BOOST_REQUIRE_EQUAL(3, result->statements.size());
CHECK_LOCATION(locationOf(result->statements.at(0)), "source0", 234, 543); CHECK_LOCATION(originLocationOf(result->statements.at(0)), "source0", 234, 543);
CHECK_LOCATION(locationOf(result->statements.at(1)), "source1", 123, 432); CHECK_LOCATION(originLocationOf(result->statements.at(1)), "source1", 123, 432);
// [2] is inherited source location // [2] is inherited source location
CHECK_LOCATION(locationOf(result->statements.at(2)), "source1", 123, 432); CHECK_LOCATION(originLocationOf(result->statements.at(2)), "source1", 123, 432);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_block_nested) BOOST_AUTO_TEST_CASE(customSourceLocations_block_nested)
@ -277,9 +277,9 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_nested)
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
CHECK_LOCATION(result->debugData->location, "source0", 234, 543); CHECK_LOCATION(result->debugData->originLocation, "source0", 234, 543);
BOOST_REQUIRE_EQUAL(2, result->statements.size()); BOOST_REQUIRE_EQUAL(2, result->statements.size());
CHECK_LOCATION(locationOf(result->statements.at(1)), "source0", 343, 434); CHECK_LOCATION(originLocationOf(result->statements.at(1)), "source0", 343, 434);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_block_switch_case) BOOST_AUTO_TEST_CASE(customSourceLocations_block_switch_case)
@ -301,19 +301,19 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_block_switch_case)
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
CHECK_LOCATION(result->debugData->location, "source0", 234, 543); CHECK_LOCATION(result->debugData->originLocation, "source0", 234, 543);
BOOST_REQUIRE_EQUAL(2, result->statements.size()); BOOST_REQUIRE_EQUAL(2, result->statements.size());
BOOST_REQUIRE(holds_alternative<Switch>(result->statements.at(1))); BOOST_REQUIRE(holds_alternative<Switch>(result->statements.at(1)));
auto const& switchStmt = get<Switch>(result->statements.at(1)); auto const& switchStmt = get<Switch>(result->statements.at(1));
CHECK_LOCATION(switchStmt.debugData->location, "source0", 343, 434); CHECK_LOCATION(switchStmt.debugData->originLocation, "source0", 343, 434);
BOOST_REQUIRE_EQUAL(1, switchStmt.cases.size()); BOOST_REQUIRE_EQUAL(1, switchStmt.cases.size());
CHECK_LOCATION(switchStmt.cases.at(0).debugData->location, "source0", 3141, 59265); CHECK_LOCATION(switchStmt.cases.at(0).debugData->originLocation, "source0", 3141, 59265);
auto const& caseBody = switchStmt.cases.at(0).body; auto const& caseBody = switchStmt.cases.at(0).body;
BOOST_REQUIRE_EQUAL(1, caseBody.statements.size()); BOOST_REQUIRE_EQUAL(1, caseBody.statements.size());
CHECK_LOCATION(locationOf(caseBody.statements.at(0)), "source0", 271, 828); CHECK_LOCATION(originLocationOf(caseBody.statements.at(0)), "source0", 271, 828);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_inherit_into_outer_scope) BOOST_AUTO_TEST_CASE(customSourceLocations_inherit_into_outer_scope)
@ -334,19 +334,19 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_inherit_into_outer_scope)
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
CHECK_LOCATION(result->debugData->location, "source0", 1, 100); CHECK_LOCATION(result->debugData->originLocation, "source0", 1, 100);
BOOST_REQUIRE_EQUAL(3, result->statements.size()); BOOST_REQUIRE_EQUAL(3, result->statements.size());
CHECK_LOCATION(locationOf(result->statements.at(0)), "source0", 1, 100); CHECK_LOCATION(originLocationOf(result->statements.at(0)), "source0", 1, 100);
// First child element must be a block itself with one statement. // First child element must be a block itself with one statement.
BOOST_REQUIRE(holds_alternative<Block>(result->statements.at(0))); BOOST_REQUIRE(holds_alternative<Block>(result->statements.at(0)));
BOOST_REQUIRE_EQUAL(get<Block>(result->statements.at(0)).statements.size(), 1); BOOST_REQUIRE_EQUAL(get<Block>(result->statements.at(0)).statements.size(), 1);
CHECK_LOCATION(locationOf(get<Block>(result->statements.at(0)).statements.at(0)), "source0", 123, 432); CHECK_LOCATION(originLocationOf(get<Block>(result->statements.at(0)).statements.at(0)), "source0", 123, 432);
// The next two elements have an inherited source location from the prior inner scope. // The next two elements have an inherited source location from the prior inner scope.
CHECK_LOCATION(locationOf(result->statements.at(1)), "source0", 123, 432); CHECK_LOCATION(originLocationOf(result->statements.at(1)), "source0", 123, 432);
CHECK_LOCATION(locationOf(result->statements.at(2)), "source0", 123, 432); CHECK_LOCATION(originLocationOf(result->statements.at(2)), "source0", 123, 432);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_assign_empty) BOOST_AUTO_TEST_CASE(customSourceLocations_assign_empty)
@ -365,8 +365,8 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_assign_empty)
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); // should still parse BOOST_REQUIRE(!!result && errorList.size() == 0); // should still parse
BOOST_REQUIRE_EQUAL(2, result->statements.size()); BOOST_REQUIRE_EQUAL(2, result->statements.size());
CHECK_LOCATION(locationOf(result->statements.at(0)), "source0", 123, 432); CHECK_LOCATION(originLocationOf(result->statements.at(0)), "source0", 123, 432);
CHECK_LOCATION(locationOf(result->statements.at(1)), "source1", 1, 10); CHECK_LOCATION(originLocationOf(result->statements.at(1)), "source1", 1, 10);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_source_index) BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_source_index)
@ -407,10 +407,10 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_1)
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
BOOST_REQUIRE_EQUAL(1, result->statements.size()); BOOST_REQUIRE_EQUAL(1, result->statements.size());
CHECK_LOCATION(locationOf(result->statements.at(0)), "source0", 123, 432); CHECK_LOCATION(originLocationOf(result->statements.at(0)), "source0", 123, 432);
BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0))); BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0)));
VariableDeclaration const& varDecl = get<VariableDeclaration>(result->statements.at(0)); VariableDeclaration const& varDecl = get<VariableDeclaration>(result->statements.at(0));
CHECK_LOCATION(locationOf(*varDecl.value), "source0", 234, 2026); CHECK_LOCATION(originLocationOf(*varDecl.value), "source0", 234, 2026);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_2) BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_2)
@ -429,20 +429,20 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_2)
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
BOOST_REQUIRE_EQUAL(1, result->statements.size()); BOOST_REQUIRE_EQUAL(1, result->statements.size());
CHECK_LOCATION(result->debugData->location, "source0", 0, 5); CHECK_LOCATION(result->debugData->originLocation, "source0", 0, 5);
// `let x := add(1, ` // `let x := add(1, `
BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0))); BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0)));
VariableDeclaration const& varDecl = get<VariableDeclaration>(result->statements.at(0)); VariableDeclaration const& varDecl = get<VariableDeclaration>(result->statements.at(0));
CHECK_LOCATION(varDecl.debugData->location, "source0", 0, 5); CHECK_LOCATION(varDecl.debugData->originLocation, "source0", 0, 5);
BOOST_REQUIRE(!!varDecl.value); BOOST_REQUIRE(!!varDecl.value);
BOOST_REQUIRE(holds_alternative<FunctionCall>(*varDecl.value)); BOOST_REQUIRE(holds_alternative<FunctionCall>(*varDecl.value));
FunctionCall const& call = get<FunctionCall>(*varDecl.value); FunctionCall const& call = get<FunctionCall>(*varDecl.value);
CHECK_LOCATION(call.debugData->location, "source1", 2, 3); CHECK_LOCATION(call.debugData->originLocation, "source1", 2, 3);
// `2` // `2`
BOOST_REQUIRE_EQUAL(2, call.arguments.size()); BOOST_REQUIRE_EQUAL(2, call.arguments.size());
CHECK_LOCATION(locationOf(call.arguments.at(1)), "source0", 4, 8); CHECK_LOCATION(originLocationOf(call.arguments.at(1)), "source0", 4, 8);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_3) BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_3)
@ -463,24 +463,24 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_mixed_locations_3)
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
BOOST_REQUIRE_EQUAL(2, result->statements.size()); BOOST_REQUIRE_EQUAL(2, result->statements.size());
CHECK_LOCATION(result->debugData->location, "source1", 23, 45); CHECK_LOCATION(result->debugData->originLocation, "source1", 23, 45);
BOOST_REQUIRE(holds_alternative<Block>(result->statements.at(0))); BOOST_REQUIRE(holds_alternative<Block>(result->statements.at(0)));
Block const& innerBlock = get<Block>(result->statements.at(0)); Block const& innerBlock = get<Block>(result->statements.at(0));
CHECK_LOCATION(innerBlock.debugData->location, "source1", 23, 45); CHECK_LOCATION(innerBlock.debugData->originLocation, "source1", 23, 45);
BOOST_REQUIRE_EQUAL(1, innerBlock.statements.size()); BOOST_REQUIRE_EQUAL(1, innerBlock.statements.size());
BOOST_REQUIRE(holds_alternative<ExpressionStatement>(result->statements.at(1))); BOOST_REQUIRE(holds_alternative<ExpressionStatement>(result->statements.at(1)));
ExpressionStatement const& sstoreStmt = get<ExpressionStatement>(innerBlock.statements.at(0)); ExpressionStatement const& sstoreStmt = get<ExpressionStatement>(innerBlock.statements.at(0));
BOOST_REQUIRE(holds_alternative<FunctionCall>(sstoreStmt.expression)); BOOST_REQUIRE(holds_alternative<FunctionCall>(sstoreStmt.expression));
FunctionCall const& sstoreCall = get<FunctionCall>(sstoreStmt.expression); FunctionCall const& sstoreCall = get<FunctionCall>(sstoreStmt.expression);
CHECK_LOCATION(sstoreCall.debugData->location, "source1", 23, 45); CHECK_LOCATION(sstoreCall.debugData->originLocation, "source1", 23, 45);
BOOST_REQUIRE(holds_alternative<ExpressionStatement>(result->statements.at(1))); BOOST_REQUIRE(holds_alternative<ExpressionStatement>(result->statements.at(1)));
ExpressionStatement mstoreStmt = get<ExpressionStatement>(result->statements.at(1)); ExpressionStatement mstoreStmt = get<ExpressionStatement>(result->statements.at(1));
BOOST_REQUIRE(holds_alternative<FunctionCall>(mstoreStmt.expression)); BOOST_REQUIRE(holds_alternative<FunctionCall>(mstoreStmt.expression));
FunctionCall const& mstoreCall = get<FunctionCall>(mstoreStmt.expression); FunctionCall const& mstoreCall = get<FunctionCall>(mstoreStmt.expression);
CHECK_LOCATION(mstoreCall.debugData->location, "source0", 420, 680); CHECK_LOCATION(mstoreCall.debugData->originLocation, "source0", 420, 680);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_comments_after_valid) BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_comments_after_valid)
@ -499,11 +499,11 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_comments_after_valid)
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
BOOST_REQUIRE_EQUAL(1, result->statements.size()); BOOST_REQUIRE_EQUAL(1, result->statements.size());
CHECK_LOCATION(result->debugData->location, "source1", 23, 45); CHECK_LOCATION(result->debugData->originLocation, "source1", 23, 45);
BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0))); BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0)));
VariableDeclaration const& varDecl = get<VariableDeclaration>(result->statements.at(0)); VariableDeclaration const& varDecl = get<VariableDeclaration>(result->statements.at(0));
CHECK_LOCATION(varDecl.debugData->location, "source0", 420, 680); CHECK_LOCATION(varDecl.debugData->originLocation, "source0", 420, 680);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_suffix) BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_suffix)
@ -520,7 +520,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_suffix)
BOOST_REQUIRE(errorList.size() == 1); BOOST_REQUIRE(errorList.size() == 1);
BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError);
BOOST_TEST(errorList[0]->errorId() == 8387_error); BOOST_TEST(errorList[0]->errorId() == 8387_error);
CHECK_LOCATION(result->debugData->location, "", -1, -1); CHECK_LOCATION(result->debugData->originLocation, "", -1, -1);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_prefix) BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_prefix)
@ -534,7 +534,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_invalid_prefix)
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
CHECK_LOCATION(result->debugData->location, "", -1, -1); CHECK_LOCATION(result->debugData->originLocation, "", -1, -1);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_unspecified) BOOST_AUTO_TEST_CASE(customSourceLocations_unspecified)
@ -548,7 +548,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_unspecified)
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
CHECK_LOCATION(result->debugData->location, "", -1, -1); CHECK_LOCATION(result->debugData->originLocation, "", -1, -1);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_non_integer) BOOST_AUTO_TEST_CASE(customSourceLocations_non_integer)
@ -565,7 +565,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_non_integer)
BOOST_REQUIRE(errorList.size() == 1); BOOST_REQUIRE(errorList.size() == 1);
BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError);
BOOST_TEST(errorList[0]->errorId() == 8387_error); BOOST_TEST(errorList[0]->errorId() == 8387_error);
CHECK_LOCATION(result->debugData->location, "", -1, -1); CHECK_LOCATION(result->debugData->originLocation, "", -1, -1);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_bad_integer) BOOST_AUTO_TEST_CASE(customSourceLocations_bad_integer)
@ -582,7 +582,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_bad_integer)
BOOST_REQUIRE(errorList.size() == 1); BOOST_REQUIRE(errorList.size() == 1);
BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError);
BOOST_TEST(errorList[0]->errorId() == 6367_error); BOOST_TEST(errorList[0]->errorId() == 6367_error);
CHECK_LOCATION(result->debugData->location, "", -1, -1); CHECK_LOCATION(result->debugData->originLocation, "", -1, -1);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_ensure_last_match) BOOST_AUTO_TEST_CASE(customSourceLocations_ensure_last_match)
@ -604,7 +604,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_ensure_last_match)
VariableDeclaration const& varDecl = get<VariableDeclaration>(result->statements.at(0)); VariableDeclaration const& varDecl = get<VariableDeclaration>(result->statements.at(0));
// Ensure the latest @src per documentation-comment is used (0:30:40). // Ensure the latest @src per documentation-comment is used (0:30:40).
CHECK_LOCATION(varDecl.debugData->location, "source0", 30, 40); CHECK_LOCATION(varDecl.debugData->originLocation, "source0", 30, 40);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_no_whitespace) BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_no_whitespace)
@ -621,7 +621,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_no_whitespace)
BOOST_REQUIRE(errorList.size() == 1); BOOST_REQUIRE(errorList.size() == 1);
BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError);
BOOST_TEST(errorList[0]->errorId() == 8387_error); BOOST_TEST(errorList[0]->errorId() == 8387_error);
CHECK_LOCATION(result->debugData->location, "", -1, -1); CHECK_LOCATION(result->debugData->originLocation, "", -1, -1);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_separated_with_single_space) BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_separated_with_single_space)
@ -635,7 +635,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_separated_with_single_s
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
CHECK_LOCATION(result->debugData->location, "source1", 333, 444); CHECK_LOCATION(result->debugData->originLocation, "source1", 333, 444);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_leading_trailing_whitespace) BOOST_AUTO_TEST_CASE(customSourceLocations_leading_trailing_whitespace)
@ -646,7 +646,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_leading_trailing_whitespace)
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
CHECK_LOCATION(result->debugData->location, "source0", 111, 222); CHECK_LOCATION(result->debugData->originLocation, "source0", 111, 222);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_reference_original_sloc) BOOST_AUTO_TEST_CASE(customSourceLocations_reference_original_sloc)
@ -667,7 +667,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_reference_original_sloc)
VariableDeclaration const& varDecl = get<VariableDeclaration>(result->statements.at(0)); VariableDeclaration const& varDecl = get<VariableDeclaration>(result->statements.at(0));
// -1 points to original source code, which in this case is `"source0"` (which is also // -1 points to original source code, which in this case is `"source0"` (which is also
CHECK_LOCATION(varDecl.debugData->location, "", 10, 20); CHECK_LOCATION(varDecl.debugData->originLocation, "", 10, 20);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets) BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets)
@ -689,14 +689,14 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets)
BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0))); BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0)));
VariableDeclaration const& varX = get<VariableDeclaration>(result->statements.at(0)); VariableDeclaration const& varX = get<VariableDeclaration>(result->statements.at(0));
CHECK_LOCATION(varX.debugData->location, "source0", 149, 156); CHECK_LOCATION(varX.debugData->originLocation, "source0", 149, 156);
BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(1))); BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(1)));
VariableDeclaration const& varY = get<VariableDeclaration>(result->statements.at(1)); VariableDeclaration const& varY = get<VariableDeclaration>(result->statements.at(1));
BOOST_REQUIRE(!!varY.value); BOOST_REQUIRE(!!varY.value);
BOOST_REQUIRE(holds_alternative<Literal>(*varY.value)); BOOST_REQUIRE(holds_alternative<Literal>(*varY.value));
Literal const& literal128 = get<Literal>(*varY.value); Literal const& literal128 = get<Literal>(*varY.value);
CHECK_LOCATION(literal128.debugData->location, "source1", 96, 165); CHECK_LOCATION(literal128.debugData->originLocation, "source1", 96, 165);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_empty_snippet) BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_empty_snippet)
@ -710,7 +710,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_empty_snippet)
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
CHECK_LOCATION(result->debugData->location, "source0", 111, 222); CHECK_LOCATION(result->debugData->originLocation, "source0", 111, 222);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_before_snippet) BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_before_snippet)
@ -727,7 +727,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_befo
BOOST_REQUIRE(errorList.size() == 1); BOOST_REQUIRE(errorList.size() == 1);
BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError);
BOOST_TEST(errorList[0]->errorId() == 8387_error); BOOST_TEST(errorList[0]->errorId() == 8387_error);
CHECK_LOCATION(result->debugData->location, "", -1, -1); CHECK_LOCATION(result->debugData->originLocation, "", -1, -1);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_after_snippet) BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_after_snippet)
@ -741,7 +741,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_no_whitespace_afte
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
CHECK_LOCATION(result->debugData->location, "source0", 111, 222); CHECK_LOCATION(result->debugData->originLocation, "source0", 111, 222);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_no_whitespace) BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_no_whitespace)
@ -755,7 +755,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_no_whites
EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{}); EVMDialectTyped const& dialect = EVMDialectTyped::instance(EVMVersion{});
shared_ptr<Block> result = parse(sourceText, dialect, reporter); shared_ptr<Block> result = parse(sourceText, dialect, reporter);
BOOST_REQUIRE(!!result && errorList.size() == 0); BOOST_REQUIRE(!!result && errorList.size() == 0);
CHECK_LOCATION(result->debugData->location, "source1", 333, 444); CHECK_LOCATION(result->debugData->originLocation, "source1", 333, 444);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_unterminated_quote) BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_unterminated_quote)
@ -772,7 +772,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_two_locations_with_snippets_untermina
BOOST_REQUIRE(errorList.size() == 1); BOOST_REQUIRE(errorList.size() == 1);
BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError);
BOOST_TEST(errorList[0]->errorId() == 1544_error); BOOST_TEST(errorList[0]->errorId() == 1544_error);
CHECK_LOCATION(result->debugData->location, "", -1, -1); CHECK_LOCATION(result->debugData->originLocation, "", -1, -1);
} }
BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_with_nested_locations) BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_with_nested_locations)
@ -794,14 +794,14 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_with_code_snippets_with_nested_locati
BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0))); BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0)));
VariableDeclaration const& varX = get<VariableDeclaration>(result->statements.at(0)); VariableDeclaration const& varX = get<VariableDeclaration>(result->statements.at(0));
CHECK_LOCATION(varX.debugData->location, "source0", 149, 156); CHECK_LOCATION(varX.debugData->originLocation, "source0", 149, 156);
BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(1))); BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(1)));
VariableDeclaration const& varY = get<VariableDeclaration>(result->statements.at(1)); VariableDeclaration const& varY = get<VariableDeclaration>(result->statements.at(1));
BOOST_REQUIRE(!!varY.value); BOOST_REQUIRE(!!varY.value);
BOOST_REQUIRE(holds_alternative<Literal>(*varY.value)); BOOST_REQUIRE(holds_alternative<Literal>(*varY.value));
Literal const& literal128 = get<Literal>(*varY.value); Literal const& literal128 = get<Literal>(*varY.value);
CHECK_LOCATION(literal128.debugData->location, "source1", 96, 165); CHECK_LOCATION(literal128.debugData->originLocation, "source1", 96, 165);
} }
BOOST_AUTO_TEST_CASE(astid) BOOST_AUTO_TEST_CASE(astid)
@ -876,7 +876,7 @@ BOOST_AUTO_TEST_CASE(astid_invalid)
BOOST_REQUIRE(errorList.size() == 1); BOOST_REQUIRE(errorList.size() == 1);
BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError); BOOST_TEST(errorList[0]->type() == Error::Type::SyntaxError);
BOOST_TEST(errorList[0]->errorId() == 1749_error); BOOST_TEST(errorList[0]->errorId() == 1749_error);
CHECK_LOCATION(result->debugData->location, "", -1, -1); CHECK_LOCATION(result->debugData->originLocation, "", -1, -1);
} }
BOOST_AUTO_TEST_CASE(astid_too_large) BOOST_AUTO_TEST_CASE(astid_too_large)
@ -948,7 +948,7 @@ BOOST_AUTO_TEST_CASE(customSourceLocations_multiple_src_tags_on_one_line)
BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0))); BOOST_REQUIRE(holds_alternative<VariableDeclaration>(result->statements.at(0)));
VariableDeclaration const& varX = get<VariableDeclaration>(result->statements.at(0)); VariableDeclaration const& varX = get<VariableDeclaration>(result->statements.at(0));
CHECK_LOCATION(varX.debugData->location, "source1", 4, 5); CHECK_LOCATION(varX.debugData->originLocation, "source1", 4, 5);
} }
BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE_END()

View File

@ -0,0 +1,9 @@
/// @use-src 0:"input.sol"
object "C" {
code {
/// @src 0:0:0
calldataload(0)
}
}
// ----
// TypeError 3083: (82-97): Top-level expressions are not supposed to return values (this expression returns 1 value). Use ``pop()`` or assign them.

View File

@ -0,0 +1,9 @@
/// @use-src 0:"input.sol"
object "C" {
code {
1
}
}
// ----
// ParserError 6913: (65-66): Call or assignment expected.
// ParserError 2314: (67-68): Expected end of source but got '}'

View File

@ -0,0 +1,8 @@
/// @use-src 0:"input.sol"
object "C" {
code {
let x, y := 1
}
}
// ----
// DeclarationError 3812: (59-72): Variable count mismatch for declaration of "x, y": 2 variables and 1 values.

View File

@ -0,0 +1,11 @@
/// @use-src 0:"input.sol"
object "C" {
code {
/// @src 0:0:0
function g() {
function g() {}
}
}
}
// ----
// DeclarationError 6052: (109-124): Function name g already taken in this scope.