diff options
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.cpp | 38 | ||||
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.cpp | 2 | ||||
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.h | 2 | ||||
-rw-r--r-- | libsolidity/analysis/TypeChecker.cpp | 32 | ||||
-rw-r--r-- | libsolidity/ast/AST.cpp | 84 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 46 | ||||
-rw-r--r-- | libsolidity/ast/AST_accept.h | 14 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 8 | ||||
-rw-r--r-- | libsolidity/codegen/Compiler.cpp | 2 | ||||
-rw-r--r-- | libsolidity/codegen/CompilerContext.cpp | 6 | ||||
-rw-r--r-- | libsolidity/formal/Why3Translator.cpp | 15 | ||||
-rw-r--r-- | libsolidity/formal/Why3Translator.h | 2 | ||||
-rw-r--r-- | libsolidity/parsing/Parser.cpp | 26 | ||||
-rw-r--r-- | test/libsolidity/SolidityParser.cpp | 16 |
14 files changed, 141 insertions, 152 deletions
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<StructDefinition> const& structDef: _contract.definedStructs()) - if (!resolver.resolve(*structDef)) - success = false; - for (ASTPointer<EnumDefinition> const& enumDef: _contract.definedEnums()) - if (!resolver.resolve(*enumDef)) - success = false; - for (ASTPointer<VariableDeclaration> const& variable: _contract.stateVariables()) - if (!resolver.resolve(*variable)) - success = false; - for (ASTPointer<EventDefinition> const& event: _contract.events()) - if (!resolver.resolve(*event)) - success = false; // these can contain code, only resolve parameters for now - for (ASTPointer<ModifierDefinition> const& modifier: _contract.functionModifiers()) + for (ASTPointer<ASTNode> const& node: _contract.subNodes()) { - m_currentScope = &m_scopes[modifier.get()]; - ReferencesResolver resolver(m_errors, *this, nullptr); - if (!resolver.resolve(*modifier)) - success = false; - } - - for (ASTPointer<FunctionDefinition> 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<ModifierDefinition> 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<FunctionDefinition> 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<FunctionDefinition> 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<string, vector<FunctionDefinition const*>> functions; - for (ASTPointer<FunctionDefinition> 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<FunctionDefinition> const& function: contract->definedFunctions()) + for (FunctionDefinition const* function: contract->definedFunctions()) { auto& overloads = functions[function->name()]; FunctionTypePointer funType = make_shared<FunctionType>(*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<FunctionDefinition> 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<ModifierDefinition> 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<string, vector<pair<Declaration const*, FunctionTypePointer>>> externalDeclarations; for (ContractDefinition const* contract: _contract.annotation().linearizedBaseContracts) { - for (ASTPointer<FunctionDefinition> const& f: contract->definedFunctions()) + for (FunctionDefinition const* f: contract->definedFunctions()) if (f->isPartOfExternalInterface()) { auto functionType = make_shared<FunctionType>(*f); externalDeclarations[functionType->externalSignature()].push_back( - make_pair(f.get(), functionType) + make_pair(f, functionType) ); } - for (ASTPointer<VariableDeclaration> const& v: contract->stateVariables()) + for (VariableDeclaration const* v: contract->stateVariables()) if (v->isPartOfExternalInterface()) { auto functionType = make_shared<FunctionType>(*v); externalDeclarations[functionType->externalSignature()].push_back( - make_pair(v.get(), functionType) + make_pair(v, functionType) ); } } diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 7ceab752..65535388 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -74,29 +74,83 @@ map<FixedHash<4>, FunctionTypePointer> ContractDefinition::interfaceFunctions() FunctionDefinition const* ContractDefinition::constructor() const { - for (ASTPointer<FunctionDefinition> const& f: m_definedFunctions) + for (FunctionDefinition const* f: definedFunctions()) if (f->isConstructor()) - return f.get(); + return f; return nullptr; } FunctionDefinition const* ContractDefinition::fallbackFunction() const { for (ContractDefinition const* contract: annotation().linearizedBaseContracts) - for (ASTPointer<FunctionDefinition> const& f: contract->definedFunctions()) + for (FunctionDefinition const* f: contract->definedFunctions()) if (f->name().empty()) - return f.get(); + return f; return nullptr; } -vector<ASTPointer<EventDefinition>> const& ContractDefinition::interfaceEvents() const +vector<StructDefinition const*> ContractDefinition::definedStructs() const +{ + vector<StructDefinition const*> ret; + for (auto const& node: m_subNodes) + if (auto v = dynamic_cast<StructDefinition const*>(node.get())) + ret.push_back(v); + return ret; +} + +vector<EnumDefinition const*> ContractDefinition::definedEnums() const +{ + vector<EnumDefinition const*> ret; + for (auto const& node: m_subNodes) + if (auto v = dynamic_cast<EnumDefinition const*>(node.get())) + ret.push_back(v); + return ret; +} + +vector<VariableDeclaration const*> ContractDefinition::stateVariables() const +{ + vector<VariableDeclaration const*> ret; + for (auto const& node: m_subNodes) + if (auto v = dynamic_cast<VariableDeclaration const*>(node.get())) + ret.push_back(v); + return ret; +} + +vector<ModifierDefinition const*> ContractDefinition::functionModifiers() const +{ + vector<ModifierDefinition const*> ret; + for (auto const& node: m_subNodes) + if (auto v = dynamic_cast<ModifierDefinition const*>(node.get())) + ret.push_back(v); + return ret; +} + +vector<FunctionDefinition const*> ContractDefinition::definedFunctions() const +{ + vector<FunctionDefinition const*> ret; + for (auto const& node: m_subNodes) + if (auto v = dynamic_cast<FunctionDefinition const*>(node.get())) + ret.push_back(v); + return ret; +} + +vector<EventDefinition const*> ContractDefinition::events() const +{ + vector<EventDefinition const*> ret; + for (auto const& node: m_subNodes) + if (auto v = dynamic_cast<EventDefinition const*>(node.get())) + ret.push_back(v); + return ret; +} + +vector<EventDefinition const*> const& ContractDefinition::interfaceEvents() const { if (!m_interfaceEvents) { set<string> eventsSeen; - m_interfaceEvents.reset(new vector<ASTPointer<EventDefinition>>()); + m_interfaceEvents.reset(new vector<EventDefinition const*>()); for (ContractDefinition const* contract: annotation().linearizedBaseContracts) - for (ASTPointer<EventDefinition> const& e: contract->events()) + for (EventDefinition const* e: contract->events()) if (eventsSeen.count(e->name()) == 0) { eventsSeen.insert(e->name()); @@ -116,10 +170,10 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::inter for (ContractDefinition const* contract: annotation().linearizedBaseContracts) { vector<FunctionTypePointer> functions; - for (ASTPointer<FunctionDefinition> const& f: contract->definedFunctions()) + for (FunctionDefinition const* f: contract->definedFunctions()) if (f->isPartOfExternalInterface()) functions.push_back(make_shared<FunctionType>(*f, false)); - for (ASTPointer<VariableDeclaration> const& v: contract->stateVariables()) + for (VariableDeclaration const* v: contract->stateVariables()) if (v->isPartOfExternalInterface()) functions.push_back(make_shared<FunctionType>(*v)); for (FunctionTypePointer const& fun: functions) @@ -176,14 +230,14 @@ vector<Declaration const*> const& ContractDefinition::inheritableMembers() const } }; - for (ASTPointer<FunctionDefinition> const& f: definedFunctions()) - addInheritableMember(f.get()); + for (FunctionDefinition const* f: definedFunctions()) + addInheritableMember(f); - for (ASTPointer<VariableDeclaration> const& v: stateVariables()) - addInheritableMember(v.get()); + for (VariableDeclaration const* v: stateVariables()) + addInheritableMember(v); - for (ASTPointer<StructDefinition> const& s: definedStructs()) - addInheritableMember(s.get()); + for (StructDefinition const* s: definedStructs()) + addInheritableMember(s); } return *m_inheritableMembers; } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 11c4fef6..ab872750 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -58,15 +58,15 @@ public: virtual void accept(ASTVisitor& _visitor) = 0; virtual void accept(ASTConstVisitor& _visitor) const = 0; template <class T> - static void listAccept(std::vector<ASTPointer<T>>& _list, ASTVisitor& _visitor) + static void listAccept(std::vector<T> const& _list, ASTVisitor& _visitor) { - for (ASTPointer<T>& element: _list) + for (T const& element: _list) element->accept(_visitor); } template <class T> - static void listAccept(std::vector<ASTPointer<T>> const& _list, ASTConstVisitor& _visitor) + static void listAccept(std::vector<T> const& _list, ASTConstVisitor& _visitor) { - for (ASTPointer<T> const& element: _list) + for (T const& element: _list) element->accept(_visitor); } @@ -238,23 +238,13 @@ public: ASTPointer<ASTString> const& _name, ASTPointer<ASTString> const& _documentation, std::vector<ASTPointer<InheritanceSpecifier>> const& _baseContracts, - std::vector<ASTPointer<StructDefinition>> const& _definedStructs, - std::vector<ASTPointer<EnumDefinition>> const& _definedEnums, - std::vector<ASTPointer<VariableDeclaration>> const& _stateVariables, - std::vector<ASTPointer<FunctionDefinition>> const& _definedFunctions, - std::vector<ASTPointer<ModifierDefinition>> const& _functionModifiers, - std::vector<ASTPointer<EventDefinition>> const& _events, + std::vector<ASTPointer<ASTNode>> const& _subNodes, bool _isLibrary ): Declaration(_location, _name), Documented(_documentation), m_baseContracts(_baseContracts), - m_definedStructs(_definedStructs), - m_definedEnums(_definedEnums), - m_stateVariables(_stateVariables), - m_definedFunctions(_definedFunctions), - m_functionModifiers(_functionModifiers), - m_events(_events), + m_subNodes(_subNodes), m_isLibrary(_isLibrary) {} @@ -262,13 +252,14 @@ public: virtual void accept(ASTConstVisitor& _visitor) const override; std::vector<ASTPointer<InheritanceSpecifier>> const& baseContracts() const { return m_baseContracts; } - std::vector<ASTPointer<StructDefinition>> const& definedStructs() const { return m_definedStructs; } - std::vector<ASTPointer<EnumDefinition>> const& definedEnums() const { return m_definedEnums; } - std::vector<ASTPointer<VariableDeclaration>> const& stateVariables() const { return m_stateVariables; } - std::vector<ASTPointer<ModifierDefinition>> const& functionModifiers() const { return m_functionModifiers; } - std::vector<ASTPointer<FunctionDefinition>> const& definedFunctions() const { return m_definedFunctions; } - std::vector<ASTPointer<EventDefinition>> const& events() const { return m_events; } - std::vector<ASTPointer<EventDefinition>> const& interfaceEvents() const; + std::vector<ASTPointer<ASTNode>> const& subNodes() const { return m_subNodes; } + std::vector<StructDefinition const*> definedStructs() const; + std::vector<EnumDefinition const*> definedEnums() const; + std::vector<VariableDeclaration const*> stateVariables() const; + std::vector<ModifierDefinition const*> functionModifiers() const; + std::vector<FunctionDefinition const*> definedFunctions() const; + std::vector<EventDefinition const*> events() const; + std::vector<EventDefinition const*> const& interfaceEvents() const; bool isLibrary() const { return m_isLibrary; } /// @returns a map of canonical function signatures to FunctionDefinitions @@ -296,12 +287,7 @@ public: private: std::vector<ASTPointer<InheritanceSpecifier>> m_baseContracts; - std::vector<ASTPointer<StructDefinition>> m_definedStructs; - std::vector<ASTPointer<EnumDefinition>> m_definedEnums; - std::vector<ASTPointer<VariableDeclaration>> m_stateVariables; - std::vector<ASTPointer<FunctionDefinition>> m_definedFunctions; - std::vector<ASTPointer<ModifierDefinition>> m_functionModifiers; - std::vector<ASTPointer<EventDefinition>> m_events; + std::vector<ASTPointer<ASTNode>> m_subNodes; bool m_isLibrary; // parsed Natspec documentation of the contract. @@ -310,7 +296,7 @@ private: std::vector<ContractDefinition const*> m_linearizedBaseContracts; mutable std::unique_ptr<std::vector<std::pair<FixedHash<4>, FunctionTypePointer>>> m_interfaceFunctionList; - mutable std::unique_ptr<std::vector<ASTPointer<EventDefinition>>> m_interfaceEvents; + mutable std::unique_ptr<std::vector<EventDefinition const*>> m_interfaceEvents; mutable std::unique_ptr<std::vector<Declaration const*>> m_inheritableMembers; }; diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h index 99d1bf6a..f65595b8 100644 --- a/libsolidity/ast/AST_accept.h +++ b/libsolidity/ast/AST_accept.h @@ -62,12 +62,7 @@ void ContractDefinition::accept(ASTVisitor& _visitor) if (_visitor.visit(*this)) { listAccept(m_baseContracts, _visitor); - listAccept(m_definedStructs, _visitor); - listAccept(m_definedEnums, _visitor); - listAccept(m_stateVariables, _visitor); - listAccept(m_events, _visitor); - listAccept(m_functionModifiers, _visitor); - listAccept(m_definedFunctions, _visitor); + listAccept(m_subNodes, _visitor); } _visitor.endVisit(*this); } @@ -77,12 +72,7 @@ void ContractDefinition::accept(ASTConstVisitor& _visitor) const if (_visitor.visit(*this)) { listAccept(m_baseContracts, _visitor); - listAccept(m_definedStructs, _visitor); - listAccept(m_definedEnums, _visitor); - listAccept(m_stateVariables, _visitor); - listAccept(m_events, _visitor); - listAccept(m_functionModifiers, _visitor); - listAccept(m_definedFunctions, _visitor); + listAccept(m_subNodes, _visitor); } _visitor.endVisit(*this); } diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 85e1fd49..a4da5b13 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -970,7 +970,7 @@ MemberList const& ContractType::members(ContractDefinition const*) const { // add the most derived of all functions which are visible in derived contracts for (ContractDefinition const* base: m_contract.annotation().linearizedBaseContracts) - for (ASTPointer<FunctionDefinition> const& function: base->definedFunctions()) + for (FunctionDefinition const* function: base->definedFunctions()) { if (!function->isVisibleInDerivedContracts()) continue; @@ -991,7 +991,7 @@ MemberList const& ContractType::members(ContractDefinition const*) const members.push_back(MemberList::Member( function->name(), functionType, - function.get() + function )); } } @@ -1024,9 +1024,9 @@ vector<tuple<VariableDeclaration const*, u256, unsigned>> ContractType::stateVar { vector<VariableDeclaration const*> variables; for (ContractDefinition const* contract: boost::adaptors::reverse(m_contract.annotation().linearizedBaseContracts)) - for (ASTPointer<VariableDeclaration> const& variable: contract->stateVariables()) + for (VariableDeclaration const* variable: contract->stateVariables()) if (!variable->isConstant()) - variables.push_back(variable.get()); + variables.push_back(variable); TypePointers types; for (auto variable: variables) types.push_back(variable->annotation().type); diff --git a/libsolidity/codegen/Compiler.cpp b/libsolidity/codegen/Compiler.cpp index 055e607f..f1d95980 100644 --- a/libsolidity/codegen/Compiler.cpp +++ b/libsolidity/codegen/Compiler.cpp @@ -385,7 +385,7 @@ void Compiler::registerStateVariables(ContractDefinition const& _contract) void Compiler::initializeStateVariables(ContractDefinition const& _contract) { - for (ASTPointer<VariableDeclaration> const& variable: _contract.stateVariables()) + for (VariableDeclaration const* variable: _contract.stateVariables()) if (variable->value() && !variable->isConstant()) ExpressionCompiler(m_context, m_optimize).appendStateVariableInitialization(*variable); } diff --git a/libsolidity/codegen/CompilerContext.cpp b/libsolidity/codegen/CompilerContext.cpp index 00b9d87c..9e2405cc 100644 --- a/libsolidity/codegen/CompilerContext.cpp +++ b/libsolidity/codegen/CompilerContext.cpp @@ -133,9 +133,9 @@ ModifierDefinition const& CompilerContext::functionModifier(string const& _name) { solAssert(!m_inheritanceHierarchy.empty(), "No inheritance hierarchy set."); for (ContractDefinition const* contract: m_inheritanceHierarchy) - for (ASTPointer<ModifierDefinition> const& modifier: contract->functionModifiers()) + for (ModifierDefinition const* modifier: contract->functionModifiers()) if (modifier->name() == _name) - return *modifier.get(); + return *modifier; BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Function modifier " + _name + " not found.")); } @@ -195,7 +195,7 @@ eth::AssemblyItem CompilerContext::virtualFunctionEntryLabel( FunctionType functionType(_function); auto it = _searchStart; for (; it != m_inheritanceHierarchy.end(); ++it) - for (ASTPointer<FunctionDefinition> const& function: (*it)->definedFunctions()) + for (FunctionDefinition const* function: (*it)->definedFunctions()) if ( function->name() == name && !function->isConstructor() && diff --git a/libsolidity/formal/Why3Translator.cpp b/libsolidity/formal/Why3Translator.cpp index fe3729d4..5028e2c3 100644 --- a/libsolidity/formal/Why3Translator.cpp +++ b/libsolidity/formal/Why3Translator.cpp @@ -145,8 +145,8 @@ bool Why3Translator::visit(ContractDefinition const& _contract) addLine("type state = {"); indent(); - m_stateVariables = &_contract.stateVariables(); - for (auto const& variable: _contract.stateVariables()) + m_stateVariables = _contract.stateVariables(); + for (VariableDeclaration const* variable: m_stateVariables) { string varType = toFormalType(*variable->annotation().type); if (varType.empty()) @@ -174,7 +174,7 @@ bool Why3Translator::visit(ContractDefinition const& _contract) void Why3Translator::endVisit(ContractDefinition const& _contract) { - m_stateVariables = nullptr; + m_stateVariables.clear(); addSourceFromDocStrings(_contract.annotation()); unindent(); addLine("end"); @@ -600,17 +600,12 @@ bool Why3Translator::visit(Literal const& _literal) bool Why3Translator::isStateVariable(VariableDeclaration const* _var) const { - solAssert(!!m_stateVariables, ""); - for (auto const& var: *m_stateVariables) - if (var.get() == _var) - return true; - return false; + return contains(m_stateVariables, _var); } bool Why3Translator::isStateVariable(string const& _name) const { - solAssert(!!m_stateVariables, ""); - for (auto const& var: *m_stateVariables) + for (auto const& var: m_stateVariables) if (var->name() == _name) return true; return false; diff --git a/libsolidity/formal/Why3Translator.h b/libsolidity/formal/Why3Translator.h index e5c298b4..f4315a7a 100644 --- a/libsolidity/formal/Why3Translator.h +++ b/libsolidity/formal/Why3Translator.h @@ -117,7 +117,7 @@ private: bool m_seenContract = false; bool m_errorOccured = false; - std::vector<ASTPointer<VariableDeclaration>> const* m_stateVariables = nullptr; + std::vector<VariableDeclaration const*> m_stateVariables; std::map<std::string, VariableDeclaration const*> m_localVariables; struct Line diff --git a/libsolidity/parsing/Parser.cpp b/libsolidity/parsing/Parser.cpp index 2d4ca43e..9272eb4b 100644 --- a/libsolidity/parsing/Parser.cpp +++ b/libsolidity/parsing/Parser.cpp @@ -132,12 +132,6 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary) expectToken(_isLibrary ? Token::Library : Token::Contract); ASTPointer<ASTString> name = expectIdentifierToken(); vector<ASTPointer<InheritanceSpecifier>> baseContracts; - vector<ASTPointer<StructDefinition>> structs; - vector<ASTPointer<EnumDefinition>> enums; - vector<ASTPointer<VariableDeclaration>> stateVariables; - vector<ASTPointer<FunctionDefinition>> functions; - vector<ASTPointer<ModifierDefinition>> modifiers; - vector<ASTPointer<EventDefinition>> events; if (m_scanner->currentToken() == Token::Is) do { @@ -145,6 +139,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary) baseContracts.push_back(parseInheritanceSpecifier()); } while (m_scanner->currentToken() == Token::Comma); + vector<ASTPointer<ASTNode>> subNodes; expectToken(Token::LBrace); while (true) { @@ -152,11 +147,11 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary) if (currentTokenValue == Token::RBrace) break; else if (currentTokenValue == Token::Function) - functions.push_back(parseFunctionDefinition(name.get())); + subNodes.push_back(parseFunctionDefinition(name.get())); else if (currentTokenValue == Token::Struct) - structs.push_back(parseStructDefinition()); + subNodes.push_back(parseStructDefinition()); else if (currentTokenValue == Token::Enum) - enums.push_back(parseEnumDefinition()); + subNodes.push_back(parseEnumDefinition()); else if ( currentTokenValue == Token::Identifier || currentTokenValue == Token::Mapping || @@ -166,13 +161,13 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary) VarDeclParserOptions options; options.isStateVariable = true; options.allowInitialValue = true; - stateVariables.push_back(parseVariableDeclaration(options)); + subNodes.push_back(parseVariableDeclaration(options)); expectToken(Token::Semicolon); } else if (currentTokenValue == Token::Modifier) - modifiers.push_back(parseModifierDefinition()); + subNodes.push_back(parseModifierDefinition()); else if (currentTokenValue == Token::Event) - events.push_back(parseEventDefinition()); + subNodes.push_back(parseEventDefinition()); else fatalParserError(std::string("Function, variable, struct or modifier declaration expected.")); } @@ -182,12 +177,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition(bool _isLibrary) name, docString, baseContracts, - structs, - enums, - stateVariables, - functions, - modifiers, - events, + subNodes, _isLibrary ); } diff --git a/test/libsolidity/SolidityParser.cpp b/test/libsolidity/SolidityParser.cpp index beb71942..b494a1aa 100644 --- a/test/libsolidity/SolidityParser.cpp +++ b/test/libsolidity/SolidityParser.cpp @@ -73,7 +73,7 @@ bool successParse(std::string const& _source) } void checkFunctionNatspec( - ASTPointer<FunctionDefinition> _function, + FunctionDefinition const* _function, std::string const& _expectedDoc ) { @@ -193,7 +193,7 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation) BOOST_CHECK(successParse(text)); ErrorList e; ASTPointer<ContractDefinition> contract = parseText(text, e); - ASTPointer<FunctionDefinition> function; + FunctionDefinition const* function = nullptr; ErrorList errors; auto functions = parseText(text, errors)->definedFunctions(); @@ -204,7 +204,7 @@ BOOST_AUTO_TEST_CASE(function_natspec_documentation) BOOST_AUTO_TEST_CASE(function_normal_comments) { ASTPointer<ContractDefinition> contract; - ASTPointer<FunctionDefinition> function; + FunctionDefinition const* function = nullptr; char const* text = "contract test {\n" " uint256 stateVar;\n" " // We won't see this comment\n" @@ -221,7 +221,7 @@ BOOST_AUTO_TEST_CASE(function_normal_comments) BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation) { ASTPointer<ContractDefinition> contract; - ASTPointer<FunctionDefinition> function; + FunctionDefinition const* function = nullptr; char const* text = "contract test {\n" " uint256 stateVar;\n" " /// This is test function 1\n" @@ -254,7 +254,7 @@ BOOST_AUTO_TEST_CASE(multiple_functions_natspec_documentation) BOOST_AUTO_TEST_CASE(multiline_function_documentation) { ASTPointer<ContractDefinition> contract; - ASTPointer<FunctionDefinition> function; + FunctionDefinition const* function = nullptr; char const* text = "contract test {\n" " uint256 stateVar;\n" " /// This is a test function\n" @@ -272,7 +272,7 @@ BOOST_AUTO_TEST_CASE(multiline_function_documentation) BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body) { ASTPointer<ContractDefinition> contract; - ASTPointer<FunctionDefinition> function; + FunctionDefinition const* function = nullptr; char const* text = "contract test {\n" " /// fun1 description\n" " function fun1(uint256 a) {\n" @@ -301,7 +301,7 @@ BOOST_AUTO_TEST_CASE(natspec_comment_in_function_body) BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature) { ASTPointer<ContractDefinition> contract; - ASTPointer<FunctionDefinition> function; + FunctionDefinition const* function = nullptr; char const* text = "contract test {\n" " uint256 stateVar;\n" " function ///I am in the wrong place \n" @@ -325,7 +325,7 @@ BOOST_AUTO_TEST_CASE(natspec_docstring_between_keyword_and_signature) BOOST_AUTO_TEST_CASE(natspec_docstring_after_signature) { ASTPointer<ContractDefinition> contract; - ASTPointer<FunctionDefinition> function; + FunctionDefinition const* function = nullptr; char const* text = "contract test {\n" " uint256 stateVar;\n" " function fun1(uint256 a) {\n" |