Contracts as types and framework for special global variables.

This commit is contained in:
Christian
2014-11-23 21:28:44 +01:00
parent fa987e0a20
commit c50cd646ce
13 changed files with 259 additions and 66 deletions
+35 -1
View File
@@ -51,6 +51,40 @@ void StructDefinition::accept(ASTVisitor& _visitor)
_visitor.endVisit(*this);
}
void StructDefinition::checkValidityOfMembers()
{
checkMemberTypes();
checkRecursion();
}
void StructDefinition::checkMemberTypes()
{
for (ASTPointer<VariableDeclaration> const& member: getMembers())
if (!member->getType()->canBeStored())
BOOST_THROW_EXCEPTION(member->createTypeError("Type cannot be used in struct."));
}
void StructDefinition::checkRecursion()
{
set<StructDefinition const*> definitionsSeen;
vector<StructDefinition const*> queue = {this};
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)
{
UserDefinedTypeName const& typeName = dynamic_cast<UserDefinedTypeName&>(*member->getTypeName());
queue.push_back(&dynamic_cast<StructDefinition const&>(*typeName.getReferencedDeclaration()));
}
}
}
void ParameterList::accept(ASTVisitor& _visitor)
{
if (_visitor.visit(*this))
@@ -258,7 +292,7 @@ void Literal::accept(ASTVisitor& _visitor)
_visitor.endVisit(*this);
}
TypeError ASTNode::createTypeError(string const& _description)
TypeError ASTNode::createTypeError(string const& _description) const
{
return TypeError() << errinfo_sourceLocation(getLocation()) << errinfo_comment(_description);
}