ast: add Declaration::functionType()

This commit is contained in:
Yoichi Hirai 2017-01-10 16:26:13 +01:00
parent e254a59bd2
commit eda147f47b
No known key found for this signature in database
GPG Key ID: E7B75D080FCF7992
3 changed files with 80 additions and 14 deletions

View File

@ -264,22 +264,15 @@ vector<Declaration const*> NameAndTypeResolver::cleanedDeclarations(
solAssert(dynamic_cast<FunctionDefinition const*>(*it) || dynamic_cast<VariableDeclaration const*>(*it),
"Found overloading involving something not a function or a variable");
unique_ptr<FunctionType const> functionType {};
if (FunctionDefinition const* functionDefinition = dynamic_cast<FunctionDefinition const*>(*it))
{
functionType = unique_ptr<FunctionType const>(new FunctionType(*functionDefinition));
for (auto parameter: functionType->parameterTypes() + functionType->returnParameterTypes())
if (!parameter)
reportFatalDeclarationError(_identifier.location(), "Function type can not be used in this context");
}
else
{
VariableDeclaration const* variableDeclaration = dynamic_cast<VariableDeclaration const*>(*it);
functionType = unique_ptr<FunctionType const>(new FunctionType(*variableDeclaration));
}
shared_ptr<FunctionType const> functionType { (*it)->functionType(false) };
if (!functionType)
functionType = (*it)->functionType(true);
solAssert(functionType, "failed to determine the function type of the overloaded");
for (auto parameter: functionType->parameterTypes() + functionType->returnParameterTypes())
if (!parameter)
reportFatalDeclarationError(_identifier.location(), "Function type can not be used in this context");
if (uniqueFunctions.end() == find_if(
uniqueFunctions.begin(),
uniqueFunctions.end(),

View File

@ -274,6 +274,45 @@ TypeDeclarationAnnotation& EnumDefinition::annotation() const
return static_cast<TypeDeclarationAnnotation&>(*m_annotation);
}
shared_ptr<FunctionType const> FunctionDefinition::functionType(bool _internal) const
{
if (_internal)
{
switch (visibility())
{
case Declaration::Visibility::Default:
solAssert(false, "visibility() should not return Default");
case Declaration::Visibility::Private:
case Declaration::Visibility::Internal:
case Declaration::Visibility::Public:
return make_shared<FunctionType const>(*this, _internal);
case Declaration::Visibility::External:
return {};
default:
solAssert(false, "visibility() should not return a Visibility");
}
}
else
{
switch (visibility())
{
case Declaration::Visibility::Default:
solAssert(false, "visibility() should not return Default");
case Declaration::Visibility::Private:
case Declaration::Visibility::Internal:
return {};
case Declaration::Visibility::Public:
case Declaration::Visibility::External:
return make_shared<FunctionType const>(*this, _internal);
default:
solAssert(false, "visibility() should not return a Visibility");
}
}
// To make the compiler happy
return {};
}
TypePointer FunctionDefinition::type() const
{
return make_shared<FunctionType>(*this);
@ -365,6 +404,28 @@ TypePointer VariableDeclaration::type() const
return annotation().type;
}
shared_ptr<FunctionType const> VariableDeclaration::functionType(bool _internal) const
{
if (_internal)
return {};
switch (visibility())
{
case Declaration::Visibility::Default:
solAssert(false, "visibility() should not return Default");
case Declaration::Visibility::Private:
case Declaration::Visibility::Internal:
return {};
case Declaration::Visibility::Public:
case Declaration::Visibility::External:
return make_shared<FunctionType const>(*this);
default:
solAssert(false, "visibility() should not return a Visibility");
}
// To make the compiler happy
return {};
}
VariableDeclarationAnnotation& VariableDeclaration::annotation() const
{
if (!m_annotation)

View File

@ -171,6 +171,10 @@ public:
/// This can only be called once types of variable declarations have already been resolved.
virtual TypePointer type() const = 0;
/// @param _internal false indicates external interface is concerned, true indicates internal interface is concerned.
/// @returns null when it is not accessible as a function.
virtual std::shared_ptr<FunctionType const> functionType(bool /*_internal*/) const { return {}; }
protected:
virtual Visibility defaultVisibility() const { return Visibility::Public; }
@ -581,6 +585,10 @@ public:
virtual TypePointer type() const override;
/// @param _internal false indicates external interface is concerned, true indicates internal interface is concerned.
/// @returns null when it is not accessible as a function.
virtual std::shared_ptr<FunctionType const> functionType(bool /*_internal*/) const override;
virtual FunctionDefinitionAnnotation& annotation() const override;
private:
@ -643,6 +651,10 @@ public:
virtual TypePointer type() const override;
/// @param _internal false indicates external interface is concerned, true indicates internal interface is concerned.
/// @returns null when it is not accessible as a function.
virtual std::shared_ptr<FunctionType const> functionType(bool /*_internal*/) const override;
virtual VariableDeclarationAnnotation& annotation() const override;
protected: