diff options
author | Christian <c@ethdev.com> | 2014-11-13 08:12:57 +0800 |
---|---|---|
committer | Christian <c@ethdev.com> | 2014-11-14 21:08:14 +0800 |
commit | c560a62352b8ba1a106ec06aedf779df06af3a22 (patch) | |
tree | 325f19538a1239529e68d0126341e0f6aa655ef7 /NameAndTypeResolver.cpp | |
parent | 46dd62982084dfe5712292b88047d2a58e0a420e (diff) | |
download | dexon-solidity-c560a62352b8ba1a106ec06aedf779df06af3a22.tar.gz dexon-solidity-c560a62352b8ba1a106ec06aedf779df06af3a22.tar.zst dexon-solidity-c560a62352b8ba1a106ec06aedf779df06af3a22.zip |
Struct types.
Diffstat (limited to 'NameAndTypeResolver.cpp')
-rw-r--r-- | NameAndTypeResolver.cpp | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/NameAndTypeResolver.cpp b/NameAndTypeResolver.cpp index 4a15fe79..5bc40685 100644 --- a/NameAndTypeResolver.cpp +++ b/NameAndTypeResolver.cpp @@ -37,7 +37,10 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract) reset(); DeclarationRegistrationHelper registrar(m_scopes, _contract); m_currentScope = &m_scopes[&_contract]; - //@todo structs + for (ASTPointer<StructDefinition> const& structDef: _contract.getDefinedStructs()) + ReferencesResolver resolver(*structDef, *this, nullptr); + for (ASTPointer<StructDefinition> const& structDef: _contract.getDefinedStructs()) + checkForRecursion(*structDef); for (ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables()) ReferencesResolver resolver(*variable, *this, nullptr); for (ASTPointer<FunctionDefinition> const& function: _contract.getDefinedFunctions()) @@ -70,6 +73,24 @@ Declaration* NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name return m_currentScope->resolveName(_name, _recursive); } +void NameAndTypeResolver::checkForRecursion(StructDefinition const& _struct) +{ + set<StructDefinition const*> definitionsSeen; + vector<StructDefinition const*> queue = {&_struct}; + while (!queue.empty()) + { + StructDefinition const* def = queue.back(); + queue.pop_back(); + if (definitionsSeen.count(def)) + BOOST_THROW_EXCEPTION(ParserError() << errinfo_sourceLocation(def->getLocation()) + << errinfo_comment("Recursive struct definition.")); + definitionsSeen.insert(def); + for (ASTPointer<VariableDeclaration> const& member: def->getMembers()) + if (member->getType()->getCategory() == Type::Category::STRUCT) + queue.push_back(dynamic_cast<UserDefinedTypeName&>(*member->getTypeName()).getReferencedStruct()); + } +} + void NameAndTypeResolver::reset() { m_scopes.clear(); @@ -163,8 +184,8 @@ void DeclarationRegistrationHelper::registerDeclaration(Declaration& _declaratio } ReferencesResolver::ReferencesResolver(ASTNode& _root, NameAndTypeResolver& _resolver, - ParameterList* _returnParameters): - m_resolver(_resolver), m_returnParameters(_returnParameters) + ParameterList* _returnParameters, bool _allowLazyTypes): + m_resolver(_resolver), m_returnParameters(_returnParameters), m_allowLazyTypes(_allowLazyTypes) { _root.accept(*this); } @@ -175,6 +196,8 @@ void ReferencesResolver::endVisit(VariableDeclaration& _variable) // or mapping if (_variable.getTypeName()) _variable.setType(_variable.getTypeName()->toType()); + else if (!m_allowLazyTypes) + BOOST_THROW_EXCEPTION(_variable.createTypeError("Explicit type needed.")); // otherwise we have a "var"-declaration whose type is resolved by the first assignment } |