Report locations of unimplemented features.

This commit is contained in:
chriseth 2020-09-11 12:02:10 +02:00
parent b1ccf73511
commit 930646ba2b
4 changed files with 128 additions and 51 deletions

View File

@ -164,7 +164,7 @@ string IRGenerator::generate(
string IRGenerator::generate(Block const& _block) string IRGenerator::generate(Block const& _block)
{ {
IRGeneratorForStatements generator(m_context, m_utils); IRGeneratorForStatements generator(m_context, m_utils);
_block.accept(generator); generator.generate(_block);
return generator.code(); return generator.code();
} }

View File

@ -38,6 +38,8 @@
#include <libyul/Dialect.h> #include <libyul/Dialect.h>
#include <libyul/optimiser/ASTCopier.h> #include <libyul/optimiser/ASTCopier.h>
#include <liblangutil/Exceptions.h>
#include <libsolutil/Whiskers.h> #include <libsolutil/Whiskers.h>
#include <libsolutil/StringUtils.h> #include <libsolutil/StringUtils.h>
#include <libsolutil/Keccak256.h> #include <libsolutil/Keccak256.h>
@ -152,8 +154,24 @@ string IRGeneratorForStatements::code() const
return m_code.str(); return m_code.str();
} }
void IRGeneratorForStatements::generate(Block const& _block)
{
try
{
_block.accept(*this);
}
catch (langutil::UnimplementedFeatureError const& _error)
{
if (!boost::get_error_info<langutil::errinfo_sourceLocation>(_error))
_error << langutil::errinfo_sourceLocation(m_currentLocation);
throw _error;
}
}
void IRGeneratorForStatements::initializeStateVar(VariableDeclaration const& _varDecl) void IRGeneratorForStatements::initializeStateVar(VariableDeclaration const& _varDecl)
{ {
try
{
setLocation(_varDecl); setLocation(_varDecl);
solAssert(_varDecl.immutable() || m_context.isStateVariable(_varDecl), "Must be immutable or a state variable."); solAssert(_varDecl.immutable() || m_context.isStateVariable(_varDecl), "Must be immutable or a state variable.");
@ -171,10 +189,19 @@ void IRGeneratorForStatements::initializeStateVar(VariableDeclaration const& _va
}}, }},
*_varDecl.value() *_varDecl.value()
); );
}
catch (langutil::UnimplementedFeatureError const& _error)
{
if (!boost::get_error_info<langutil::errinfo_sourceLocation>(_error))
_error << langutil::errinfo_sourceLocation(m_currentLocation);
throw _error;
}
} }
void IRGeneratorForStatements::initializeLocalVar(VariableDeclaration const& _varDecl) void IRGeneratorForStatements::initializeLocalVar(VariableDeclaration const& _varDecl)
{ {
try
{
setLocation(_varDecl); setLocation(_varDecl);
solAssert(m_context.isLocalVariable(_varDecl), "Must be a local variable."); solAssert(m_context.isLocalVariable(_varDecl), "Must be a local variable.");
@ -186,20 +213,38 @@ void IRGeneratorForStatements::initializeLocalVar(VariableDeclaration const& _va
IRVariable zero = zeroValue(*type); IRVariable zero = zeroValue(*type);
assign(m_context.localVariable(_varDecl), zero); assign(m_context.localVariable(_varDecl), zero);
}
catch (langutil::UnimplementedFeatureError const& _error)
{
if (!boost::get_error_info<langutil::errinfo_sourceLocation>(_error))
_error << langutil::errinfo_sourceLocation(m_currentLocation);
throw _error;
}
} }
IRVariable IRGeneratorForStatements::evaluateExpression(Expression const& _expression, Type const& _targetType) IRVariable IRGeneratorForStatements::evaluateExpression(Expression const& _expression, Type const& _targetType)
{ {
try
{
setLocation(_expression); setLocation(_expression);
_expression.accept(*this); _expression.accept(*this);
IRVariable variable{m_context.newYulVariable(), _targetType}; IRVariable variable{m_context.newYulVariable(), _targetType};
define(variable, _expression); define(variable, _expression);
return variable; return variable;
}
catch (langutil::UnimplementedFeatureError const& _error)
{
if (!boost::get_error_info<langutil::errinfo_sourceLocation>(_error))
_error << langutil::errinfo_sourceLocation(m_currentLocation);
throw _error;
}
} }
string IRGeneratorForStatements::constantValueFunction(VariableDeclaration const& _constant) string IRGeneratorForStatements::constantValueFunction(VariableDeclaration const& _constant)
{ {
try
{
setLocation(_constant); setLocation(_constant);
string functionName = IRNames::constantValueFunction(_constant); string functionName = IRNames::constantValueFunction(_constant);
@ -220,6 +265,13 @@ string IRGeneratorForStatements::constantValueFunction(VariableDeclaration const
return templ.render(); return templ.render();
}); });
}
catch (langutil::UnimplementedFeatureError const& _error)
{
if (!boost::get_error_info<langutil::errinfo_sourceLocation>(_error))
_error << langutil::errinfo_sourceLocation(m_currentLocation);
throw _error;
}
} }
void IRGeneratorForStatements::endVisit(VariableDeclarationStatement const& _varDeclStatement) void IRGeneratorForStatements::endVisit(VariableDeclarationStatement const& _varDeclStatement)

View File

@ -47,6 +47,9 @@ public:
std::string code() const; std::string code() const;
/// Generate the code for the statements in the block;
void generate(Block const& _block);
/// Generates code to initialize the given state variable. /// Generates code to initialize the given state variable.
void initializeStateVar(VariableDeclaration const& _varDecl); void initializeStateVar(VariableDeclaration const& _varDecl);
/// Generates code to initialize the given local variable. /// Generates code to initialize the given local variable.

View File

@ -524,6 +524,10 @@ bool CompilerStack::compile()
{ {
if (m_generateEvmBytecode) if (m_generateEvmBytecode)
compileContract(*contract, otherCompilers); compileContract(*contract, otherCompilers);
if (m_generateIR || m_generateEwasm)
generateIR(*contract);
if (m_generateEwasm)
generateEwasm(*contract);
} }
catch (Error const& _error) catch (Error const& _error)
{ {
@ -532,10 +536,28 @@ bool CompilerStack::compile()
m_errorReporter.error(_error.errorId(), _error.type(), SourceLocation(), _error.what()); m_errorReporter.error(_error.errorId(), _error.type(), SourceLocation(), _error.what());
return false; return false;
} }
if (m_generateIR || m_generateEwasm) catch (UnimplementedFeatureError const& _unimplementedError)
generateIR(*contract); {
if (m_generateEwasm) if (
generateEwasm(*contract); SourceLocation const* sourceLocation =
boost::get_error_info<langutil::errinfo_sourceLocation>(_unimplementedError)
)
{
string const* comment = _unimplementedError.comment();
m_errorReporter.error(
1834_error,
Error::Type::CodeGenerationError,
*sourceLocation,
"Unimplemented feature error" +
((comment && !comment->empty()) ? ": " + *comment : string{}) +
" in " +
_unimplementedError.lineInfo()
);
return false;
}
else
throw;
}
} }
m_stackState = CompilationSuccessful; m_stackState = CompilationSuccessful;
this->link(); this->link();