mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Save the scope for every declaration.
This commit is contained in:
parent
3fc2708d65
commit
9e91596c8d
7
AST.h
7
AST.h
@ -88,11 +88,16 @@ public:
|
|||||||
Declaration(Location const& _location, ASTPointer<ASTString> const& _name):
|
Declaration(Location const& _location, ASTPointer<ASTString> const& _name):
|
||||||
ASTNode(_location), m_name(_name) {}
|
ASTNode(_location), m_name(_name) {}
|
||||||
|
|
||||||
/// Returns the declared name.
|
/// @returns the declared name.
|
||||||
ASTString const& getName() const { return *m_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:
|
private:
|
||||||
ASTPointer<ASTString> m_name;
|
ASTPointer<ASTString> m_name;
|
||||||
|
Declaration* m_scope;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
* Scope - object that holds declaration of names.
|
* Scope - object that holds declaration of names.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <libsolidity/Scope.h>
|
#include <libsolidity/DeclarationContainer.h>
|
||||||
#include <libsolidity/AST.h>
|
#include <libsolidity/AST.h>
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
@ -28,7 +28,7 @@ namespace dev
|
|||||||
namespace solidity
|
namespace solidity
|
||||||
{
|
{
|
||||||
|
|
||||||
bool Scope::registerDeclaration(Declaration& _declaration)
|
bool DeclarationContainer::registerDeclaration(Declaration& _declaration)
|
||||||
{
|
{
|
||||||
if (m_declarations.find(_declaration.getName()) != m_declarations.end())
|
if (m_declarations.find(_declaration.getName()) != m_declarations.end())
|
||||||
return false;
|
return false;
|
||||||
@ -36,13 +36,13 @@ bool Scope::registerDeclaration(Declaration& _declaration)
|
|||||||
return true;
|
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);
|
auto result = m_declarations.find(_name);
|
||||||
if (result != m_declarations.end())
|
if (result != m_declarations.end())
|
||||||
return result->second;
|
return result->second;
|
||||||
if (_recursive && m_enclosingScope)
|
if (_recursive && m_enclosingContainer)
|
||||||
return m_enclosingScope->resolveName(_name, true);
|
return m_enclosingContainer->resolveName(_name, true);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
@ -36,18 +36,20 @@ namespace solidity
|
|||||||
* Container that stores mappings betwee names and declarations. It also contains a link to the
|
* Container that stores mappings betwee names and declarations. It also contains a link to the
|
||||||
* enclosing scope.
|
* enclosing scope.
|
||||||
*/
|
*/
|
||||||
class Scope
|
class DeclarationContainer
|
||||||
{
|
{
|
||||||
public:
|
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
|
/// Registers the declaration in the scope unless its name is already declared. Returns true iff
|
||||||
/// it was not yet declared.
|
/// it was not yet declared.
|
||||||
bool registerDeclaration(Declaration& _declaration);
|
bool registerDeclaration(Declaration& _declaration);
|
||||||
Declaration* resolveName(ASTString const& _name, bool _recursive = false) const;
|
Declaration* resolveName(ASTString const& _name, bool _recursive = false) const;
|
||||||
Scope* getEnclosingScope() const { return m_enclosingScope; }
|
Declaration* getEnclosingDeclaration() const { return m_enclosingDeclaration; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Scope* m_enclosingScope;
|
Declaration* m_enclosingDeclaration;
|
||||||
|
DeclarationContainer* m_enclosingContainer;
|
||||||
std::map<ASTString, Declaration*> m_declarations;
|
std::map<ASTString, Declaration*> m_declarations;
|
||||||
};
|
};
|
||||||
|
|
@ -78,9 +78,9 @@ Declaration* NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name
|
|||||||
return m_currentScope->resolveName(_name, _recursive);
|
return m_currentScope->resolveName(_name, _recursive);
|
||||||
}
|
}
|
||||||
|
|
||||||
DeclarationRegistrationHelper::DeclarationRegistrationHelper(map<ASTNode const*, Scope>& _scopes,
|
DeclarationRegistrationHelper::DeclarationRegistrationHelper(map<ASTNode const*, DeclarationContainer>& _scopes,
|
||||||
ASTNode& _astRoot):
|
ASTNode& _astRoot):
|
||||||
m_scopes(_scopes), m_currentScope(&m_scopes[nullptr])
|
m_scopes(_scopes), m_currentScope(nullptr)
|
||||||
{
|
{
|
||||||
_astRoot.accept(*this);
|
_astRoot.accept(*this);
|
||||||
}
|
}
|
||||||
@ -135,31 +135,30 @@ bool DeclarationRegistrationHelper::visit(VariableDeclaration& _declaration)
|
|||||||
return true;
|
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;
|
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))
|
if (asserts(newlyAdded))
|
||||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to add new scope."));
|
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to add new scope."));
|
||||||
m_currentScope = &iter->second;
|
m_currentScope = &_declaration;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DeclarationRegistrationHelper::closeCurrentScope()
|
void DeclarationRegistrationHelper::closeCurrentScope()
|
||||||
{
|
{
|
||||||
if (asserts(m_currentScope))
|
if (asserts(m_currentScope))
|
||||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Closed non-existing scope."));
|
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)
|
void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaration, bool _opensScope)
|
||||||
{
|
{
|
||||||
if (asserts(m_currentScope))
|
if (!m_scopes[m_currentScope].registerDeclaration(_declaration))
|
||||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Declaration registered without scope."));
|
|
||||||
if (!m_currentScope->registerDeclaration(_declaration))
|
|
||||||
BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_declaration.getLocation())
|
BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_declaration.getLocation())
|
||||||
<< errinfo_comment("Identifier already declared."));
|
<< errinfo_comment("Identifier already declared."));
|
||||||
//@todo the exception should also contain the location of the first declaration
|
//@todo the exception should also contain the location of the first declaration
|
||||||
|
_declaration.setScope(m_currentScope);
|
||||||
if (_opensScope)
|
if (_opensScope)
|
||||||
enterNewSubScope(_declaration);
|
enterNewSubScope(_declaration);
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <boost/noncopyable.hpp>
|
#include <boost/noncopyable.hpp>
|
||||||
|
|
||||||
#include <libsolidity/Scope.h>
|
#include <libsolidity/DeclarationContainer.h>
|
||||||
#include <libsolidity/ASTVisitor.h>
|
#include <libsolidity/ASTVisitor.h>
|
||||||
|
|
||||||
namespace dev
|
namespace dev
|
||||||
@ -61,9 +61,9 @@ private:
|
|||||||
/// Maps nodes declaring a scope to scopes, i.e. ContractDefinition and FunctionDeclaration,
|
/// 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
|
/// where nullptr denotes the global scope. Note that structs are not scope since they do
|
||||||
/// not contain code.
|
/// 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
|
class DeclarationRegistrationHelper: private ASTVisitor
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DeclarationRegistrationHelper(std::map<ASTNode const*, Scope>& _scopes, ASTNode& _astRoot);
|
DeclarationRegistrationHelper(std::map<ASTNode const*, DeclarationContainer>& _scopes, ASTNode& _astRoot);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool visit(ContractDefinition& _contract);
|
bool visit(ContractDefinition& _contract);
|
||||||
@ -85,12 +85,12 @@ private:
|
|||||||
void endVisit(VariableDefinition& _variableDefinition);
|
void endVisit(VariableDefinition& _variableDefinition);
|
||||||
bool visit(VariableDeclaration& _declaration);
|
bool visit(VariableDeclaration& _declaration);
|
||||||
|
|
||||||
void enterNewSubScope(ASTNode& _node);
|
void enterNewSubScope(Declaration& _declaration);
|
||||||
void closeCurrentScope();
|
void closeCurrentScope();
|
||||||
void registerDeclaration(Declaration& _declaration, bool _opensScope);
|
void registerDeclaration(Declaration& _declaration, bool _opensScope);
|
||||||
|
|
||||||
std::map<ASTNode const*, Scope>& m_scopes;
|
std::map<ASTNode const*, DeclarationContainer>& m_scopes;
|
||||||
Scope* m_currentScope;
|
Declaration* m_currentScope;
|
||||||
FunctionDefinition* m_currentFunction;
|
FunctionDefinition* m_currentFunction;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user