diff options
Diffstat (limited to 'libsolidity/analysis/ReferencesResolver.cpp')
-rw-r--r-- | libsolidity/analysis/ReferencesResolver.cpp | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/libsolidity/analysis/ReferencesResolver.cpp b/libsolidity/analysis/ReferencesResolver.cpp index a7b9e8b8..a0768a34 100644 --- a/libsolidity/analysis/ReferencesResolver.cpp +++ b/libsolidity/analysis/ReferencesResolver.cpp @@ -83,6 +83,31 @@ void ReferencesResolver::endVisit(UserDefinedTypeName const& _typeName) fatalTypeError(_typeName.location(), "Name has to refer to a struct, enum or contract."); } +void ReferencesResolver::endVisit(FunctionTypeName const& _typeName) +{ + switch (_typeName.visibility()) + { + case VariableDeclaration::Visibility::Default: + case VariableDeclaration::Visibility::Internal: + case VariableDeclaration::Visibility::External: + break; + default: + typeError(_typeName.location(), "Invalid visibility, can only be \"external\" or \"internal\"."); + } + + if (_typeName.isPayable() && _typeName.visibility() != VariableDeclaration::Visibility::External) + fatalTypeError(_typeName.location(), "Only external function types can be payable."); + if (_typeName.visibility() == VariableDeclaration::Visibility::External) + for (auto const& t: _typeName.parameterTypes() + _typeName.returnParameterTypes()) + { + solAssert(t->annotation().type, "Type not set for parameter."); + if (!t->annotation().type->canBeUsedExternally(false)) + fatalTypeError(t->location(), "Internal type cannot be used for external function type."); + } + + _typeName.annotation().type = make_shared<FunctionType>(_typeName); +} + void ReferencesResolver::endVisit(Mapping const& _typeName) { TypePointer keyType = _typeName.keyType().annotation().type; |