diff options
Diffstat (limited to 'libsolidity/ast')
-rw-r--r-- | libsolidity/ast/AST.cpp | 8 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 56 | ||||
-rw-r--r-- | libsolidity/ast/ASTForward.h | 1 | ||||
-rw-r--r-- | libsolidity/ast/ASTJsonConverter.cpp | 28 | ||||
-rw-r--r-- | libsolidity/ast/ASTJsonConverter.h | 2 | ||||
-rw-r--r-- | libsolidity/ast/ASTPrinter.cpp | 14 | ||||
-rw-r--r-- | libsolidity/ast/ASTPrinter.h | 2 | ||||
-rw-r--r-- | libsolidity/ast/ASTVisitor.h | 4 | ||||
-rw-r--r-- | libsolidity/ast/AST_accept.h | 20 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 149 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 18 |
11 files changed, 269 insertions, 33 deletions
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 695d9881..305668e7 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -160,22 +160,22 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::inter return *m_interfaceFunctionList; } -string const& ContractDefinition::devDocumentation() const +Json::Value const& ContractDefinition::devDocumentation() const { return m_devDocumentation; } -string const& ContractDefinition::userDocumentation() const +Json::Value const& ContractDefinition::userDocumentation() const { return m_userDocumentation; } -void ContractDefinition::setDevDocumentation(string const& _devDocumentation) +void ContractDefinition::setDevDocumentation(Json::Value const& _devDocumentation) { m_devDocumentation = _devDocumentation; } -void ContractDefinition::setUserDocumentation(string const& _userDocumentation) +void ContractDefinition::setUserDocumentation(Json::Value const& _userDocumentation) { m_userDocumentation = _userDocumentation; } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 7ed4ddce..a2b70fe9 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -35,6 +35,7 @@ #include <libsolidity/ast/Types.h> #include <libsolidity/interface/Exceptions.h> #include <libsolidity/ast/ASTAnnotations.h> +#include <json/json.h> namespace dev { @@ -343,11 +344,11 @@ public: /// Returns the fallback function or nullptr if no fallback function was specified. FunctionDefinition const* fallbackFunction() const; - std::string const& userDocumentation() const; - void setUserDocumentation(std::string const& _userDocumentation); + Json::Value const& userDocumentation() const; + void setUserDocumentation(Json::Value const& _userDocumentation); - std::string const& devDocumentation() const; - void setDevDocumentation(std::string const& _devDocumentation); + Json::Value const& devDocumentation() const; + void setDevDocumentation(Json::Value const& _devDocumentation); virtual TypePointer type() const override; @@ -359,8 +360,8 @@ private: bool m_isLibrary; // parsed Natspec documentation of the contract. - std::string m_userDocumentation; - std::string m_devDocumentation; + Json::Value m_userDocumentation; + Json::Value m_devDocumentation; std::vector<ContractDefinition const*> m_linearizedBaseContracts; mutable std::unique_ptr<std::vector<std::pair<FixedHash<4>, FunctionTypePointer>>> m_interfaceFunctionList; @@ -822,6 +823,41 @@ private: }; /** + * A literal function type. Its source form is "function (paramType1, paramType2) internal / external returns (retType1, retType2)" + */ +class FunctionTypeName: public TypeName +{ +public: + FunctionTypeName( + SourceLocation const& _location, + ASTPointer<ParameterList> const& _parameterTypes, + ASTPointer<ParameterList> const& _returnTypes, + Declaration::Visibility _visibility, + bool _isDeclaredConst, + bool _isPayable + ): + TypeName(_location), m_parameterTypes(_parameterTypes), m_returnTypes(_returnTypes), + m_visibility(_visibility), m_isDeclaredConst(_isDeclaredConst), m_isPayable(_isPayable) + {} + virtual void accept(ASTVisitor& _visitor) override; + virtual void accept(ASTConstVisitor& _visitor) const override; + + std::vector<ASTPointer<VariableDeclaration>> const& parameterTypes() const { return m_parameterTypes->parameters(); } + std::vector<ASTPointer<VariableDeclaration>> const& returnParameterTypes() const { return m_returnTypes->parameters(); } + + Declaration::Visibility visibility() const { return m_visibility; } + bool isDeclaredConst() const { return m_isDeclaredConst; } + bool isPayable() const { return m_isPayable; } + +private: + ASTPointer<ParameterList> m_parameterTypes; + ASTPointer<ParameterList> m_returnTypes; + Declaration::Visibility m_visibility; + bool m_isDeclaredConst; + bool m_isPayable; +}; + +/** * A mapping type. Its source form is "mapping('keyType' => 'valueType')" */ class Mapping: public TypeName @@ -1005,18 +1041,22 @@ public: SourceLocation const& _location, ASTPointer<ASTString> const& _docString, ASTPointer<Expression> const& _condition, - ASTPointer<Statement> const& _body + ASTPointer<Statement> const& _body, + bool _isDoWhile ): - BreakableStatement(_location, _docString), m_condition(_condition), m_body(_body) {} + BreakableStatement(_location, _docString), m_condition(_condition), m_body(_body), + m_isDoWhile(_isDoWhile) {} virtual void accept(ASTVisitor& _visitor) override; virtual void accept(ASTConstVisitor& _visitor) const override; Expression const& condition() const { return *m_condition; } Statement const& body() const { return *m_body; } + bool isDoWhile() const { return m_isDoWhile; } private: ASTPointer<Expression> m_condition; ASTPointer<Statement> m_body; + bool m_isDoWhile; }; /** diff --git a/libsolidity/ast/ASTForward.h b/libsolidity/ast/ASTForward.h index 59fc1b57..52bbf396 100644 --- a/libsolidity/ast/ASTForward.h +++ b/libsolidity/ast/ASTForward.h @@ -54,6 +54,7 @@ class MagicVariableDeclaration; class TypeName; class ElementaryTypeName; class UserDefinedTypeName; +class FunctionTypeName; class Mapping; class ArrayTypeName; class Statement; diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index 0ea5e093..37dfd3c6 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -174,7 +174,8 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node) addJsonNode(_node, "FunctionDefinition", { make_pair("name", _node.name()), make_pair("public", _node.isPublic()), - make_pair("constant", _node.isDeclaredConst()) + make_pair("constant", _node.isDeclaredConst()), + make_pair("payable", _node.isPayable()) }, true); return true; } @@ -225,6 +226,20 @@ bool ASTJsonConverter::visit(UserDefinedTypeName const& _node) return true; } +bool ASTJsonConverter::visit(FunctionTypeName const& _node) +{ + string visibility = "internal"; + if (_node.visibility() == Declaration::Visibility::External) + visibility = "external"; + + addJsonNode(_node, "FunctionTypeName", { + make_pair("payable", _node.isPayable()), + make_pair("visibility", visibility), + make_pair("constant", _node.isDeclaredConst()) + }, true); + return true; +} + bool ASTJsonConverter::visit(Mapping const& _node) { addJsonNode(_node, "Mapping", {}, true); @@ -263,7 +278,11 @@ bool ASTJsonConverter::visit(IfStatement const& _node) bool ASTJsonConverter::visit(WhileStatement const& _node) { - addJsonNode(_node, "WhileStatement", {}, true); + addJsonNode( + _node, + _node.isDoWhile() ? "DoWhileStatement" : "WhileStatement", + {}, + true); return true; } @@ -502,6 +521,11 @@ void ASTJsonConverter::endVisit(UserDefinedTypeName const&) { } +void ASTJsonConverter::endVisit(FunctionTypeName const&) +{ + goUp(); +} + void ASTJsonConverter::endVisit(Mapping const&) { goUp(); diff --git a/libsolidity/ast/ASTJsonConverter.h b/libsolidity/ast/ASTJsonConverter.h index 7c7b37f8..0a71779c 100644 --- a/libsolidity/ast/ASTJsonConverter.h +++ b/libsolidity/ast/ASTJsonConverter.h @@ -69,6 +69,7 @@ public: bool visit(TypeName const& _node) override; bool visit(ElementaryTypeName const& _node) override; bool visit(UserDefinedTypeName const& _node) override; + bool visit(FunctionTypeName const& _node) override; bool visit(Mapping const& _node) override; bool visit(ArrayTypeName const& _node) override; bool visit(InlineAssembly const& _node) override; @@ -114,6 +115,7 @@ public: void endVisit(TypeName const&) override; void endVisit(ElementaryTypeName const&) override; void endVisit(UserDefinedTypeName const&) override; + void endVisit(FunctionTypeName const&) override; void endVisit(Mapping const&) override; void endVisit(ArrayTypeName const&) override; void endVisit(InlineAssembly const&) override; diff --git a/libsolidity/ast/ASTPrinter.cpp b/libsolidity/ast/ASTPrinter.cpp index a9de457a..053b9b82 100644 --- a/libsolidity/ast/ASTPrinter.cpp +++ b/libsolidity/ast/ASTPrinter.cpp @@ -164,6 +164,13 @@ bool ASTPrinter::visit(UserDefinedTypeName const& _node) return goDeeper(); } +bool ASTPrinter::visit(FunctionTypeName const& _node) +{ + writeLine("FunctionTypeName"); + printSourcePart(_node); + return goDeeper(); +} + bool ASTPrinter::visit(Mapping const& _node) { writeLine("Mapping"); @@ -208,7 +215,7 @@ bool ASTPrinter::visit(IfStatement const& _node) bool ASTPrinter::visit(WhileStatement const& _node) { - writeLine("WhileStatement"); + writeLine(_node.isDoWhile() ? "DoWhileStatement" : "WhileStatement"); printSourcePart(_node); return goDeeper(); } @@ -442,6 +449,11 @@ void ASTPrinter::endVisit(UserDefinedTypeName const&) m_indentation--; } +void ASTPrinter::endVisit(FunctionTypeName const&) +{ + m_indentation--; +} + void ASTPrinter::endVisit(Mapping const&) { m_indentation--; diff --git a/libsolidity/ast/ASTPrinter.h b/libsolidity/ast/ASTPrinter.h index f0ab1098..9f88a1fd 100644 --- a/libsolidity/ast/ASTPrinter.h +++ b/libsolidity/ast/ASTPrinter.h @@ -63,6 +63,7 @@ public: bool visit(TypeName const& _node) override; bool visit(ElementaryTypeName const& _node) override; bool visit(UserDefinedTypeName const& _node) override; + bool visit(FunctionTypeName const& _node) override; bool visit(Mapping const& _node) override; bool visit(ArrayTypeName const& _node) override; bool visit(InlineAssembly const& _node) override; @@ -106,6 +107,7 @@ public: void endVisit(TypeName const&) override; void endVisit(ElementaryTypeName const&) override; void endVisit(UserDefinedTypeName const&) override; + void endVisit(FunctionTypeName const&) override; void endVisit(Mapping const&) override; void endVisit(ArrayTypeName const&) override; void endVisit(InlineAssembly const&) override; diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h index 3a1b55d3..e72afe69 100644 --- a/libsolidity/ast/ASTVisitor.h +++ b/libsolidity/ast/ASTVisitor.h @@ -61,6 +61,7 @@ public: virtual bool visit(TypeName& _node) { return visitNode(_node); } virtual bool visit(ElementaryTypeName& _node) { return visitNode(_node); } virtual bool visit(UserDefinedTypeName& _node) { return visitNode(_node); } + virtual bool visit(FunctionTypeName& _node) { return visitNode(_node); } virtual bool visit(Mapping& _node) { return visitNode(_node); } virtual bool visit(ArrayTypeName& _node) { return visitNode(_node); } virtual bool visit(InlineAssembly& _node) { return visitNode(_node); } @@ -106,6 +107,7 @@ public: virtual void endVisit(TypeName& _node) { endVisitNode(_node); } virtual void endVisit(ElementaryTypeName& _node) { endVisitNode(_node); } virtual void endVisit(UserDefinedTypeName& _node) { endVisitNode(_node); } + virtual void endVisit(FunctionTypeName& _node) { endVisitNode(_node); } virtual void endVisit(Mapping& _node) { endVisitNode(_node); } virtual void endVisit(ArrayTypeName& _node) { endVisitNode(_node); } virtual void endVisit(InlineAssembly& _node) { endVisitNode(_node); } @@ -163,6 +165,7 @@ public: virtual bool visit(TypeName const& _node) { return visitNode(_node); } virtual bool visit(ElementaryTypeName const& _node) { return visitNode(_node); } virtual bool visit(UserDefinedTypeName const& _node) { return visitNode(_node); } + virtual bool visit(FunctionTypeName const& _node) { return visitNode(_node); } virtual bool visit(Mapping const& _node) { return visitNode(_node); } virtual bool visit(ArrayTypeName const& _node) { return visitNode(_node); } virtual bool visit(Block const& _node) { return visitNode(_node); } @@ -208,6 +211,7 @@ public: virtual void endVisit(TypeName const& _node) { endVisitNode(_node); } virtual void endVisit(ElementaryTypeName const& _node) { endVisitNode(_node); } virtual void endVisit(UserDefinedTypeName const& _node) { endVisitNode(_node); } + virtual void endVisit(FunctionTypeName const& _node) { endVisitNode(_node); } virtual void endVisit(Mapping const& _node) { endVisitNode(_node); } virtual void endVisit(ArrayTypeName const& _node) { endVisitNode(_node); } virtual void endVisit(Block const& _node) { endVisitNode(_node); } diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h index b5a3806b..f521e092 100644 --- a/libsolidity/ast/AST_accept.h +++ b/libsolidity/ast/AST_accept.h @@ -327,6 +327,26 @@ void UserDefinedTypeName::accept(ASTConstVisitor& _visitor) const _visitor.endVisit(*this); } +void FunctionTypeName::accept(ASTVisitor& _visitor) +{ + if (_visitor.visit(*this)) + { + m_parameterTypes->accept(_visitor); + m_returnTypes->accept(_visitor); + } + _visitor.endVisit(*this); +} + +void FunctionTypeName::accept(ASTConstVisitor& _visitor) const +{ + if (_visitor.visit(*this)) + { + m_parameterTypes->accept(_visitor); + m_returnTypes->accept(_visitor); + } + _visitor.endVisit(*this); +} + void Mapping::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this)) diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 7fe97fa7..4488398f 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -200,10 +200,10 @@ TypePointer Type::commonType(TypePointer const& _a, TypePointer const& _b) { if (!_a || !_b) return TypePointer(); - else if (_b->isImplicitlyConvertibleTo(*_a)) - return _a; - else if (_a->isImplicitlyConvertibleTo(*_b)) - return _b; + else if (_b->isImplicitlyConvertibleTo(*_a->mobileType())) + return _a->mobileType(); + else if (_a->isImplicitlyConvertibleTo(*_b->mobileType())) + return _b->mobileType(); else return TypePointer(); } @@ -1265,6 +1265,7 @@ TypePointer ArrayType::decodingType() const TypePointer ArrayType::interfaceType(bool _inLibrary) const { + // Note: This has to fulfill canBeUsedExternally(_inLibrary) == !!interfaceType(_inLibrary) if (_inLibrary && location() == DataLocation::Storage) return shared_from_this(); @@ -1282,6 +1283,21 @@ TypePointer ArrayType::interfaceType(bool _inLibrary) const return make_shared<ArrayType>(DataLocation::Memory, baseExt, m_length); } +bool ArrayType::canBeUsedExternally(bool _inLibrary) const +{ + // Note: This has to fulfill canBeUsedExternally(_inLibrary) == !!interfaceType(_inLibrary) + if (_inLibrary && location() == DataLocation::Storage) + return true; + else if (m_arrayKind != ArrayKind::Ordinary) + return true; + else if (!m_baseType->canBeUsedExternally(_inLibrary)) + return false; + else if (m_baseType->category() == Category::Array && m_baseType->isDynamicallySized()) + return false; + else + return true; +} + u256 ArrayType::memorySize() const { solAssert(!isDynamicallySized(), ""); @@ -1451,7 +1467,7 @@ u256 StructType::storageSize() const string StructType::toString(bool _short) const { - string ret = "struct " + m_struct.name(); + string ret = "struct " + m_struct.annotation().canonicalName; if (!_short) ret += " " + stringForReferencePart(); return ret; @@ -1561,7 +1577,7 @@ bool EnumType::operator==(Type const& _other) const unsigned EnumType::storageBytes() const { - size_t elements = m_enum.members().size(); + size_t elements = numberOfMembers(); if (elements <= 1) return 1; else @@ -1570,7 +1586,7 @@ unsigned EnumType::storageBytes() const string EnumType::toString(bool) const { - return string("enum ") + m_enum.name(); + return string("enum ") + m_enum.annotation().canonicalName; } string EnumType::canonicalName(bool) const @@ -1578,9 +1594,14 @@ string EnumType::canonicalName(bool) const return m_enum.annotation().canonicalName; } +size_t EnumType::numberOfMembers() const +{ + return m_enum.members().size(); +}; + bool EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) const { - return _convertTo.category() == category() || _convertTo.category() == Category::Integer; + return _convertTo == *this || _convertTo.category() == Category::Integer; } unsigned EnumType::memberValue(ASTString const& _member) const @@ -1699,7 +1720,7 @@ TypePointer TupleType::closestTemporaryType(TypePointer const& _targetType) cons FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal): m_location(_isInternal ? Location::Internal : Location::External), m_isConstant(_function.isDeclaredConst()), - m_isPayable(_function.isPayable()), + m_isPayable(_isInternal ? false : _function.isPayable()), m_declaration(&_function) { TypePointers params; @@ -1800,6 +1821,38 @@ FunctionType::FunctionType(EventDefinition const& _event): swap(paramNames, m_parameterNames); } +FunctionType::FunctionType(FunctionTypeName const& _typeName): + m_location(_typeName.visibility() == VariableDeclaration::Visibility::External ? Location::External : Location::Internal), + m_isConstant(_typeName.isDeclaredConst()), + m_isPayable(_typeName.isPayable()) +{ + if (_typeName.isPayable()) + { + solAssert(m_location == Location::External, "Internal payable function type used."); + solAssert(!m_isConstant, "Payable constant function"); + } + for (auto const& t: _typeName.parameterTypes()) + { + solAssert(t->annotation().type, "Type not set for parameter."); + if (m_location == Location::External) + solAssert( + t->annotation().type->canBeUsedExternally(false), + "Internal type used as parameter for external function." + ); + m_parameterTypes.push_back(t->annotation().type); + } + for (auto const& t: _typeName.returnParameterTypes()) + { + solAssert(t->annotation().type, "Type not set for return parameter."); + if (m_location == Location::External) + solAssert( + t->annotation().type->canBeUsedExternally(false), + "Internal type used as return parameter for external function." + ); + m_returnParameterTypes.push_back(t->annotation().type); + } +} + FunctionTypePointer FunctionType::newExpressionType(ContractDefinition const& _contract) { FunctionDefinition const* constructor = _contract.constructor(); @@ -1875,22 +1928,69 @@ bool FunctionType::operator==(Type const& _other) const return true; } +TypePointer FunctionType::unaryOperatorResult(Token::Value _operator) const +{ + if (_operator == Token::Value::Delete) + return make_shared<TupleType>(); + return TypePointer(); +} + +string FunctionType::canonicalName(bool) const +{ + solAssert(m_location == Location::External, ""); + return "function"; +} + string FunctionType::toString(bool _short) const { string name = "function ("; for (auto it = m_parameterTypes.begin(); it != m_parameterTypes.end(); ++it) name += (*it)->toString(_short) + (it + 1 == m_parameterTypes.end() ? "" : ","); - name += ") returns ("; - for (auto it = m_returnParameterTypes.begin(); it != m_returnParameterTypes.end(); ++it) - name += (*it)->toString(_short) + (it + 1 == m_returnParameterTypes.end() ? "" : ","); - return name + ")"; + name += ")"; + if (m_isConstant) + name += " constant"; + if (m_isPayable) + name += " payable"; + if (m_location == Location::External) + name += " external"; + if (!m_returnParameterTypes.empty()) + { + name += " returns ("; + for (auto it = m_returnParameterTypes.begin(); it != m_returnParameterTypes.end(); ++it) + name += (*it)->toString(_short) + (it + 1 == m_returnParameterTypes.end() ? "" : ","); + name += ")"; + } + return name; +} + +unsigned FunctionType::calldataEncodedSize(bool _padded) const +{ + unsigned size = storageBytes(); + if (_padded) + size = ((size + 31) / 32) * 32; + return size; } u256 FunctionType::storageSize() const { - BOOST_THROW_EXCEPTION( - InternalCompilerError() - << errinfo_comment("Storage size of non-storable function type requested.")); + if (m_location == Location::External || m_location == Location::Internal) + return 1; + else + BOOST_THROW_EXCEPTION( + InternalCompilerError() + << errinfo_comment("Storage size of non-storable function type requested.")); +} + +unsigned FunctionType::storageBytes() const +{ + if (m_location == Location::External) + return 20 + 4; + else if (m_location == Location::Internal) + return 8; // it should really not be possible to create larger programs + else + BOOST_THROW_EXCEPTION( + InternalCompilerError() + << errinfo_comment("Storage size of non-storable function type requested.")); } unsigned FunctionType::sizeOnStack() const @@ -2013,6 +2113,23 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con } } +TypePointer FunctionType::encodingType() const +{ + // Only external functions can be encoded, internal functions cannot leave code boundaries. + if (m_location == Location::External) + return shared_from_this(); + else + return TypePointer(); +} + +TypePointer FunctionType::interfaceType(bool /*_inLibrary*/) const +{ + if (m_location == Location::External) + return shared_from_this(); + else + return TypePointer(); +} + bool FunctionType::canTakeArguments(TypePointers const& _argumentTypes, TypePointer const& _selfType) const { solAssert(!bound() || _selfType, ""); diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 3f94d11a..34fcfc82 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -254,6 +254,9 @@ public: /// @param _inLibrary if set, returns types as used in a library, e.g. struct and contract types /// are returned without modification. virtual TypePointer interfaceType(bool /*_inLibrary*/) const { return TypePointer(); } + /// @returns true iff this type can be passed on via calls (to libraries if _inLibrary is true), + /// should be have identical to !!interfaceType(_inLibrary) but might do optimizations. + virtual bool canBeUsedExternally(bool _inLibrary) const { return !!interfaceType(_inLibrary); } private: /// @returns a member list containing all members added to this type by `using for` directives. @@ -580,6 +583,7 @@ public: virtual TypePointer encodingType() const override; virtual TypePointer decodingType() const override; virtual TypePointer interfaceType(bool _inLibrary) const override; + virtual bool canBeUsedExternally(bool _inLibrary) const override; /// @returns true if this is a byte array or a string bool isByteArray() const { return m_arrayKind != ArrayKind::Ordinary; } @@ -738,6 +742,7 @@ public: EnumDefinition const& enumDefinition() const { return m_enum; } /// @returns the value that the string has in the Enum unsigned int memberValue(ASTString const& _member) const; + size_t numberOfMembers() const; private: EnumDefinition const& m_enum; @@ -820,6 +825,8 @@ public: explicit FunctionType(VariableDeclaration const& _varDecl); /// Creates the function type of an event. explicit FunctionType(EventDefinition const& _event); + /// Creates the type of a function type name. + explicit FunctionType(FunctionTypeName const& _typeName); /// Function type constructor to be used for a plain type (not derived from a declaration). FunctionType( strings const& _parameterTypes, @@ -889,12 +896,19 @@ public: TypePointer selfType() const; virtual bool operator==(Type const& _other) const override; + virtual TypePointer unaryOperatorResult(Token::Value _operator) const override; + virtual std::string canonicalName(bool /*_addDataLocation*/) const override; virtual std::string toString(bool _short) const override; - virtual bool canBeStored() const override { return false; } + virtual unsigned calldataEncodedSize(bool _padded) const override; + virtual bool canBeStored() const override { return m_location == Location::Internal || m_location == Location::External; } virtual u256 storageSize() const override; - virtual bool canLiveOutsideStorage() const override { return false; } + virtual unsigned storageBytes() const override; + virtual bool isValueType() const override { return true; } + virtual bool canLiveOutsideStorage() const override { return m_location == Location::Internal || m_location == Location::External; } virtual unsigned sizeOnStack() const override; virtual MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override; + virtual TypePointer encodingType() const override; + virtual TypePointer interfaceType(bool _inLibrary) const override; /// @returns TypePointer of a new FunctionType object. All input/return parameters are an /// appropriate external types (i.e. the interfaceType()s) of input/return parameters of |