Introduce struct for scopes.

This commit is contained in:
chriseth 2018-02-05 18:02:32 +01:00
parent 773be40c19
commit 88a5d152d0
2 changed files with 17 additions and 11 deletions

View File

@ -51,7 +51,7 @@ void DataFlowAnalyzer::operator()(VariableDeclaration& _varDecl)
set<string> names; set<string> names;
for (auto const& var: _varDecl.variables) for (auto const& var: _varDecl.variables)
names.insert(var.name); names.insert(var.name);
m_variableScopes.back().first += names; m_variableScopes.back().variables += names;
if (_varDecl.value) if (_varDecl.value)
visit(*_varDecl.value); visit(*_varDecl.value);
handleAssignment(names, _varDecl.value.get()); handleAssignment(names, _varDecl.value.get());
@ -84,11 +84,11 @@ void DataFlowAnalyzer::operator()(Switch& _switch)
void DataFlowAnalyzer::operator()(FunctionDefinition& _fun) void DataFlowAnalyzer::operator()(FunctionDefinition& _fun)
{ {
m_variableScopes.push_back(make_pair(set<string>(), true)); m_variableScopes.emplace_back(true);
for (auto const& parameter: _fun.parameters) for (auto const& parameter: _fun.parameters)
m_variableScopes.back().first.insert(parameter.name); m_variableScopes.back().variables.insert(parameter.name);
for (auto const& var: _fun.returnVariables) for (auto const& var: _fun.returnVariables)
m_variableScopes.back().first.insert(var.name); m_variableScopes.back().variables.insert(var.name);
ASTModifier::operator()(_fun); ASTModifier::operator()(_fun);
m_variableScopes.pop_back(); m_variableScopes.pop_back();
} }
@ -96,7 +96,7 @@ void DataFlowAnalyzer::operator()(FunctionDefinition& _fun)
void DataFlowAnalyzer::operator()(ForLoop& _for) void DataFlowAnalyzer::operator()(ForLoop& _for)
{ {
// Special scope handling of the pre block. // Special scope handling of the pre block.
m_variableScopes.push_back(make_pair(set<string>(), false)); m_variableScopes.emplace_back(false);
for (auto& statement: _for.pre.statements) for (auto& statement: _for.pre.statements)
visit(statement); visit(statement);
@ -117,7 +117,7 @@ void DataFlowAnalyzer::operator()(ForLoop& _for)
void DataFlowAnalyzer::operator()(Block& _block) void DataFlowAnalyzer::operator()(Block& _block)
{ {
size_t numScopes = m_variableScopes.size(); size_t numScopes = m_variableScopes.size();
m_variableScopes.push_back(make_pair(set<string>(), false)); m_variableScopes.emplace_back(false);
ASTModifier::operator()(_block); ASTModifier::operator()(_block);
m_variableScopes.pop_back(); m_variableScopes.pop_back();
solAssert(numScopes == m_variableScopes.size(), ""); solAssert(numScopes == m_variableScopes.size(), "");
@ -186,9 +186,9 @@ bool DataFlowAnalyzer::inScope(string const& _variableName) const
{ {
for (auto const& scope: m_variableScopes | boost::adaptors::reversed) for (auto const& scope: m_variableScopes | boost::adaptors::reversed)
{ {
if (scope.first.count(_variableName)) if (scope.variables.count(_variableName))
return true; return true;
if (scope.second) if (scope.isFunction)
return false; return false;
} }
return false; return false;

View File

@ -69,9 +69,15 @@ protected:
std::map<std::string, std::set<std::string>> m_references; std::map<std::string, std::set<std::string>> m_references;
/// m_referencedBy[b].contains(a) <=> the current expression assigned to a references b /// m_referencedBy[b].contains(a) <=> the current expression assigned to a references b
std::map<std::string, std::set<std::string>> m_referencedBy; std::map<std::string, std::set<std::string>> m_referencedBy;
/// List of scopes, where each scope is a set of variables and a bool that tells
/// whether it is a function body (true) or not. struct Scope
std::vector<std::pair<std::set<std::string>, bool>> m_variableScopes; {
explicit Scope(bool _isFunction): isFunction(_isFunction) {}
std::set<std::string> variables;
bool isFunction;
};
/// List of scopes.
std::vector<Scope> m_variableScopes;
}; };
} }