diff options
-rw-r--r-- | libsolidity/analysis/NameAndTypeResolver.cpp | 21 | ||||
-rw-r--r-- | libsolidity/ast/AST.cpp | 61 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 12 |
3 files changed, 80 insertions, 14 deletions
diff --git a/libsolidity/analysis/NameAndTypeResolver.cpp b/libsolidity/analysis/NameAndTypeResolver.cpp index 260965ae..47a9df1b 100644 --- a/libsolidity/analysis/NameAndTypeResolver.cpp +++ b/libsolidity/analysis/NameAndTypeResolver.cpp @@ -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(), diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 78d8949c..ac92eaa3 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -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) diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index ab4be1ea..088d68db 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -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: |