mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Replaced code for assigning scopes with the class Scoper
This commit is contained in:
parent
c9ed116621
commit
a4aa2639d0
@ -30,7 +30,6 @@
|
||||
|
||||
#include <libsolutil/CommonData.h>
|
||||
|
||||
#include <boost/range/adaptor/reversed.hpp>
|
||||
#include <boost/range/algorithm_ext/erase.hpp>
|
||||
#include <variant>
|
||||
|
||||
@ -104,16 +103,14 @@ void DataFlowAnalyzer::operator()(Assignment& _assignment)
|
||||
|
||||
void DataFlowAnalyzer::operator()(VariableDeclaration& _varDecl)
|
||||
{
|
||||
if (_varDecl.value)
|
||||
clearKnowledgeIfInvalidated(*_varDecl.value);
|
||||
|
||||
Scoper::operator()(_varDecl);
|
||||
|
||||
set<YulString> names;
|
||||
for (auto const& var: _varDecl.variables)
|
||||
names.emplace(var.name);
|
||||
m_variableScopes.back().variables += names;
|
||||
|
||||
if (_varDecl.value)
|
||||
{
|
||||
clearKnowledgeIfInvalidated(*_varDecl.value);
|
||||
visit(*_varDecl.value);
|
||||
}
|
||||
|
||||
handleAssignment(names, _varDecl.value.get(), true);
|
||||
}
|
||||
@ -171,22 +168,15 @@ void DataFlowAnalyzer::operator()(FunctionDefinition& _fun)
|
||||
swap(m_references, references);
|
||||
swap(m_storage, storage);
|
||||
swap(m_memory, memory);
|
||||
pushScope(true);
|
||||
|
||||
for (auto const& parameter: _fun.parameters)
|
||||
m_variableScopes.back().variables.emplace(parameter.name);
|
||||
for (auto const& var: _fun.returnVariables)
|
||||
{
|
||||
m_variableScopes.back().variables.emplace(var.name);
|
||||
handleAssignment({var.name}, nullptr, true);
|
||||
}
|
||||
ASTModifier::operator()(_fun);
|
||||
|
||||
Scoper::operator()(_fun);
|
||||
|
||||
// Note that the contents of return variables, storage and memory at this point
|
||||
// might be incorrect due to the fact that the DataFlowAnalyzer ignores the ``leave``
|
||||
// statement.
|
||||
|
||||
popScope();
|
||||
swap(m_value, value);
|
||||
swap(m_loopDepth, loopDepth);
|
||||
swap(m_references, references);
|
||||
@ -228,14 +218,6 @@ void DataFlowAnalyzer::operator()(ForLoop& _for)
|
||||
--m_loopDepth;
|
||||
}
|
||||
|
||||
void DataFlowAnalyzer::operator()(Block& _block)
|
||||
{
|
||||
size_t numScopes = m_variableScopes.size();
|
||||
pushScope(false);
|
||||
ASTModifier::operator()(_block);
|
||||
popScope();
|
||||
assertThrow(numScopes == m_variableScopes.size(), OptimizerException, "");
|
||||
}
|
||||
|
||||
void DataFlowAnalyzer::handleAssignment(set<YulString> const& _variables, Expression* _value, bool _isDeclaration)
|
||||
{
|
||||
@ -291,11 +273,6 @@ void DataFlowAnalyzer::handleAssignment(set<YulString> const& _variables, Expres
|
||||
}
|
||||
}
|
||||
|
||||
void DataFlowAnalyzer::pushScope(bool _functionScope)
|
||||
{
|
||||
m_variableScopes.emplace_back(_functionScope);
|
||||
}
|
||||
|
||||
void DataFlowAnalyzer::popScope()
|
||||
{
|
||||
clearValues(std::move(m_variableScopes.back().variables));
|
||||
@ -396,18 +373,6 @@ void DataFlowAnalyzer::joinKnowledgeHelper(
|
||||
_this.eraseKey(key);
|
||||
}
|
||||
|
||||
bool DataFlowAnalyzer::inScope(YulString _variableName) const
|
||||
{
|
||||
for (auto const& scope: m_variableScopes | boost::adaptors::reversed)
|
||||
{
|
||||
if (scope.variables.count(_variableName))
|
||||
return true;
|
||||
if (scope.isFunction)
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::optional<pair<YulString, YulString>> DataFlowAnalyzer::isSimpleStore(
|
||||
StoreLoadLocation _location,
|
||||
ExpressionStatement const& _statement
|
||||
@ -432,4 +397,3 @@ std::optional<YulString> DataFlowAnalyzer::isSimpleLoad(
|
||||
return key->name;
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <libyul/optimiser/Scoper.h>
|
||||
#include <libyul/optimiser/ASTWalker.h>
|
||||
#include <libyul/optimiser/KnowledgeBase.h>
|
||||
#include <libyul/YulString.h>
|
||||
@ -76,7 +77,7 @@ struct AssignedValue
|
||||
*
|
||||
* Prerequisite: Disambiguator, ForLoopInitRewriter.
|
||||
*/
|
||||
class DataFlowAnalyzer: public ASTModifier
|
||||
class DataFlowAnalyzer: public Scoper
|
||||
{
|
||||
public:
|
||||
/// @param _functionSideEffects
|
||||
@ -96,17 +97,13 @@ public:
|
||||
void operator()(Switch& _switch) override;
|
||||
void operator()(FunctionDefinition&) override;
|
||||
void operator()(ForLoop&) override;
|
||||
void operator()(Block& _block) override;
|
||||
|
||||
protected:
|
||||
/// Registers the assignment.
|
||||
void handleAssignment(std::set<YulString> const& _names, Expression* _value, bool _isDeclaration);
|
||||
|
||||
/// Creates a new inner scope.
|
||||
void pushScope(bool _functionScope);
|
||||
|
||||
/// Removes the innermost scope and clears all variables in it.
|
||||
void popScope();
|
||||
void popScope() override;
|
||||
|
||||
/// Clears information about the values assigned to the given variables,
|
||||
/// for example at points where control flow is merged.
|
||||
@ -133,9 +130,6 @@ protected:
|
||||
InvertibleMap<YulString, YulString> const& _olderData
|
||||
);
|
||||
|
||||
/// Returns true iff the variable is in scope.
|
||||
bool inScope(YulString _variableName) const;
|
||||
|
||||
enum class StoreLoadLocation {
|
||||
Memory = 0,
|
||||
Storage = 1,
|
||||
@ -178,17 +172,9 @@ protected:
|
||||
/// Current nesting depth of loops.
|
||||
size_t m_loopDepth{0};
|
||||
|
||||
struct Scope
|
||||
{
|
||||
explicit Scope(bool _isFunction): isFunction(_isFunction) {}
|
||||
std::set<YulString> variables;
|
||||
bool isFunction;
|
||||
};
|
||||
/// Special expression whose address will be used in m_value.
|
||||
/// YulString does not need to be reset because DataFlowAnalyzer is short-lived.
|
||||
Expression const m_zero{Literal{{}, LiteralKind::Number, YulString{"0"}, {}}};
|
||||
/// List of scopes.
|
||||
std::vector<Scope> m_variableScopes;
|
||||
};
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user