aboutsummaryrefslogtreecommitdiffstats
path: root/NameAndTypeResolver.cpp
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2014-11-13 08:12:57 +0800
committerChristian <c@ethdev.com>2014-11-14 21:08:14 +0800
commitc560a62352b8ba1a106ec06aedf779df06af3a22 (patch)
tree325f19538a1239529e68d0126341e0f6aa655ef7 /NameAndTypeResolver.cpp
parent46dd62982084dfe5712292b88047d2a58e0a420e (diff)
downloaddexon-solidity-c560a62352b8ba1a106ec06aedf779df06af3a22.tar.gz
dexon-solidity-c560a62352b8ba1a106ec06aedf779df06af3a22.tar.zst
dexon-solidity-c560a62352b8ba1a106ec06aedf779df06af3a22.zip
Struct types.
Diffstat (limited to 'NameAndTypeResolver.cpp')
-rw-r--r--NameAndTypeResolver.cpp29
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
}