aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--AST.cpp42
-rw-r--r--AST.h3
2 files changed, 44 insertions, 1 deletions
diff --git a/AST.cpp b/AST.cpp
index 37016646..4d183889 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -54,6 +54,7 @@ void ContractDefinition::checkTypeRequirements()
checkIllegalOverrides();
checkAbstractFunctions();
+ checkAbstractConstructors();
FunctionDefinition const* constructor = getConstructor();
if (constructor && !constructor->getReturnParameters().empty())
@@ -152,6 +153,47 @@ void ContractDefinition::checkAbstractFunctions()
}
}
+void ContractDefinition::checkAbstractConstructors()
+{
+ set<FunctionDefinition const*> argumentsNeeded;
+ set<FunctionDefinition const*> argumentsProvided;
+ // check that we get arguments for all base constructors that need it.
+ // If not mark the contract as abstract (not fully implemented)
+ vector<ContractDefinition const*> const& bases = getLinearizedBaseContracts();
+ for (ContractDefinition const* contract: bases)
+ {
+ FunctionDefinition const* constructor = contract->getConstructor();
+ if (constructor)
+ {
+ if (!constructor->getParameters().empty())
+ argumentsProvided.insert(constructor);
+ for (auto const& modifier: constructor->getModifiers())
+ {
+ auto baseContract = dynamic_cast<ContractDefinition const*>(
+ modifier->getName()->getReferencedDeclaration());
+ if (baseContract)
+ {
+ FunctionDefinition const* baseConstructor = baseContract->getConstructor();
+ if (argumentsProvided.count(baseConstructor) == 1)
+ argumentsNeeded.insert(baseConstructor);
+ }
+ }
+ }
+
+ for (ASTPointer<InheritanceSpecifier> const& base: contract->getBaseContracts())
+ {
+ ContractDefinition const* baseContract = dynamic_cast<ContractDefinition const*>(
+ base->getName()->getReferencedDeclaration());
+ solAssert(baseContract, "");
+ FunctionDefinition const* baseConstructor = baseContract->getConstructor();
+ if (argumentsProvided.count(baseConstructor) == 1)
+ argumentsNeeded.insert(baseConstructor);
+ }
+ }
+ if (argumentsProvided != argumentsNeeded)
+ setFullyImplemented(false);
+}
+
void ContractDefinition::checkIllegalOverrides() const
{
// TODO unify this at a later point. for this we need to put the constness and the access specifier
diff --git a/AST.h b/AST.h
index 8c36caea..99abf229 100644
--- a/AST.h
+++ b/AST.h
@@ -284,6 +284,7 @@ public:
private:
void checkIllegalOverrides() const;
void checkAbstractFunctions();
+ void checkAbstractConstructors();
std::vector<std::pair<FixedHash<4>, FunctionTypePointer>> const& getInterfaceFunctionList() const;
@@ -376,7 +377,7 @@ class EnumValue: public Declaration
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
- TypePointer getType(ContractDefinition const* = nullptr) const;
+ TypePointer getType(ContractDefinition const* = nullptr) const override;
};
/**