diff options
Diffstat (limited to 'libsolidity/analysis/DeclarationContainer.cpp')
-rw-r--r-- | libsolidity/analysis/DeclarationContainer.cpp | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/libsolidity/analysis/DeclarationContainer.cpp b/libsolidity/analysis/DeclarationContainer.cpp new file mode 100644 index 00000000..7339ad5d --- /dev/null +++ b/libsolidity/analysis/DeclarationContainer.cpp @@ -0,0 +1,85 @@ +/* + This file is part of cpp-ethereum. + + cpp-ethereum is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + cpp-ethereum is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with cpp-ethereum. If not, see <http://www.gnu.org/licenses/>. +*/ +/** + * @author Christian <c@ethdev.com> + * @date 2014 + * Scope - object that holds declaration of names. + */ + +#include <libsolidity/analysis/DeclarationContainer.h> +#include <libsolidity/ast/AST.h> +#include <libsolidity/ast/Types.h> + +using namespace std; +using namespace dev; +using namespace dev::solidity; + +Declaration const* DeclarationContainer::conflictingDeclaration(Declaration const& _declaration) const +{ + ASTString const& declarationName(_declaration.name()); + solAssert(!declarationName.empty(), ""); + vector<Declaration const*> declarations; + if (m_declarations.count(declarationName)) + declarations += m_declarations.at(declarationName); + if (m_invisibleDeclarations.count(declarationName)) + declarations += m_invisibleDeclarations.at(declarationName); + + if (dynamic_cast<FunctionDefinition const*>(&_declaration)) + { + // check that all other declarations with the same name are functions + for (Declaration const* declaration: declarations) + if (!dynamic_cast<FunctionDefinition const*>(declaration)) + return declaration; + } + else if (!declarations.empty()) + return declarations.front(); + + return nullptr; +} + +bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, bool _invisible, bool _update) +{ + ASTString const& declarationName(_declaration.name()); + if (declarationName.empty()) + return true; + + if (_update) + { + solAssert(!dynamic_cast<FunctionDefinition const*>(&_declaration), "Attempt to update function definition."); + m_declarations.erase(declarationName); + m_invisibleDeclarations.erase(declarationName); + } + else if (conflictingDeclaration(_declaration)) + return false; + + if (_invisible) + m_invisibleDeclarations[declarationName].push_back(&_declaration); + else + m_declarations[declarationName].push_back(&_declaration); + return true; +} + +std::vector<Declaration const*> DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const +{ + solAssert(!_name.empty(), "Attempt to resolve empty name."); + auto result = m_declarations.find(_name); + if (result != m_declarations.end()) + return result->second; + if (_recursive && m_enclosingContainer) + return m_enclosingContainer->resolveName(_name, true); + return vector<Declaration const*>({}); +} |