Separate DebugData fields for Solidity and Yul source locations

This commit is contained in:
Kamil Śliwak
2021-09-22 13:11:39 +02:00
parent 9c1d40debf
commit ce4420f857
21 changed files with 281 additions and 242 deletions
+3 -3
View File
@@ -409,7 +409,7 @@ bool ControlFlowBuilder::visit(InlineAssembly const& _inlineAssembly)
void ControlFlowBuilder::visit(yul::Statement const& _statement)
{
solAssert(m_currentNode && m_inlineAssembly, "");
m_currentNode->location = langutil::SourceLocation::smallestCovering(m_currentNode->location, locationOf(_statement));
m_currentNode->location = langutil::SourceLocation::smallestCovering(m_currentNode->location, nativeLocationOf(_statement));
ASTWalker::visit(_statement);
}
@@ -501,7 +501,7 @@ void ControlFlowBuilder::operator()(yul::Identifier const& _identifier)
m_currentNode->variableOccurrences.emplace_back(
*declaration,
VariableOccurrence::Kind::Access,
_identifier.debugData->location
nativeLocationOf(_identifier)
);
}
}
@@ -517,7 +517,7 @@ void ControlFlowBuilder::operator()(yul::Assignment const& _assignment)
m_currentNode->variableOccurrences.emplace_back(
*declaration,
VariableOccurrence::Kind::Assignment,
variable.debugData->location
nativeLocationOf(variable)
);
}
+7 -7
View File
@@ -201,9 +201,9 @@ bool ReferencesResolver::visit(Return const& _return)
void ReferencesResolver::operator()(yul::FunctionDefinition const& _function)
{
validateYulIdentifierName(_function.name, _function.debugData->location);
validateYulIdentifierName(_function.name, nativeLocationOf(_function));
for (yul::TypedName const& varName: _function.parameters + _function.returnVariables)
validateYulIdentifierName(varName.name, varName.debugData->location);
validateYulIdentifierName(varName.name, nativeLocationOf(varName));
bool wasInsideFunction = m_yulInsideFunction;
m_yulInsideFunction = true;
@@ -238,7 +238,7 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
{
m_errorReporter.declarationError(
4718_error,
_identifier.debugData->location,
nativeLocationOf(_identifier),
"Multiple matching identifiers. Resolving overloaded identifiers is not supported."
);
return;
@@ -251,7 +251,7 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
)
m_errorReporter.declarationError(
9467_error,
_identifier.debugData->location,
nativeLocationOf(_identifier),
"Identifier not found. Use \".slot\" and \".offset\" to access storage variables."
);
return;
@@ -261,7 +261,7 @@ void ReferencesResolver::operator()(yul::Identifier const& _identifier)
{
m_errorReporter.declarationError(
6578_error,
_identifier.debugData->location,
nativeLocationOf(_identifier),
"Cannot access local Solidity variables from inside an inline assembly function."
);
return;
@@ -275,7 +275,7 @@ void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)
{
for (auto const& identifier: _varDecl.variables)
{
validateYulIdentifierName(identifier.name, identifier.debugData->location);
validateYulIdentifierName(identifier.name, nativeLocationOf(identifier));
if (
@@ -289,7 +289,7 @@ void ReferencesResolver::operator()(yul::VariableDeclaration const& _varDecl)
if (!ssl.infos.empty())
m_errorReporter.declarationError(
3859_error,
identifier.debugData->location,
nativeLocationOf(identifier),
ssl,
"This declaration shadows a declaration outside the inline assembly block."
);
+20 -20
View File
@@ -772,7 +772,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
solAssert(var->type(), "Expected variable type!");
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;
}
if (var->isConstant())
@@ -781,7 +781,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{
m_errorReporter.typeError(
3558_error,
_identifier.debugData->location,
nativeLocationOf(_identifier),
"Constant variable is circular."
);
return false;
@@ -791,24 +791,24 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
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;
}
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;
}
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;
}
else if (var && var->value() && !var->value()->annotation().type && !dynamic_cast<Literal const*>(var->value().get()))
{
m_errorReporter.typeError(
2249_error,
_identifier.debugData->location,
nativeLocationOf(_identifier),
"Constant variables with non-literal values cannot be forward referenced from inline assembly."
);
return false;
@@ -818,7 +818,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
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;
}
}
@@ -833,19 +833,19 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{
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;
}
else if (_context == yul::IdentifierContext::LValue)
{
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;
}
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;
}
}
@@ -857,13 +857,13 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{
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;
}
}
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;
}
}
@@ -871,14 +871,14 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{
m_errorReporter.typeError(
1408_error,
_identifier.debugData->location,
nativeLocationOf(_identifier),
"Only local variables are supported. To access storage variables, use the \".slot\" and \".offset\" suffixes."
);
return false;
}
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;
}
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());
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
{
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;
}
}
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;
}
else if (_context == yul::IdentifierContext::LValue)
@@ -906,7 +906,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
if (dynamic_cast<MagicVariableDeclaration const*>(declaration))
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;
}
@@ -915,7 +915,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
solAssert(!!declaration->type(), "Type of declaration required but not yet determined.");
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;
}
else if (dynamic_cast<VariableDeclaration const*>(declaration))
@@ -925,7 +925,7 @@ bool TypeChecker::visit(InlineAssembly const& _inlineAssembly)
{
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;
}
}
+1 -1
View File
@@ -69,7 +69,7 @@ public:
if (yul::EVMDialect const* dialect = dynamic_cast<decltype(dialect)>(&m_dialect))
if (yul::BuiltinFunctionForEVM const* fun = dialect->builtin(_funCall.functionName.name))
if (fun->instruction)
checkInstruction(_funCall.debugData->location, *fun->instruction);
checkInstruction(nativeLocationOf(_funCall), *fun->instruction);
for (auto const& arg: _funCall.arguments)
std::visit(*this, arg);
+2 -2
View File
@@ -171,10 +171,10 @@ void ASTJsonConverter::appendExpressionAttributes(
_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);
tuple["src"] = sourceLocationToString(_info.first->debugData->location);
tuple["src"] = sourceLocationToString(nativeLocationOf(*_info.first));
tuple["declaration"] = idOrNull(_info.second.declaration);
tuple["isSlot"] = Json::Value(_info.second.suffix == "slot");
tuple["isOffset"] = Json::Value(_info.second.suffix == "offset");
+1 -1
View File
@@ -421,7 +421,7 @@ void CompilerContext::appendInlineAssembly(
if (stackDiff < 1 || stackDiff > 16)
BOOST_THROW_EXCEPTION(
StackTooDeepError() <<
errinfo_sourceLocation(_identifier.debugData->location) <<
errinfo_sourceLocation(nativeLocationOf(_identifier)) <<
util::errinfo_comment("Stack too deep (" + to_string(stackDiff) + "), try removing local variables.")
);
if (_context == yul::IdentifierContext::RValue)
+1 -1
View File
@@ -1326,7 +1326,7 @@ ASTPointer<InlineAssembly> Parser::parseInlineAssembly(ASTPointer<ASTString> con
if (block == nullptr)
BOOST_THROW_EXCEPTION(FatalError());
location.end = block->debugData->location.end;
location.end = nativeLocationOf(*block).end;
return make_shared<InlineAssembly>(nextID(), location, _docString, dialect, block);
}