diff --git a/libdevcore/Result.h b/libdevcore/Result.h
new file mode 100644
index 000000000..4f7a063b5
--- /dev/null
+++ b/libdevcore/Result.h
@@ -0,0 +1,66 @@
+/*
+ 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 .
+*/
+#pragma once
+
+#include
+
+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. The class is mainly designed for a result type of
+/// bool or pointer type. The idea is that the default constructed value of
+/// the result type is interpreted as an error value.
+///
+/// Result check()
+/// {
+/// if (false)
+/// return Result("Error message.")
+/// return true;
+/// }
+///
+
+template
+class Result
+{
+public:
+ Result(ResultType _value): Result(_value, std::string{}) {}
+ Result(std::string _message): Result(ResultType{}, std::move(_message)) {}
+
+ /// @{
+ /// @name Wrapper functions
+ /// Wrapper functions that provide implicit conversions to and explicit retrieval of
+ /// the value this result holds.
+ operator ResultType const&() const { return m_value; }
+ ResultType const& get() const { return m_value; }
+ /// @}
+
+ /// @returns the error message (can be empty).
+ std::string const& message() const { return m_message; }
+
+private:
+ explicit Result(ResultType _value, std::string _message):
+ m_value(std::move(_value)),
+ m_message(std::move(_message))
+ {}
+
+ ResultType m_value;
+ std::string m_message;
+};
+
+}
diff --git a/libsolidity/analysis/ConstantEvaluator.cpp b/libsolidity/analysis/ConstantEvaluator.cpp
index 9d041ce5b..26d9584b5 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 6cadb5f33..c6b4211a3 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(&_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() : 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();
+ return TypeResult{make_shared()};
// 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{shared_from_this()};
else
- return TypePointer();
+ return TypeResult{""};
}
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();
+ return TypeResult(make_shared());
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 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(value);
+ return TypeResult(make_shared(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(value);
+ return TypeResult(make_shared(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(&_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(_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();
+ return TypeResult(make_shared());
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();
+ return TypeResult(make_shared());
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(&_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() : 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();
+ return TypeResult(make_shared());
case DataLocation::Storage:
return m_isPointer ? TypePointer() : make_shared();
}
@@ -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> 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() : 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(&_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();
+ return TypeResult(make_shared());
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 0f0548d3b..39157abe0 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -29,6 +29,7 @@
#include
#include
+#include
#include
#include
@@ -50,6 +51,8 @@ using TypePointer = std::shared_ptr;
using FunctionTypePointer = std::shared_ptr;
using TypePointers = std::vector;
using rational = boost::rational;
+using TypeResult = Result;
+using BoolResult = Result;
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(8 * int(storageBytes()));
@@ -917,10 +920,10 @@ class TupleType: public Type
public:
Category category() const override { return Category::Tuple; }
explicit TupleType(std::vector const& _types = std::vector()): 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(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; }