[Yul] Fix registration of functions in scopes.

This commit is contained in:
chriseth 2019-04-02 23:19:23 +02:00
parent d20b3c9f9f
commit 054c16aa05
2 changed files with 26 additions and 21 deletions

View File

@ -74,28 +74,13 @@ bool ScopeFiller::operator()(VariableDeclaration const& _varDecl)
bool ScopeFiller::operator()(FunctionDefinition const& _funDef) bool ScopeFiller::operator()(FunctionDefinition const& _funDef)
{ {
bool success = true;
vector<Scope::YulType> arguments;
for (auto const& _argument: _funDef.parameters)
arguments.emplace_back(_argument.type.str());
vector<Scope::YulType> returns;
for (auto const& _return: _funDef.returnVariables)
returns.emplace_back(_return.type.str());
if (!m_currentScope->registerFunction(_funDef.name, arguments, returns))
{
//@TODO secondary location
m_errorReporter.declarationError(
_funDef.location,
"Function name " + _funDef.name.str() + " already taken in this scope."
);
success = false;
}
auto virtualBlock = m_info.virtualBlocks[&_funDef] = make_shared<Block>(); auto virtualBlock = m_info.virtualBlocks[&_funDef] = make_shared<Block>();
Scope& varScope = scope(virtualBlock.get()); Scope& varScope = scope(virtualBlock.get());
varScope.superScope = m_currentScope; varScope.superScope = m_currentScope;
m_currentScope = &varScope; m_currentScope = &varScope;
varScope.functionScope = true; varScope.functionScope = true;
bool success = true;
for (auto const& var: _funDef.parameters + _funDef.returnVariables) for (auto const& var: _funDef.parameters + _funDef.returnVariables)
if (!registerVariable(var, _funDef.location, varScope)) if (!registerVariable(var, _funDef.location, varScope))
success = false; success = false;
@ -153,10 +138,9 @@ bool ScopeFiller::operator()(Block const& _block)
// an entry in the scope according to their visibility. // an entry in the scope according to their visibility.
for (auto const& s: _block.statements) for (auto const& s: _block.statements)
if (s.type() == typeid(FunctionDefinition)) if (s.type() == typeid(FunctionDefinition))
if (!boost::apply_visitor(*this, s)) if (!registerFunction(boost::get<FunctionDefinition>(s)))
success = false; success = false;
for (auto const& s: _block.statements) for (auto const& s: _block.statements)
if (s.type() != typeid(FunctionDefinition))
if (!boost::apply_visitor(*this, s)) if (!boost::apply_visitor(*this, s))
success = false; success = false;
@ -178,6 +162,26 @@ bool ScopeFiller::registerVariable(TypedName const& _name, SourceLocation const&
return true; return true;
} }
bool ScopeFiller::registerFunction(FunctionDefinition const& _funDef)
{
vector<Scope::YulType> arguments;
for (auto const& _argument: _funDef.parameters)
arguments.emplace_back(_argument.type.str());
vector<Scope::YulType> returns;
for (auto const& _return: _funDef.returnVariables)
returns.emplace_back(_return.type.str());
if (!m_currentScope->registerFunction(_funDef.name, arguments, returns))
{
//@TODO secondary location
m_errorReporter.declarationError(
_funDef.location,
"Function name " + _funDef.name.str() + " already taken in this scope."
);
return false;
}
return true;
}
Scope& ScopeFiller::scope(Block const* _block) Scope& ScopeFiller::scope(Block const* _block)
{ {
auto& scope = m_info.scopes[_block]; auto& scope = m_info.scopes[_block];

View File

@ -73,6 +73,7 @@ private:
langutil::SourceLocation const& _location, langutil::SourceLocation const& _location,
Scope& _scope Scope& _scope
); );
bool registerFunction(FunctionDefinition const& _funDef);
Scope& scope(Block const* _block); Scope& scope(Block const* _block);