aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/analysis/NameAndTypeResolver.cpp
diff options
context:
space:
mode:
authorchriseth <chris@ethereum.org>2018-02-15 18:30:32 +0800
committerchriseth <chris@ethereum.org>2018-02-27 19:17:25 +0800
commit88a5c66f4a7efae6d78ce2e04144219656bb9da0 (patch)
treea2aaf6ea3dd359077ad3024b5938a061c665f439 /libsolidity/analysis/NameAndTypeResolver.cpp
parent6b9dda06f3d85344a70efb2f868760a0dde9dc45 (diff)
downloaddexon-solidity-88a5c66f4a7efae6d78ce2e04144219656bb9da0.tar
dexon-solidity-88a5c66f4a7efae6d78ce2e04144219656bb9da0.tar.gz
dexon-solidity-88a5c66f4a7efae6d78ce2e04144219656bb9da0.tar.bz2
dexon-solidity-88a5c66f4a7efae6d78ce2e04144219656bb9da0.tar.lz
dexon-solidity-88a5c66f4a7efae6d78ce2e04144219656bb9da0.tar.xz
dexon-solidity-88a5c66f4a7efae6d78ce2e04144219656bb9da0.tar.zst
dexon-solidity-88a5c66f4a7efae6d78ce2e04144219656bb9da0.zip
Only active variables at the point of their declaration.
Diffstat (limited to 'libsolidity/analysis/NameAndTypeResolver.cpp')
-rw-r--r--libsolidity/analysis/NameAndTypeResolver.cpp54
1 files changed, 34 insertions, 20 deletions
diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp
index 40021771..2f675135 100644
--- a/libsolidity/analysis/NameAndTypeResolver.cpp
+++ b/libsolidity/analysis/NameAndTypeResolver.cpp
@@ -50,12 +50,13 @@ NameAndTypeResolver::NameAndTypeResolver(
m_scopes[nullptr]->registerDeclaration(*declaration);
}
-bool NameAndTypeResolver::registerDeclarations(ASTNode& _sourceUnit, ASTNode const* _currentScope)
+bool NameAndTypeResolver::registerDeclarations(SourceUnit& _sourceUnit, ASTNode const* _currentScope)
{
+ bool useC99Scoping = _sourceUnit.annotation().experimentalFeatures.count(ExperimentalFeature::V050);
// The helper registers all declarations in m_scopes as a side-effect of its construction.
try
{
- DeclarationRegistrationHelper registrar(m_scopes, _sourceUnit, m_errorReporter, _currentScope);
+ DeclarationRegistrationHelper registrar(m_scopes, _sourceUnit, useC99Scoping, m_errorReporter, _currentScope);
}
catch (FatalError const&)
{
@@ -106,7 +107,7 @@ bool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, map<string, So
else
for (Declaration const* declaration: declarations)
if (!DeclarationRegistrationHelper::registerDeclaration(
- target, *declaration, alias.second.get(), &imp->location(), true, m_errorReporter
+ target, *declaration, alias.second.get(), &imp->location(), true, false, m_errorReporter
))
error = true;
}
@@ -114,7 +115,7 @@ bool NameAndTypeResolver::performImports(SourceUnit& _sourceUnit, map<string, So
for (auto const& nameAndDeclaration: scope->second->declarations())
for (auto const& declaration: nameAndDeclaration.second)
if (!DeclarationRegistrationHelper::registerDeclaration(
- target, *declaration, &nameAndDeclaration.first, &imp->location(), true, m_errorReporter
+ target, *declaration, &nameAndDeclaration.first, &imp->location(), true, false, m_errorReporter
))
error = true;
}
@@ -151,6 +152,12 @@ bool NameAndTypeResolver::updateDeclaration(Declaration const& _declaration)
return true;
}
+void NameAndTypeResolver::activateVariable(string const& _name)
+{
+ solAssert(m_currentScope, "");
+ m_currentScope->activateVariable(_name);
+}
+
vector<Declaration const*> NameAndTypeResolver::resolveName(ASTString const& _name, ASTNode const* _scope) const
{
auto iterator = m_scopes.find(_scope);
@@ -159,9 +166,9 @@ vector<Declaration const*> NameAndTypeResolver::resolveName(ASTString const& _na
return iterator->second->resolveName(_name, false);
}
-vector<Declaration const*> NameAndTypeResolver::nameFromCurrentScope(ASTString const& _name) const
+vector<Declaration const*> NameAndTypeResolver::nameFromCurrentScope(ASTString const& _name, bool _includeInvisibles) const
{
- return m_currentScope->resolveName(_name, true);
+ return m_currentScope->resolveName(_name, true, _includeInvisibles);
}
Declaration const* NameAndTypeResolver::pathFromCurrentScope(vector<ASTString> const& _path) const
@@ -229,7 +236,7 @@ void NameAndTypeResolver::warnVariablesNamedLikeInstructions()
for (auto const& instruction: c_instructions)
{
string const instructionName{boost::algorithm::to_lower_copy(instruction.first)};
- auto declarations = nameFromCurrentScope(instructionName);
+ auto declarations = nameFromCurrentScope(instructionName, true);
for (Declaration const* const declaration: declarations)
{
solAssert(!!declaration, "");
@@ -439,9 +446,11 @@ string NameAndTypeResolver::similarNameSuggestions(ASTString const& _name) const
DeclarationRegistrationHelper::DeclarationRegistrationHelper(
map<ASTNode const*, shared_ptr<DeclarationContainer>>& _scopes,
ASTNode& _astRoot,
+ bool _useC99Scoping,
ErrorReporter& _errorReporter,
ASTNode const* _currentScope
):
+ m_useC99Scoping(_useC99Scoping),
m_scopes(_scopes),
m_currentScope(_currentScope),
m_errorReporter(_errorReporter)
@@ -456,6 +465,7 @@ bool DeclarationRegistrationHelper::registerDeclaration(
string const* _name,
SourceLocation const* _errorLocation,
bool _warnOnShadow,
+ bool _inactive,
ErrorReporter& _errorReporter
)
{
@@ -465,10 +475,13 @@ bool DeclarationRegistrationHelper::registerDeclaration(
string name = _name ? *_name : _declaration.name();
Declaration const* shadowedDeclaration = nullptr;
if (_warnOnShadow && !name.empty() && _container.enclosingContainer())
- for (auto const* decl: _container.enclosingContainer()->resolveName(name, true))
+ for (auto const* decl: _container.enclosingContainer()->resolveName(name, true, true))
shadowedDeclaration = decl;
- if (!_container.registerDeclaration(_declaration, _name, !_declaration.isVisibleInContract()))
+ // We use "invisible" for both inactive variables in blocks and for members invisible in contracts.
+ // They cannot both be true at the same time.
+ solAssert(!(_inactive && !_declaration.isVisibleInContract()), "");
+ if (!_container.registerDeclaration(_declaration, _name, !_declaration.isVisibleInContract() || _inactive))
{
SourceLocation firstDeclarationLocation;
SourceLocation secondDeclarationLocation;
@@ -613,32 +626,28 @@ void DeclarationRegistrationHelper::endVisit(ModifierDefinition&)
bool DeclarationRegistrationHelper::visit(Block& _block)
{
_block.setScope(m_currentScope);
- // Enable C99-scoped variables.
- if (_block.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
+ if (m_useC99Scoping)
enterNewSubScope(_block);
return true;
}
-void DeclarationRegistrationHelper::endVisit(Block& _block)
+void DeclarationRegistrationHelper::endVisit(Block&)
{
- // Enable C99-scoped variables.
- if (_block.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
+ if (m_useC99Scoping)
closeCurrentScope();
}
bool DeclarationRegistrationHelper::visit(ForStatement& _for)
{
_for.setScope(m_currentScope);
- if (_for.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
- // TODO special scoping rules for the init statement - if it is a block, then it should
- // not open its own scope.
+ if (m_useC99Scoping)
enterNewSubScope(_for);
return true;
}
-void DeclarationRegistrationHelper::endVisit(ForStatement& _for)
+void DeclarationRegistrationHelper::endVisit(ForStatement&)
{
- if (_for.sourceUnit().annotation().experimentalFeatures.count(ExperimentalFeature::V050))
+ if (m_useC99Scoping)
closeCurrentScope();
}
@@ -704,7 +713,12 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio
if (fun->isConstructor())
warnAboutShadowing = false;
- registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, warnAboutShadowing, m_errorReporter);
+ // Register declaration as inactive if we are in block scope and C99 mode.
+ bool inactive =
+ m_useC99Scoping &&
+ (dynamic_cast<Block const*>(m_currentScope) || dynamic_cast<ForStatement const*>(m_currentScope));
+
+ registerDeclaration(*m_scopes[m_currentScope], _declaration, nullptr, nullptr, warnAboutShadowing, inactive, m_errorReporter);
_declaration.setScope(m_currentScope);
if (_opensScope)