aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2014-12-01 22:22:45 +0800
committerChristian <c@ethdev.com>2014-12-02 00:33:21 +0800
commit9e91596c8d5683e79314fcd53a18e0e3df7b3390 (patch)
tree403740e7f56b4f6fc9d7b49b1c7383f5cdb99a5f
parent3fc2708d657525162567b663a07cf8cb5b1c59aa (diff)
downloaddexon-solidity-9e91596c8d5683e79314fcd53a18e0e3df7b3390.tar
dexon-solidity-9e91596c8d5683e79314fcd53a18e0e3df7b3390.tar.gz
dexon-solidity-9e91596c8d5683e79314fcd53a18e0e3df7b3390.tar.bz2
dexon-solidity-9e91596c8d5683e79314fcd53a18e0e3df7b3390.tar.lz
dexon-solidity-9e91596c8d5683e79314fcd53a18e0e3df7b3390.tar.xz
dexon-solidity-9e91596c8d5683e79314fcd53a18e0e3df7b3390.tar.zst
dexon-solidity-9e91596c8d5683e79314fcd53a18e0e3df7b3390.zip
Save the scope for every declaration.
-rw-r--r--AST.h7
-rw-r--r--DeclarationContainer.cpp (renamed from Scope.cpp)10
-rw-r--r--DeclarationContainer.h (renamed from Scope.h)10
-rw-r--r--NameAndTypeResolver.cpp19
-rw-r--r--NameAndTypeResolver.h14
5 files changed, 33 insertions, 27 deletions
diff --git a/AST.h b/AST.h
index 81a12ad1..68b5c8b8 100644
--- a/AST.h
+++ b/AST.h
@@ -88,11 +88,16 @@ public:
Declaration(Location const& _location, ASTPointer<ASTString> const& _name):
ASTNode(_location), m_name(_name) {}
- /// Returns the declared name.
+ /// @returns the declared name.
ASTString const& getName() const { return *m_name; }
+ /// @returns the scope this declaration resides in. Can be nullptr if it is the global scope.
+ /// Available only after name and type resolution step.
+ Declaration* getScope() const { return m_scope; }
+ void setScope(Declaration* const& _scope) { m_scope = _scope; }
private:
ASTPointer<ASTString> m_name;
+ Declaration* m_scope;
};
/**
diff --git a/Scope.cpp b/DeclarationContainer.cpp
index 540c4120..6ea9c28c 100644
--- a/Scope.cpp
+++ b/DeclarationContainer.cpp
@@ -20,7 +20,7 @@
* Scope - object that holds declaration of names.
*/
-#include <libsolidity/Scope.h>
+#include <libsolidity/DeclarationContainer.h>
#include <libsolidity/AST.h>
namespace dev
@@ -28,7 +28,7 @@ namespace dev
namespace solidity
{
-bool Scope::registerDeclaration(Declaration& _declaration)
+bool DeclarationContainer::registerDeclaration(Declaration& _declaration)
{
if (m_declarations.find(_declaration.getName()) != m_declarations.end())
return false;
@@ -36,13 +36,13 @@ bool Scope::registerDeclaration(Declaration& _declaration)
return true;
}
-Declaration* Scope::resolveName(ASTString const& _name, bool _recursive) const
+Declaration* DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const
{
auto result = m_declarations.find(_name);
if (result != m_declarations.end())
return result->second;
- if (_recursive && m_enclosingScope)
- return m_enclosingScope->resolveName(_name, true);
+ if (_recursive && m_enclosingContainer)
+ return m_enclosingContainer->resolveName(_name, true);
return nullptr;
}
diff --git a/Scope.h b/DeclarationContainer.h
index 637c2d5c..db681289 100644
--- a/Scope.h
+++ b/DeclarationContainer.h
@@ -36,18 +36,20 @@ namespace solidity
* Container that stores mappings betwee names and declarations. It also contains a link to the
* enclosing scope.
*/
-class Scope
+class DeclarationContainer
{
public:
- explicit Scope(Scope* _enclosingScope = nullptr): m_enclosingScope(_enclosingScope) {}
+ explicit DeclarationContainer(Declaration* _enclosingDeclaration = nullptr, DeclarationContainer* _enclosingContainer = nullptr):
+ m_enclosingDeclaration(_enclosingDeclaration), m_enclosingContainer(_enclosingContainer) {}
/// Registers the declaration in the scope unless its name is already declared. Returns true iff
/// it was not yet declared.
bool registerDeclaration(Declaration& _declaration);
Declaration* resolveName(ASTString const& _name, bool _recursive = false) const;
- Scope* getEnclosingScope() const { return m_enclosingScope; }
+ Declaration* getEnclosingDeclaration() const { return m_enclosingDeclaration; }
private:
- Scope* m_enclosingScope;
+ Declaration* m_enclosingDeclaration;
+ DeclarationContainer* m_enclosingContainer;
std::map<ASTString, Declaration*> m_declarations;
};
diff --git a/NameAndTypeResolver.cpp b/NameAndTypeResolver.cpp
index 225f2a78..d473348b 100644
--- a/NameAndTypeResolver.cpp
+++ b/NameAndTypeResolver.cpp
@@ -78,9 +78,9 @@ Declaration* NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name
return m_currentScope->resolveName(_name, _recursive);
}
-DeclarationRegistrationHelper::DeclarationRegistrationHelper(map<ASTNode const*, Scope>& _scopes,
+DeclarationRegistrationHelper::DeclarationRegistrationHelper(map<ASTNode const*, DeclarationContainer>& _scopes,
ASTNode& _astRoot):
- m_scopes(_scopes), m_currentScope(&m_scopes[nullptr])
+ m_scopes(_scopes), m_currentScope(nullptr)
{
_astRoot.accept(*this);
}
@@ -135,31 +135,30 @@ bool DeclarationRegistrationHelper::visit(VariableDeclaration& _declaration)
return true;
}
-void DeclarationRegistrationHelper::enterNewSubScope(ASTNode& _node)
+void DeclarationRegistrationHelper::enterNewSubScope(Declaration& _declaration)
{
- map<ASTNode const*, Scope>::iterator iter;
+ map<ASTNode const*, DeclarationContainer>::iterator iter;
bool newlyAdded;
- tie(iter, newlyAdded) = m_scopes.emplace(&_node, Scope(m_currentScope));
+ tie(iter, newlyAdded) = m_scopes.emplace(&_declaration, DeclarationContainer(m_currentScope, &m_scopes[m_currentScope]));
if (asserts(newlyAdded))
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to add new scope."));
- m_currentScope = &iter->second;
+ m_currentScope = &_declaration;
}
void DeclarationRegistrationHelper::closeCurrentScope()
{
if (asserts(m_currentScope))
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Closed non-existing scope."));
- m_currentScope = m_currentScope->getEnclosingScope();
+ m_currentScope = m_scopes[m_currentScope].getEnclosingDeclaration();
}
void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaration, bool _opensScope)
{
- if (asserts(m_currentScope))
- BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Declaration registered without scope."));
- if (!m_currentScope->registerDeclaration(_declaration))
+ if (!m_scopes[m_currentScope].registerDeclaration(_declaration))
BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_declaration.getLocation())
<< errinfo_comment("Identifier already declared."));
//@todo the exception should also contain the location of the first declaration
+ _declaration.setScope(m_currentScope);
if (_opensScope)
enterNewSubScope(_declaration);
}
diff --git a/NameAndTypeResolver.h b/NameAndTypeResolver.h
index 64f3c89d..797eca60 100644
--- a/NameAndTypeResolver.h
+++ b/NameAndTypeResolver.h
@@ -25,7 +25,7 @@
#include <map>
#include <boost/noncopyable.hpp>
-#include <libsolidity/Scope.h>
+#include <libsolidity/DeclarationContainer.h>
#include <libsolidity/ASTVisitor.h>
namespace dev
@@ -61,9 +61,9 @@ private:
/// Maps nodes declaring a scope to scopes, i.e. ContractDefinition and FunctionDeclaration,
/// where nullptr denotes the global scope. Note that structs are not scope since they do
/// not contain code.
- std::map<ASTNode const*, Scope> m_scopes;
+ std::map<ASTNode const*, DeclarationContainer> m_scopes;
- Scope* m_currentScope;
+ DeclarationContainer* m_currentScope;
};
/**
@@ -73,7 +73,7 @@ private:
class DeclarationRegistrationHelper: private ASTVisitor
{
public:
- DeclarationRegistrationHelper(std::map<ASTNode const*, Scope>& _scopes, ASTNode& _astRoot);
+ DeclarationRegistrationHelper(std::map<ASTNode const*, DeclarationContainer>& _scopes, ASTNode& _astRoot);
private:
bool visit(ContractDefinition& _contract);
@@ -85,12 +85,12 @@ private:
void endVisit(VariableDefinition& _variableDefinition);
bool visit(VariableDeclaration& _declaration);
- void enterNewSubScope(ASTNode& _node);
+ void enterNewSubScope(Declaration& _declaration);
void closeCurrentScope();
void registerDeclaration(Declaration& _declaration, bool _opensScope);
- std::map<ASTNode const*, Scope>& m_scopes;
- Scope* m_currentScope;
+ std::map<ASTNode const*, DeclarationContainer>& m_scopes;
+ Declaration* m_currentScope;
FunctionDefinition* m_currentFunction;
};