From b47d5932528357939ee29758a8b8027c90bdb1e5 Mon Sep 17 00:00:00 2001 From: chriseth Date: Mon, 23 Nov 2015 23:57:17 +0100 Subject: Do not store elements of a contract by AST node type. --- libsolidity/analysis/NameAndTypeResolver.cpp | 38 +++++----------------------- libsolidity/analysis/ReferencesResolver.cpp | 2 +- libsolidity/analysis/ReferencesResolver.h | 2 +- libsolidity/analysis/TypeChecker.cpp | 32 +++++++++++------------ 4 files changed, 24 insertions(+), 50 deletions(-) (limited to 'libsolidity/analysis') diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index a2397d9e..612989e1 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -84,35 +84,11 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) importInheritedScope(*base); } - for (ASTPointer const& structDef: _contract.definedStructs()) - if (!resolver.resolve(*structDef)) - success = false; - for (ASTPointer const& enumDef: _contract.definedEnums()) - if (!resolver.resolve(*enumDef)) - success = false; - for (ASTPointer const& variable: _contract.stateVariables()) - if (!resolver.resolve(*variable)) - success = false; - for (ASTPointer const& event: _contract.events()) - if (!resolver.resolve(*event)) - success = false; // these can contain code, only resolve parameters for now - for (ASTPointer const& modifier: _contract.functionModifiers()) + for (ASTPointer const& node: _contract.subNodes()) { - m_currentScope = &m_scopes[modifier.get()]; - ReferencesResolver resolver(m_errors, *this, nullptr); - if (!resolver.resolve(*modifier)) - success = false; - } - - for (ASTPointer const& function: _contract.definedFunctions()) - { - m_currentScope = &m_scopes[function.get()]; - if (!ReferencesResolver( - m_errors, - *this, - function->returnParameterList().get() - ).resolve(*function)) + m_currentScope = &m_scopes[m_scopes.count(node.get()) ? node.get() : &_contract]; + if (!resolver.resolve(*node)) success = false; } @@ -122,17 +98,17 @@ bool NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) m_currentScope = &m_scopes[&_contract]; // now resolve references inside the code - for (ASTPointer const& modifier: _contract.functionModifiers()) + for (ModifierDefinition const* modifier: _contract.functionModifiers()) { - m_currentScope = &m_scopes[modifier.get()]; + m_currentScope = &m_scopes[modifier]; ReferencesResolver resolver(m_errors, *this, nullptr, true); if (!resolver.resolve(*modifier)) success = false; } - for (ASTPointer const& function: _contract.definedFunctions()) + for (FunctionDefinition const* function: _contract.definedFunctions()) { - m_currentScope = &m_scopes[function.get()]; + m_currentScope = &m_scopes[function]; if (!ReferencesResolver( m_errors, *this, diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index 2207fd80..e5b1c52b 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -53,7 +53,7 @@ bool ReferencesResolver::visit(UserDefinedTypeName const& _typeName) return true; } -bool ReferencesResolver::resolve(ASTNode& _root) +bool ReferencesResolver::resolve(ASTNode const& _root) { try { diff --git a/libsolidity/analysis/ReferencesResolver.h b/libsolidity/analysis/ReferencesResolver.h index 870312f1..6f5ced8c 100644 --- a/libsolidity/analysis/ReferencesResolver.h +++ b/libsolidity/analysis/ReferencesResolver.h @@ -55,7 +55,7 @@ public: {} /// @returns true if no errors during resolving - bool resolve(ASTNode& _root); + bool resolve(ASTNode const& _root); private: virtual bool visit(Block const&) override { return m_resolveInsideCode; } diff --git a/libsolidity/analysis/TypeChecker.cpp b/libsolidity/analysis/TypeChecker.cpp index 2dc357bb..1d2d0258 100644 --- a/libsolidity/analysis/TypeChecker.cpp +++ b/libsolidity/analysis/TypeChecker.cpp @@ -63,6 +63,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract) m_scope = &_contract; // We force our own visiting order here. + //@TODO structs will be visited again below, but it is probably fine. ASTNode::listAccept(_contract.definedStructs(), *this); ASTNode::listAccept(_contract.baseContracts(), *this); @@ -76,7 +77,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract) typeError(function->returnParameterList()->location(), "Non-empty \"returns\" directive for constructor."); FunctionDefinition const* fallbackFunction = nullptr; - for (ASTPointer const& function: _contract.definedFunctions()) + for (FunctionDefinition const* function: _contract.definedFunctions()) { if (function->name().empty()) { @@ -88,7 +89,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract) } else { - fallbackFunction = function.get(); + fallbackFunction = function; if (!fallbackFunction->parameters().empty()) typeError(fallbackFunction->parameterList().location(), "Fallback function cannot take parameters."); } @@ -97,10 +98,7 @@ bool TypeChecker::visit(ContractDefinition const& _contract) _contract.annotation().isFullyImplemented = false; } - ASTNode::listAccept(_contract.stateVariables(), *this); - ASTNode::listAccept(_contract.events(), *this); - ASTNode::listAccept(_contract.functionModifiers(), *this); - ASTNode::listAccept(_contract.definedFunctions(), *this); + ASTNode::listAccept(_contract.subNodes(), *this); checkContractExternalTypeClashes(_contract); // check for hash collisions in function signatures @@ -127,8 +125,8 @@ void TypeChecker::checkContractDuplicateFunctions(ContractDefinition const& _con /// Checks that two functions with the same name defined in this contract have different /// argument types and that there is at most one constructor. map> functions; - for (ASTPointer const& function: _contract.definedFunctions()) - functions[function->name()].push_back(function.get()); + for (FunctionDefinition const* function: _contract.definedFunctions()) + functions[function->name()].push_back(function); // Constructor if (functions[_contract.name()].size() > 1) @@ -172,7 +170,7 @@ void TypeChecker::checkContractAbstractFunctions(ContractDefinition const& _cont // Search from base to derived for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.annotation().linearizedBaseContracts)) - for (ASTPointer const& function: contract->definedFunctions()) + for (FunctionDefinition const* function: contract->definedFunctions()) { auto& overloads = functions[function->name()]; FunctionTypePointer funType = make_shared(*function); @@ -248,7 +246,7 @@ void TypeChecker::checkContractIllegalOverrides(ContractDefinition const& _contr // We search from derived to base, so the stored item causes the error. for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts) { - for (ASTPointer const& function: contract->definedFunctions()) + for (FunctionDefinition const* function: contract->definedFunctions()) { if (function->isConstructor()) continue; // constructors can neither be overridden nor override anything @@ -269,14 +267,14 @@ void TypeChecker::checkContractIllegalOverrides(ContractDefinition const& _contr ) typeError(overriding->location(), "Override changes extended function signature."); } - functions[name].push_back(function.get()); + functions[name].push_back(function); } - for (ASTPointer const& modifier: contract->functionModifiers()) + for (ModifierDefinition const* modifier: contract->functionModifiers()) { string const& name = modifier->name(); ModifierDefinition const*& override = modifiers[name]; if (!override) - override = modifier.get(); + override = modifier; else if (ModifierType(*override) != ModifierType(*modifier)) typeError(override->location(), "Override changes modifier signature."); if (!functions[name].empty()) @@ -290,20 +288,20 @@ void TypeChecker::checkContractExternalTypeClashes(ContractDefinition const& _co map>> externalDeclarations; for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts) { - for (ASTPointer const& f: contract->definedFunctions()) + for (FunctionDefinition const* f: contract->definedFunctions()) if (f->isPartOfExternalInterface()) { auto functionType = make_shared(*f); externalDeclarations[functionType->externalSignature()].push_back( - make_pair(f.get(), functionType) + make_pair(f, functionType) ); } - for (ASTPointer const& v: contract->stateVariables()) + for (VariableDeclaration const* v: contract->stateVariables()) if (v->isPartOfExternalInterface()) { auto functionType = make_shared(*v); externalDeclarations[functionType->externalSignature()].push_back( - make_pair(v.get(), functionType) + make_pair(v, functionType) ); } } -- cgit