diff options
-rw-r--r-- | libdevcore/Result.h | 83 | ||||
-rw-r--r-- | libsolidity/analysis/ConstantEvaluator.cpp | 2 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 96 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 109 |
4 files changed, 188 insertions, 102 deletions
diff --git a/libdevcore/Result.h b/libdevcore/Result.h new file mode 100644 index 00000000..c1abf380 --- /dev/null +++ b/libdevcore/Result.h @@ -0,0 +1,83 @@ +/* + This file is part of solidity. + + solidity is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + solidity is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with solidity. If not, see <http://www.gnu.org/licenses/>. +*/ +#pragma once + +#include <string> + +namespace dev +{ + +/// Simple generic result that holds a value and an optional error message. +/// Results can be implicitly converted to and created from the type of +/// the value they hold. +/// +/// Result<bool> check() +/// { +/// if (false) +/// return Result<bool>(false, "Error message.") +/// return true; +/// } +/// +/// A result can also be instantiated using one of the factory methods it provides: +/// +/// using BoolResult = Result<bool>; +/// BoolResult check() +/// { +/// if (false) +/// return BoolResult::failure("Error message"); +/// return BoolResult::success(true); +/// } +/// +/// +struct ResultError { std::string reason; }; + +template <class ResultType> +class Result +{ +public: + /// @{ + /// @name Factory functions + /// Factory functions that provide a verbose way to create a result + static Result<ResultType> Ok(ResultType _value) { return Result(std::move(_value)); } + static Result<ResultType> Err() { return Result(ResultError{std::string()}); } + static Result<ResultType> Err(std::string _error) { return Result(ResultError{std::move(_error)}); } + /// @} + + Result(ResultType _value): m_value(std::move(_value)) {} + Result(ResultError _error): m_error(std::move(_error.reason)) {} + Result(ResultType _value, ResultError _error): m_value(std::move(_value)), m_error(std::move(_error.reason)) {} + + /// @{ + /// @name Wrapper functions + /// Wrapper functions that provide implicit conversions to and explicit retrieval of + /// the value this result holds. + /// If the result is an error, accessing the value results in undefined behaviour. + operator ResultType const&() const { return m_value; } + ResultType& operator*() const { return m_value; } + ResultType const& get() const { return m_value; } + ResultType& get() { return m_value; } + /// @} + + /// @returns the error message (can be empty). + std::string const& err() const { return m_error; } + +private: + ResultType m_value; + std::string m_error; +}; + +} diff --git a/libsolidity/analysis/ConstantEvaluator.cpp b/libsolidity/analysis/ConstantEvaluator.cpp index 9d041ce5..26d9584b 100644 --- a/libsolidity/analysis/ConstantEvaluator.cpp +++ b/libsolidity/analysis/ConstantEvaluator.cpp @@ -41,7 +41,7 @@ void ConstantEvaluator::endVisit(BinaryOperation const& _operation) auto right = type(_operation.rightExpression()); if (left && right) { - auto commonType = left->binaryOperatorResult(_operation.getOperator(), right); + TypePointer commonType = left->binaryOperatorResult(_operation.getOperator(), right); if (!commonType) m_errorReporter.fatalTypeError( _operation.location(), diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 6cadb5f3..f67d0b12 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -466,7 +466,7 @@ string AddressType::richIdentifier() const return "t_address"; } -bool AddressType::isImplicitlyConvertibleTo(Type const& _other) const +BoolResult AddressType::isImplicitlyConvertibleTo(Type const& _other) const { if (_other.category() != category()) return false; @@ -475,7 +475,7 @@ bool AddressType::isImplicitlyConvertibleTo(Type const& _other) const return other.m_stateMutability <= m_stateMutability; } -bool AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult AddressType::isExplicitlyConvertibleTo(Type const& _convertTo) const { if (auto const* contractType = dynamic_cast<ContractType const*>(&_convertTo)) return (m_stateMutability >= StateMutability::Payable) || !contractType->isPayable(); @@ -504,13 +504,13 @@ u256 AddressType::literalValue(Literal const* _literal) const return u256(_literal->valueWithoutUnderscores()); } -TypePointer AddressType::unaryOperatorResult(Token _operator) const +TypeResult AddressType::unaryOperatorResult(Token _operator) const { return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer(); } -TypePointer AddressType::binaryOperatorResult(Token _operator, TypePointer const& _other) const +TypeResult AddressType::binaryOperatorResult(Token _operator, TypePointer const& _other) const { // Addresses can only be compared. if (!TokenTraits::isCompareOp(_operator)) @@ -576,7 +576,7 @@ string IntegerType::richIdentifier() const return "t_" + string(isSigned() ? "" : "u") + "int" + to_string(numBits()); } -bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const { if (_convertTo.category() == category()) { @@ -597,7 +597,7 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const return false; } -bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const { return _convertTo.category() == category() || _convertTo.category() == Category::Address || @@ -607,18 +607,18 @@ bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const _convertTo.category() == Category::FixedPoint; } -TypePointer IntegerType::unaryOperatorResult(Token _operator) const +TypeResult IntegerType::unaryOperatorResult(Token _operator) const { // "delete" is ok for all integer types if (_operator == Token::Delete) - return make_shared<TupleType>(); + return TypeResult::Ok(make_shared<TupleType>()); // we allow +, -, ++ and -- else if (_operator == Token::Add || _operator == Token::Sub || _operator == Token::Inc || _operator == Token::Dec || _operator == Token::BitNot) - return shared_from_this(); + return TypeResult::Ok(shared_from_this()); else - return TypePointer(); + return TypeResult::Err(); } bool IntegerType::operator==(Type const& _other) const @@ -651,7 +651,7 @@ bigint IntegerType::maxValue() const return (bigint(1) << m_bits) - 1; } -TypePointer IntegerType::binaryOperatorResult(Token _operator, TypePointer const& _other) const +TypeResult IntegerType::binaryOperatorResult(Token _operator, TypePointer const& _other) const { if ( _other->category() != Category::RationalNumber && @@ -704,7 +704,7 @@ string FixedPointType::richIdentifier() const return "t_" + string(isSigned() ? "" : "u") + "fixed" + to_string(m_totalBits) + "x" + to_string(m_fractionalDigits); } -bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const { if (_convertTo.category() == category()) { @@ -717,18 +717,18 @@ bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const return false; } -bool FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult FixedPointType::isExplicitlyConvertibleTo(Type const& _convertTo) const { return _convertTo.category() == category() || _convertTo.category() == Category::Integer; } -TypePointer FixedPointType::unaryOperatorResult(Token _operator) const +TypeResult FixedPointType::unaryOperatorResult(Token _operator) const { switch(_operator) { case Token::Delete: // "delete" is ok for all fixed types - return make_shared<TupleType>(); + return TypeResult(make_shared<TupleType>()); case Token::Add: case Token::Sub: case Token::Inc: @@ -771,7 +771,7 @@ bigint FixedPointType::minIntegerValue() const return bigint(0); } -TypePointer FixedPointType::binaryOperatorResult(Token _operator, TypePointer const& _other) const +TypeResult FixedPointType::binaryOperatorResult(Token _operator, TypePointer const& _other) const { auto commonType = Type::commonType(shared_from_this(), _other); @@ -957,7 +957,7 @@ tuple<bool, rational> RationalNumberType::isValidLiteral(Literal const& _literal return make_tuple(true, value); } -bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const { switch (_convertTo.category()) { @@ -995,7 +995,7 @@ bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const } } -bool RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const { if (isImplicitlyConvertibleTo(_convertTo)) return true; @@ -1008,7 +1008,7 @@ bool RationalNumberType::isExplicitlyConvertibleTo(Type const& _convertTo) const return false; } -TypePointer RationalNumberType::unaryOperatorResult(Token _operator) const +TypeResult RationalNumberType::unaryOperatorResult(Token _operator) const { rational value; switch (_operator) @@ -1029,10 +1029,10 @@ TypePointer RationalNumberType::unaryOperatorResult(Token _operator) const default: return TypePointer(); } - return make_shared<RationalNumberType>(value); + return TypeResult(make_shared<RationalNumberType>(value)); } -TypePointer RationalNumberType::binaryOperatorResult(Token _operator, TypePointer const& _other) const +TypeResult RationalNumberType::binaryOperatorResult(Token _operator, TypePointer const& _other) const { if (_other->category() == Category::Integer || _other->category() == Category::FixedPoint) { @@ -1214,7 +1214,7 @@ TypePointer RationalNumberType::binaryOperatorResult(Token _operator, TypePointe if (value.numerator() != 0 && max(mostSignificantBit(abs(value.numerator())), mostSignificantBit(abs(value.denominator()))) > 4096) return TypePointer(); - return make_shared<RationalNumberType>(value); + return TypeResult(make_shared<RationalNumberType>(value)); } } @@ -1354,7 +1354,7 @@ StringLiteralType::StringLiteralType(Literal const& _literal): { } -bool StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const { if (auto fixedBytes = dynamic_cast<FixedBytesType const*>(&_convertTo)) return size_t(fixedBytes->numBytes()) >= m_value.size(); @@ -1409,7 +1409,7 @@ FixedBytesType::FixedBytesType(unsigned _bytes): m_bytes(_bytes) ); } -bool FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) const { if (_convertTo.category() != category()) return false; @@ -1417,7 +1417,7 @@ bool FixedBytesType::isImplicitlyConvertibleTo(Type const& _convertTo) const return convertTo.m_bytes >= m_bytes; } -bool FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const { return (_convertTo.category() == Category::Integer && numBytes() * 8 == dynamic_cast<IntegerType const&>(_convertTo).numBits()) || (_convertTo.category() == Category::Address && numBytes() == 20) || @@ -1425,18 +1425,18 @@ bool FixedBytesType::isExplicitlyConvertibleTo(Type const& _convertTo) const _convertTo.category() == category(); } -TypePointer FixedBytesType::unaryOperatorResult(Token _operator) const +TypeResult FixedBytesType::unaryOperatorResult(Token _operator) const { // "delete" and "~" is okay for FixedBytesType if (_operator == Token::Delete) - return make_shared<TupleType>(); + return TypeResult(make_shared<TupleType>()); else if (_operator == Token::BitNot) return shared_from_this(); return TypePointer(); } -TypePointer FixedBytesType::binaryOperatorResult(Token _operator, TypePointer const& _other) const +TypeResult FixedBytesType::binaryOperatorResult(Token _operator, TypePointer const& _other) const { if (TokenTraits::isShiftOp(_operator)) { @@ -1452,7 +1452,7 @@ TypePointer FixedBytesType::binaryOperatorResult(Token _operator, TypePointer co // FixedBytes can be compared and have bitwise operators applied to them if (TokenTraits::isCompareOp(_operator) || TokenTraits::isBitOp(_operator)) - return commonType; + return TypeResult(commonType); return TypePointer(); } @@ -1486,14 +1486,14 @@ u256 BoolType::literalValue(Literal const* _literal) const solAssert(false, "Bool type constructed from non-boolean literal."); } -TypePointer BoolType::unaryOperatorResult(Token _operator) const +TypeResult BoolType::unaryOperatorResult(Token _operator) const { if (_operator == Token::Delete) - return make_shared<TupleType>(); + return TypeResult(make_shared<TupleType>()); return (_operator == Token::Not) ? shared_from_this() : TypePointer(); } -TypePointer BoolType::binaryOperatorResult(Token _operator, TypePointer const& _other) const +TypeResult BoolType::binaryOperatorResult(Token _operator, TypePointer const& _other) const { if (category() != _other->category()) return TypePointer(); @@ -1503,7 +1503,7 @@ TypePointer BoolType::binaryOperatorResult(Token _operator, TypePointer const& _ return TypePointer(); } -bool ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const { if (*this == _convertTo) return true; @@ -1520,7 +1520,7 @@ bool ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const return false; } -bool ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const { if (auto const* addressType = dynamic_cast<AddressType const*>(&_convertTo)) return isPayable() || (addressType->stateMutability() < StateMutability::Payable); @@ -1533,14 +1533,14 @@ bool ContractType::isPayable() const return fallbackFunction && fallbackFunction->isPayable(); } -TypePointer ContractType::unaryOperatorResult(Token _operator) const +TypeResult ContractType::unaryOperatorResult(Token _operator) const { if (isSuper()) return TypePointer{}; return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer(); } -TypePointer ReferenceType::unaryOperatorResult(Token _operator) const +TypeResult ReferenceType::unaryOperatorResult(Token _operator) const { if (_operator != Token::Delete) return TypePointer(); @@ -1551,7 +1551,7 @@ TypePointer ReferenceType::unaryOperatorResult(Token _operator) const case DataLocation::CallData: return TypePointer(); case DataLocation::Memory: - return make_shared<TupleType>(); + return TypeResult(make_shared<TupleType>()); case DataLocation::Storage: return m_isPointer ? TypePointer() : make_shared<TupleType>(); } @@ -1605,7 +1605,7 @@ string ReferenceType::identifierLocationSuffix() const return id; } -bool ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const +BoolResult ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const { if (_convertTo.category() != category()) return false; @@ -1645,7 +1645,7 @@ bool ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const } } -bool ArrayType::isExplicitlyConvertibleTo(const Type& _convertTo) const +BoolResult ArrayType::isExplicitlyConvertibleTo(const Type& _convertTo) const { if (isImplicitlyConvertibleTo(_convertTo)) return true; @@ -2006,7 +2006,7 @@ vector<tuple<VariableDeclaration const*, u256, unsigned>> ContractType::stateVar return variablesAndOffsets; } -bool StructType::isImplicitlyConvertibleTo(const Type& _convertTo) const +BoolResult StructType::isImplicitlyConvertibleTo(const Type& _convertTo) const { if (_convertTo.category() != category()) return false; @@ -2249,7 +2249,7 @@ bool StructType::recursive() const return *m_recursive; } -TypePointer EnumType::unaryOperatorResult(Token _operator) const +TypeResult EnumType::unaryOperatorResult(Token _operator) const { return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer(); } @@ -2291,7 +2291,7 @@ size_t EnumType::numberOfMembers() const return m_enum.members().size(); }; -bool EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) const { return _convertTo == *this || _convertTo.category() == Category::Integer; } @@ -2308,7 +2308,7 @@ unsigned EnumType::memberValue(ASTString const& _member) const solAssert(false, "Requested unknown enum value " + _member); } -bool TupleType::isImplicitlyConvertibleTo(Type const& _other) const +BoolResult TupleType::isImplicitlyConvertibleTo(Type const& _other) const { if (auto tupleType = dynamic_cast<TupleType const*>(&_other)) { @@ -2648,14 +2648,14 @@ bool FunctionType::operator==(Type const& _other) const return true; } -bool FunctionType::isExplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult FunctionType::isExplicitlyConvertibleTo(Type const& _convertTo) const { if (m_kind == Kind::External && _convertTo == AddressType::address()) return true; return _convertTo.category() == category(); } -bool FunctionType::isImplicitlyConvertibleTo(Type const& _convertTo) const +BoolResult FunctionType::isImplicitlyConvertibleTo(Type const& _convertTo) const { if (_convertTo.category() != category()) return false; @@ -2680,14 +2680,14 @@ bool FunctionType::isImplicitlyConvertibleTo(Type const& _convertTo) const return true; } -TypePointer FunctionType::unaryOperatorResult(Token _operator) const +TypeResult FunctionType::unaryOperatorResult(Token _operator) const { if (_operator == Token::Delete) - return make_shared<TupleType>(); + return TypeResult(make_shared<TupleType>()); return TypePointer(); } -TypePointer FunctionType::binaryOperatorResult(Token _operator, TypePointer const& _other) const +TypeResult FunctionType::binaryOperatorResult(Token _operator, TypePointer const& _other) const { if (_other->category() != category() || !(_operator == Token::Equal || _operator == Token::NotEqual)) return TypePointer(); diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 0f0548d3..39157abe 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -29,6 +29,7 @@ #include <libdevcore/Common.h> #include <libdevcore/CommonIO.h> +#include <libdevcore/Result.h> #include <boost/noncopyable.hpp> #include <boost/rational.hpp> @@ -50,6 +51,8 @@ using TypePointer = std::shared_ptr<Type const>; using FunctionTypePointer = std::shared_ptr<FunctionType const>; using TypePointers = std::vector<TypePointer>; using rational = boost::rational<dev::bigint>; +using TypeResult = Result<TypePointer>; +using BoolResult = Result<bool>; inline rational makeRational(bigint const& _numerator, bigint const& _denominator) { @@ -63,6 +66,7 @@ inline rational makeRational(bigint const& _numerator, bigint const& _denominato enum class DataLocation { Storage, CallData, Memory }; + /** * Helper class to compute storage offsets of members of structs and contracts. */ @@ -189,19 +193,19 @@ public: /// @returns an escaped identifier (will not contain any parenthesis or commas) static std::string escapeIdentifier(std::string const& _identifier); - virtual bool isImplicitlyConvertibleTo(Type const& _other) const { return *this == _other; } - virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const + virtual BoolResult isImplicitlyConvertibleTo(Type const& _other) const { return *this == _other; } + virtual BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const { return isImplicitlyConvertibleTo(_convertTo); } /// @returns the resulting type of applying the given unary operator or an empty pointer if /// this is not possible. /// The default implementation does not allow any unary operator. - virtual TypePointer unaryOperatorResult(Token) const { return TypePointer(); } + virtual TypeResult unaryOperatorResult(Token) const { return TypePointer(); } /// @returns the resulting type of applying the given binary operator or an empty pointer if /// this is not possible. /// The default implementation allows comparison operators if a common type exists - virtual TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const + virtual TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const { return TokenTraits::isCompareOp(_operator) ? commonType(shared_from_this(), _other) : TypePointer(); } @@ -336,10 +340,10 @@ public: explicit AddressType(StateMutability _stateMutability); std::string richIdentifier() const override; - bool isImplicitlyConvertibleTo(Type const& _other) const override; - bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; - TypePointer unaryOperatorResult(Token _operator) const override; - TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override; + BoolResult isImplicitlyConvertibleTo(Type const& _other) const override; + BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override; + TypeResult unaryOperatorResult(Token _operator) const override; + TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const override; bool operator==(Type const& _other) const override; @@ -381,10 +385,10 @@ public: explicit IntegerType(unsigned _bits, Modifier _modifier = Modifier::Unsigned); std::string richIdentifier() const override; - bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; - bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; - TypePointer unaryOperatorResult(Token _operator) const override; - TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override; + BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override; + BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override; + TypeResult unaryOperatorResult(Token _operator) const override; + TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const override; bool operator==(Type const& _other) const override; @@ -423,10 +427,10 @@ public: explicit FixedPointType(unsigned _totalBits, unsigned _fractionalDigits, Modifier _modifier = Modifier::Unsigned); std::string richIdentifier() const override; - bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; - bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; - TypePointer unaryOperatorResult(Token _operator) const override; - TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override; + BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override; + BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override; + TypeResult unaryOperatorResult(Token _operator) const override; + TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const override; bool operator==(Type const& _other) const override; @@ -476,11 +480,10 @@ public: explicit RationalNumberType(rational const& _value, TypePointer const& _compatibleBytesType = TypePointer()): m_value(_value), m_compatibleBytesType(_compatibleBytesType) {} - - bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; - bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; - TypePointer unaryOperatorResult(Token _operator) const override; - TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override; + BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override; + BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override; + TypeResult unaryOperatorResult(Token _operator) const override; + TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const override; std::string richIdentifier() const override; bool operator==(Type const& _other) const override; @@ -536,8 +539,8 @@ public: explicit StringLiteralType(Literal const& _literal); - bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; - TypePointer binaryOperatorResult(Token, TypePointer const&) const override + BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override; + TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } @@ -570,12 +573,12 @@ public: explicit FixedBytesType(unsigned _bytes); - bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; - bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; + BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override; + BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override; std::string richIdentifier() const override; bool operator==(Type const& _other) const override; - TypePointer unaryOperatorResult(Token _operator) const override; - TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override; + TypeResult unaryOperatorResult(Token _operator) const override; + TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const override; unsigned calldataEncodedSize(bool _padded) const override { return _padded && m_bytes > 0 ? 32 : m_bytes; } unsigned storageBytes() const override { return m_bytes; } @@ -601,8 +604,8 @@ public: BoolType() {} Category category() const override { return Category::Bool; } std::string richIdentifier() const override { return "t_bool"; } - TypePointer unaryOperatorResult(Token _operator) const override; - TypePointer binaryOperatorResult(Token _operator, TypePointer const& _other) const override; + TypeResult unaryOperatorResult(Token _operator) const override; + TypeResult binaryOperatorResult(Token _operator, TypePointer const& _other) const override; unsigned calldataEncodedSize(bool _padded) const override{ return _padded ? 32 : 1; } unsigned storageBytes() const override { return 1; } @@ -624,8 +627,8 @@ public: explicit ReferenceType(DataLocation _location): m_location(_location) {} DataLocation location() const { return m_location; } - TypePointer unaryOperatorResult(Token _operator) const override; - TypePointer binaryOperatorResult(Token, TypePointer const&) const override + TypeResult unaryOperatorResult(Token _operator) const override; + TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } @@ -702,8 +705,8 @@ public: m_length(_length) {} - bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; - bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; + BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override; + BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override; std::string richIdentifier() const override; bool operator==(const Type& _other) const override; unsigned calldataEncodedSize(bool _padded) const override; @@ -757,10 +760,10 @@ public: explicit ContractType(ContractDefinition const& _contract, bool _super = false): m_contract(_contract), m_super(_super) {} /// Contracts can be implicitly converted only to base contracts. - bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; + BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override; /// Contracts can only be explicitly converted to address types and base contracts. - bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; - TypePointer unaryOperatorResult(Token _operator) const override; + BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override; + TypeResult unaryOperatorResult(Token _operator) const override; std::string richIdentifier() const override; bool operator==(Type const& _other) const override; unsigned calldataEncodedSize(bool _padded ) const override @@ -821,7 +824,7 @@ public: Category category() const override { return Category::Struct; } explicit StructType(StructDefinition const& _struct, DataLocation _location = DataLocation::Storage): ReferenceType(_location), m_struct(_struct) {} - bool isImplicitlyConvertibleTo(const Type& _convertTo) const override; + BoolResult isImplicitlyConvertibleTo(const Type& _convertTo) const override; std::string richIdentifier() const override; bool operator==(Type const& _other) const override; unsigned calldataEncodedSize(bool _padded) const override; @@ -876,7 +879,7 @@ class EnumType: public Type public: Category category() const override { return Category::Enum; } explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {} - TypePointer unaryOperatorResult(Token _operator) const override; + TypeResult unaryOperatorResult(Token _operator) const override; std::string richIdentifier() const override; bool operator==(Type const& _other) const override; unsigned calldataEncodedSize(bool _padded) const override @@ -889,7 +892,7 @@ public: std::string canonicalName() const override; bool isValueType() const override { return true; } - bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; + BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override; TypePointer encodingType() const override { return std::make_shared<IntegerType>(8 * int(storageBytes())); @@ -917,10 +920,10 @@ class TupleType: public Type public: Category category() const override { return Category::Tuple; } explicit TupleType(std::vector<TypePointer> const& _types = std::vector<TypePointer>()): m_components(_types) {} - bool isImplicitlyConvertibleTo(Type const& _other) const override; + BoolResult isImplicitlyConvertibleTo(Type const& _other) const override; std::string richIdentifier() const override; bool operator==(Type const& _other) const override; - TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } + TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } std::string toString(bool) const override; bool canBeStored() const override { return false; } u256 storageSize() const override; @@ -1065,10 +1068,10 @@ public: std::string richIdentifier() const override; bool operator==(Type const& _other) const override; - bool isImplicitlyConvertibleTo(Type const& _convertTo) const override; - bool isExplicitlyConvertibleTo(Type const& _convertTo) const override; - TypePointer unaryOperatorResult(Token _operator) const override; - TypePointer binaryOperatorResult(Token, TypePointer const&) const override; + BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override; + BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override; + TypeResult unaryOperatorResult(Token _operator) const override; + TypeResult binaryOperatorResult(Token, TypePointer const&) const override; std::string canonicalName() const override; std::string toString(bool _short) const override; unsigned calldataEncodedSize(bool _padded) const override; @@ -1197,7 +1200,7 @@ public: std::string toString(bool _short) const override; std::string canonicalName() const override; bool canLiveOutsideStorage() const override { return false; } - TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } + TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } TypePointer encodingType() const override { return std::make_shared<IntegerType>(256); @@ -1230,7 +1233,7 @@ public: explicit TypeType(TypePointer const& _actualType): m_actualType(_actualType) {} TypePointer const& actualType() const { return m_actualType; } - TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } + TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } std::string richIdentifier() const override; bool operator==(Type const& _other) const override; bool canBeStored() const override { return false; } @@ -1255,7 +1258,7 @@ public: Category category() const override { return Category::Modifier; } explicit ModifierType(ModifierDefinition const& _modifier); - TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } + TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } bool canBeStored() const override { return false; } u256 storageSize() const override; bool canLiveOutsideStorage() const override { return false; } @@ -1281,7 +1284,7 @@ public: explicit ModuleType(SourceUnit const& _source): m_sourceUnit(_source) {} - TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } + TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } std::string richIdentifier() const override; bool operator==(Type const& _other) const override; bool canBeStored() const override { return false; } @@ -1308,7 +1311,7 @@ public: explicit MagicType(Kind _kind): m_kind(_kind) {} - TypePointer binaryOperatorResult(Token, TypePointer const&) const override + TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } @@ -1339,9 +1342,9 @@ public: Category category() const override { return Category::InaccessibleDynamic; } std::string richIdentifier() const override { return "t_inaccessible"; } - bool isImplicitlyConvertibleTo(Type const&) const override { return false; } - bool isExplicitlyConvertibleTo(Type const&) const override { return false; } - TypePointer binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } + BoolResult isImplicitlyConvertibleTo(Type const&) const override { return false; } + BoolResult isExplicitlyConvertibleTo(Type const&) const override { return false; } + TypeResult binaryOperatorResult(Token, TypePointer const&) const override { return TypePointer(); } unsigned calldataEncodedSize(bool _padded) const override { (void)_padded; return 32; } bool canBeStored() const override { return false; } bool canLiveOutsideStorage() const override { return false; } |