diff options
author | Christian <c@ethdev.com> | 2014-12-01 22:22:45 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2014-12-02 00:33:21 +0800 |
commit | 9e91596c8d5683e79314fcd53a18e0e3df7b3390 (patch) | |
tree | 403740e7f56b4f6fc9d7b49b1c7383f5cdb99a5f | |
parent | 3fc2708d657525162567b663a07cf8cb5b1c59aa (diff) | |
download | dexon-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.h | 7 | ||||
-rw-r--r-- | DeclarationContainer.cpp (renamed from Scope.cpp) | 10 | ||||
-rw-r--r-- | DeclarationContainer.h (renamed from Scope.h) | 10 | ||||
-rw-r--r-- | NameAndTypeResolver.cpp | 19 | ||||
-rw-r--r-- | NameAndTypeResolver.h | 14 |
5 files changed, 33 insertions, 27 deletions
@@ -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; }; |