diff options
Diffstat (limited to 'libsolidity/ast')
-rw-r--r-- | libsolidity/ast/AST.cpp | 5 | ||||
-rw-r--r-- | libsolidity/ast/AST.h | 8 | ||||
-rw-r--r-- | libsolidity/ast/ASTAnnotations.h | 6 | ||||
-rw-r--r-- | libsolidity/ast/ASTForward.h | 2 | ||||
-rw-r--r-- | libsolidity/ast/ASTJsonConverter.cpp | 19 | ||||
-rw-r--r-- | libsolidity/ast/ASTJsonConverter.h | 7 | ||||
-rw-r--r-- | libsolidity/ast/ASTPrinter.cpp | 5 | ||||
-rw-r--r-- | libsolidity/ast/ASTPrinter.h | 2 | ||||
-rw-r--r-- | libsolidity/ast/ASTVisitor.h | 4 | ||||
-rw-r--r-- | libsolidity/ast/Types.cpp | 233 | ||||
-rw-r--r-- | libsolidity/ast/Types.h | 120 |
11 files changed, 205 insertions, 206 deletions
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 3ae6bd6d..f379d758 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -21,13 +21,12 @@ */ #include <libsolidity/ast/AST.h> + #include <libsolidity/ast/ASTVisitor.h> #include <libsolidity/ast/AST_accept.h> - #include <libdevcore/Keccak256.h> #include <boost/algorithm/string.hpp> - #include <algorithm> #include <functional> @@ -198,7 +197,7 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::inter { signaturesSeen.insert(functionSignature); FixedHash<4> hash(dev::keccak256(functionSignature)); - m_interfaceFunctionList->push_back(make_pair(hash, fun)); + m_interfaceFunctionList->emplace_back(hash, fun); } } } diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index 2f418b09..9ac065ea 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -22,24 +22,22 @@ #pragma once - -#include <libsolidity/parsing/Token.h> #include <libsolidity/ast/ASTForward.h> #include <libsolidity/ast/Types.h> #include <libsolidity/ast/ASTAnnotations.h> #include <libsolidity/ast/ASTEnums.h> +#include <libsolidity/parsing/Token.h> #include <liblangutil/SourceLocation.h> #include <libevmasm/Instruction.h> - #include <libdevcore/FixedHash.h> -#include <json/json.h> #include <boost/noncopyable.hpp> +#include <json/json.h> +#include <memory> #include <string> #include <vector> -#include <memory> namespace yul { diff --git a/libsolidity/ast/ASTAnnotations.h b/libsolidity/ast/ASTAnnotations.h index e9cc905e..d1acf90b 100644 --- a/libsolidity/ast/ASTAnnotations.h +++ b/libsolidity/ast/ASTAnnotations.h @@ -27,8 +27,8 @@ #include <map> #include <memory> -#include <vector> #include <set> +#include <vector> namespace yul { @@ -46,7 +46,7 @@ using TypePointer = std::shared_ptr<Type const>; struct ASTAnnotation { - virtual ~ASTAnnotation() {} + virtual ~ASTAnnotation() = default; }; struct DocTag @@ -57,7 +57,7 @@ struct DocTag struct DocumentedAnnotation { - virtual ~DocumentedAnnotation() {} + virtual ~DocumentedAnnotation() = default; /// Mapping docstring tag name -> content. std::multimap<std::string, DocTag> docTags; }; diff --git a/libsolidity/ast/ASTForward.h b/libsolidity/ast/ASTForward.h index 992fe4cd..f61acad9 100644 --- a/libsolidity/ast/ASTForward.h +++ b/libsolidity/ast/ASTForward.h @@ -22,8 +22,8 @@ #pragma once -#include <string> #include <memory> +#include <string> #include <vector> // Forward-declare all AST node types diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp index cfb13271..f8222598 100644 --- a/libsolidity/ast/ASTJsonConverter.cpp +++ b/libsolidity/ast/ASTJsonConverter.cpp @@ -20,11 +20,12 @@ */ #include <libsolidity/ast/ASTJsonConverter.h> -#include <boost/algorithm/string/join.hpp> -#include <libdevcore/UTF8.h> + #include <libsolidity/ast/AST.h> #include <libyul/AsmData.h> #include <libyul/AsmPrinter.h> +#include <libdevcore/UTF8.h> +#include <boost/algorithm/string/join.hpp> using namespace std; using namespace langutil; @@ -234,7 +235,7 @@ bool ASTJsonConverter::visit(ImportDirective const& _node) make_pair(m_legacy ? "SourceUnit" : "sourceUnit", nodeId(*_node.annotation().sourceUnit)), make_pair("scope", idOrNull(_node.scope())) }; - attributes.push_back(make_pair("unitAlias", _node.name())); + attributes.emplace_back("unitAlias", _node.name()); Json::Value symbolAliases(Json::arrayValue); for (auto const& symbolAlias: _node.symbolAliases()) { @@ -244,7 +245,7 @@ bool ASTJsonConverter::visit(ImportDirective const& _node) tuple["local"] = symbolAlias.second ? Json::Value(*symbolAlias.second) : Json::nullValue; symbolAliases.append(tuple); } - attributes.push_back(make_pair("symbolAliases", std::move(symbolAliases))); + attributes.emplace_back("symbolAliases", std::move(symbolAliases)); setJsonNode(_node, "ImportDirective", std::move(attributes)); return false; } @@ -357,7 +358,7 @@ bool ASTJsonConverter::visit(VariableDeclaration const& _node) make_pair("typeDescriptions", typePointerToJson(_node.annotation().type, true)) }; if (m_inEvent) - attributes.push_back(make_pair("indexed", _node.isIndexed())); + attributes.emplace_back("indexed", _node.isIndexed()); setJsonNode(_node, "VariableDeclaration", std::move(attributes)); return false; } @@ -647,11 +648,11 @@ bool ASTJsonConverter::visit(FunctionCall const& _node) }; if (m_legacy) { - attributes.push_back(make_pair("isStructConstructorCall", _node.annotation().kind == FunctionCallKind::StructConstructorCall)); - attributes.push_back(make_pair("type_conversion", _node.annotation().kind == FunctionCallKind::TypeConversion)); + attributes.emplace_back("isStructConstructorCall", _node.annotation().kind == FunctionCallKind::StructConstructorCall); + attributes.emplace_back("type_conversion", _node.annotation().kind == FunctionCallKind::TypeConversion); } else - attributes.push_back(make_pair("kind", functionCallKind(_node.annotation().kind))); + attributes.emplace_back("kind", functionCallKind(_node.annotation().kind)); appendExpressionAttributes(attributes, _node.annotation()); setJsonNode(_node, "FunctionCall", std::move(attributes)); return false; @@ -724,7 +725,7 @@ bool ASTJsonConverter::visit(Literal const& _node) std::vector<pair<string, Json::Value>> attributes = { make_pair(m_legacy ? "token" : "kind", literalTokenKind(_node.token())), make_pair("value", value), - make_pair(m_legacy ? "hexvalue" : "hexValue", toHex(_node.value())), + make_pair(m_legacy ? "hexvalue" : "hexValue", toHex(asBytes(_node.value()))), make_pair( "subdenomination", subdenomination == Token::Illegal ? diff --git a/libsolidity/ast/ASTJsonConverter.h b/libsolidity/ast/ASTJsonConverter.h index ef0a217a..770e3d9d 100644 --- a/libsolidity/ast/ASTJsonConverter.h +++ b/libsolidity/ast/ASTJsonConverter.h @@ -22,12 +22,13 @@ #pragma once -#include <ostream> -#include <stack> +#include <libsolidity/ast/ASTAnnotations.h> #include <libsolidity/ast/ASTVisitor.h> #include <liblangutil/Exceptions.h> -#include <libsolidity/ast/ASTAnnotations.h> + #include <json/json.h> +#include <ostream> +#include <stack> namespace langutil { diff --git a/libsolidity/ast/ASTPrinter.cpp b/libsolidity/ast/ASTPrinter.cpp index cdc6ae7d..d8bafa2c 100644 --- a/libsolidity/ast/ASTPrinter.cpp +++ b/libsolidity/ast/ASTPrinter.cpp @@ -21,11 +21,10 @@ */ #include <libsolidity/ast/ASTPrinter.h> -#include <libsolidity/ast/AST.h> - -#include <json/json.h> +#include <libsolidity/ast/AST.h> #include <boost/algorithm/string/join.hpp> +#include <json/json.h> using namespace std; using namespace langutil; diff --git a/libsolidity/ast/ASTPrinter.h b/libsolidity/ast/ASTPrinter.h index de3bf8a2..d762af47 100644 --- a/libsolidity/ast/ASTPrinter.h +++ b/libsolidity/ast/ASTPrinter.h @@ -22,9 +22,9 @@ #pragma once -#include <ostream> #include <libsolidity/ast/ASTVisitor.h> #include <libsolidity/interface/GasEstimator.h> +#include <ostream> namespace dev { diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h index 1a761032..8cb94e05 100644 --- a/libsolidity/ast/ASTVisitor.h +++ b/libsolidity/ast/ASTVisitor.h @@ -22,10 +22,10 @@ #pragma once -#include <string> +#include <libsolidity/ast/AST.h> #include <functional> +#include <string> #include <vector> -#include <libsolidity/ast/AST.h> namespace dev { diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp index 6cadb5f3..cc978b4a 100644 --- a/libsolidity/ast/Types.cpp +++ b/libsolidity/ast/Types.cpp @@ -24,22 +24,22 @@ #include <libsolidity/ast/AST.h> -#include <libdevcore/CommonIO.h> +#include <libdevcore/Algorithms.h> #include <libdevcore/CommonData.h> +#include <libdevcore/CommonIO.h> #include <libdevcore/Keccak256.h> #include <libdevcore/UTF8.h> -#include <libdevcore/Algorithms.h> +#include <boost/algorithm/string.hpp> +#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/join.hpp> -#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/predicate.hpp> -#include <boost/algorithm/string/classification.hpp> +#include <boost/algorithm/string/replace.hpp> #include <boost/algorithm/string/split.hpp> #include <boost/range/adaptor/reversed.hpp> -#include <boost/range/algorithm/copy.hpp> #include <boost/range/adaptor/sliced.hpp> #include <boost/range/adaptor/transformed.hpp> -#include <boost/algorithm/string.hpp> +#include <boost/range/algorithm/copy.hpp> #include <limits> @@ -125,6 +125,22 @@ bool fitsPrecisionBase2(bigint const& _mantissa, uint32_t _expBase2) return fitsPrecisionBaseX(_mantissa, 1.0, _expBase2); } +/// Checks whether _value fits into IntegerType _type. +bool fitsIntegerType(bigint const& _value, IntegerType const& _type) +{ + return (_type.minValue() <= _value) && (_value <= _type.maxValue()); +} + +/// Checks whether _value fits into _bits bits when having 1 bit as the sign bit +/// if _signed is true. +bool fitsIntoBits(bigint const& _value, unsigned _bits, bool _signed) +{ + return fitsIntegerType(_value, IntegerType( + _bits, + _signed ? IntegerType::Modifier::Signed : IntegerType::Modifier::Unsigned + )); +} + } void StorageOffsets::computeOffsets(TypePointers const& _types) @@ -446,7 +462,7 @@ MemberList::MemberMap Type::boundFunctions(Type const& _type, ContractDefinition continue; FunctionTypePointer fun = FunctionType(*function, false).asCallableFunction(true, true); if (_type.isImplicitlyConvertibleTo(*fun->selfType())) - members.push_back(MemberList::Member(function->name(), fun, function)); + members.emplace_back(function->name(), fun, function); } } return members; @@ -466,7 +482,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 +491,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,17 +520,16 @@ 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)) - return TypePointer(); + return TypeResult{"Arithmetic operations on addresses are not supported. Convert to integer first before using them."}; return Type::commonType(shared_from_this(), _other); } @@ -576,7 +591,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 +612,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 +622,17 @@ 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>(); - // 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{make_shared<TupleType>()}; + // we allow -, ++ and -- + else if (_operator == Token::Sub || _operator == Token::Inc || + _operator == Token::Dec || _operator == Token::BitNot) + return TypeResult{shared_from_this()}; else - return TypePointer(); + return TypeResult{""}; } bool IntegerType::operator==(Type const& _other) const @@ -651,7 +665,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 && @@ -679,9 +693,8 @@ TypePointer IntegerType::binaryOperatorResult(Token _operator, TypePointer const return TypePointer(); if (auto intType = dynamic_pointer_cast<IntegerType const>(commonType)) { - // Signed EXP is not allowed if (Token::Exp == _operator && intType->isSigned()) - return TypePointer(); + return TypeResult{"Exponentiation is not allowed for signed integer types."}; } else if (auto fixType = dynamic_pointer_cast<FixedPointType const>(commonType)) if (Token::Exp == _operator) @@ -704,7 +717,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 +730,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 +784,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 +970,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()) { @@ -966,27 +979,21 @@ bool RationalNumberType::isImplicitlyConvertibleTo(Type const& _convertTo) const if (isFractional()) return false; IntegerType const& targetType = dynamic_cast<IntegerType const&>(_convertTo); - if (m_value == rational(0)) - return true; - unsigned forSignBit = (targetType.isSigned() ? 1 : 0); - if (m_value > rational(0)) - { - if (m_value.numerator() <= (u256(-1) >> (256 - targetType.numBits() + forSignBit))) - return true; - return false; - } - if (targetType.isSigned()) - { - if (-m_value.numerator() <= (u256(1) << (targetType.numBits() - forSignBit))) - return true; - } - return false; + return fitsIntegerType(m_value.numerator(), targetType); } case Category::FixedPoint: { - if (auto fixed = fixedPointType()) - return fixed->isImplicitlyConvertibleTo(_convertTo); - return false; + FixedPointType const& targetType = dynamic_cast<FixedPointType const&>(_convertTo); + // Store a negative number into an unsigned. + if (isNegative() && !targetType.isSigned()) + return false; + if (!isFractional()) + return (targetType.minIntegerValue() <= m_value) && (m_value <= targetType.maxIntegerValue()); + rational value = m_value * pow(bigint(10), targetType.fractionalDigits()); + // Need explicit conversion since truncation will occur. + if (value.denominator() != 1) + return false; + return fitsIntoBits(value.numerator(), targetType.numBits(), targetType.isSigned()); } case Category::FixedBytes: return (m_value == rational(0)) || (m_compatibleBytesType && *m_compatibleBytesType == _convertTo); @@ -995,7 +1002,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 +1015,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 +1036,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) { @@ -1129,9 +1136,8 @@ TypePointer RationalNumberType::binaryOperatorResult(Token _operator, TypePointe uint32_t absExp = bigint(abs(exp)).convert_to<uint32_t>(); - // Limit size to 4096 bits if (!fitsPrecisionExp(abs(m_value.numerator()), absExp) || !fitsPrecisionExp(abs(m_value.denominator()), absExp)) - return TypePointer(); + return TypeResult{"Precision of rational constants is limited to 4096 bits."}; static auto const optimizedPow = [](bigint const& _base, uint32_t _exponent) -> bigint { if (_base == 1) @@ -1212,9 +1218,9 @@ TypePointer RationalNumberType::binaryOperatorResult(Token _operator, TypePointe // verify that numerator and denominator fit into 4096 bit after every operation if (value.numerator() != 0 && max(mostSignificantBit(abs(value.numerator())), mostSignificantBit(abs(value.denominator()))) > 4096) - return TypePointer(); + return TypeResult{"Precision of rational constants is limited to 4096 bits."}; - return make_shared<RationalNumberType>(value); + return TypeResult(make_shared<RationalNumberType>(value)); } } @@ -1354,7 +1360,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 +1415,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 +1423,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 +1431,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 +1458,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 +1492,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 +1509,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 +1526,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 +1539,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 +1557,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 +1611,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 +1651,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; @@ -1815,23 +1821,23 @@ MemberList::MemberMap ArrayType::nativeMembers(ContractDefinition const*) const MemberList::MemberMap members; if (!isString()) { - members.push_back({"length", make_shared<IntegerType>(256)}); + members.emplace_back("length", make_shared<IntegerType>(256)); if (isDynamicallySized() && location() == DataLocation::Storage) { - members.push_back({"push", make_shared<FunctionType>( + members.emplace_back("push", make_shared<FunctionType>( TypePointers{baseType()}, TypePointers{make_shared<IntegerType>(256)}, strings{string()}, strings{string()}, isByteArray() ? FunctionType::Kind::ByteArrayPush : FunctionType::Kind::ArrayPush - )}); - members.push_back({"pop", make_shared<FunctionType>( + )); + members.emplace_back("pop", make_shared<FunctionType>( TypePointers{}, TypePointers{}, strings{string()}, strings{string()}, FunctionType::Kind::ArrayPop - )}); + )); } } return members; @@ -1960,21 +1966,17 @@ MemberList::MemberMap ContractType::nativeMembers(ContractDefinition const* _con break; } if (!functionWithEqualArgumentsFound) - members.push_back(MemberList::Member( - function->name(), - functionType, - function - )); + members.emplace_back(function->name(), functionType, function); } } else if (!m_contract.isLibrary()) { for (auto const& it: m_contract.interfaceFunctions()) - members.push_back(MemberList::Member( + members.emplace_back( it.second->declaration().name(), it.second->asCallableFunction(m_contract.isLibrary()), &it.second->declaration() - )); + ); } return members; } @@ -2002,11 +2004,11 @@ vector<tuple<VariableDeclaration const*, u256, unsigned>> ContractType::stateVar vector<tuple<VariableDeclaration const*, u256, unsigned>> variablesAndOffsets; for (size_t index = 0; index < variables.size(); ++index) if (auto const* offset = offsets.offset(index)) - variablesAndOffsets.push_back(make_tuple(variables[index], offset->first, offset->second)); + variablesAndOffsets.emplace_back(variables[index], offset->first, offset->second); return variablesAndOffsets; } -bool StructType::isImplicitlyConvertibleTo(const Type& _convertTo) const +BoolResult StructType::isImplicitlyConvertibleTo(const Type& _convertTo) const { if (_convertTo.category() != category()) return false; @@ -2092,10 +2094,10 @@ MemberList::MemberMap StructType::nativeMembers(ContractDefinition const*) const // Skip all mapping members if we are not in storage. if (location() != DataLocation::Storage && !type->canLiveOutsideStorage()) continue; - members.push_back(MemberList::Member( + members.emplace_back( variable->name(), copyForLocationIfReference(type), - variable.get()) + variable.get() ); } return members; @@ -2249,7 +2251,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 +2293,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 +2310,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)) { @@ -2432,7 +2434,7 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl): if (auto mappingType = dynamic_cast<MappingType const*>(returnType.get())) { m_parameterTypes.push_back(mappingType->keyType()); - m_parameterNames.push_back(""); + m_parameterNames.emplace_back(""); returnType = mappingType->valueType(); } else if (auto arrayType = dynamic_cast<ArrayType const*>(returnType.get())) @@ -2441,7 +2443,7 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl): // Return byte arrays as whole. break; returnType = arrayType->baseType(); - m_parameterNames.push_back(""); + m_parameterNames.emplace_back(""); m_parameterTypes.push_back(make_shared<IntegerType>(256)); } else @@ -2472,7 +2474,7 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl): DataLocation::Memory, returnType )); - m_returnParameterNames.push_back(""); + m_returnParameterNames.emplace_back(""); } } @@ -2648,14 +2650,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 +2682,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(); @@ -2841,14 +2843,11 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con { MemberList::MemberMap members; if (m_kind == Kind::External) - members.push_back(MemberList::Member( - "selector", - make_shared<FixedBytesType>(4) - )); + members.emplace_back("selector", make_shared<FixedBytesType>(4)); if (m_kind != Kind::BareDelegateCall) { if (isPayable()) - members.push_back(MemberList::Member( + members.emplace_back( "value", make_shared<FunctionType>( parseElementaryTypeVector({"uint"}), @@ -2862,10 +2861,10 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con m_gasSet, m_valueSet ) - )); + ); } if (m_kind != Kind::Creation) - members.push_back(MemberList::Member( + members.emplace_back( "gas", make_shared<FunctionType>( parseElementaryTypeVector({"uint"}), @@ -2879,7 +2878,7 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con m_gasSet, m_valueSet ) - )); + ); return members; } default: @@ -3207,24 +3206,24 @@ MemberList::MemberMap TypeType::nativeMembers(ContractDefinition const* _current if (contract.isLibrary()) for (FunctionDefinition const* function: contract.definedFunctions()) if (function->isVisibleAsLibraryMember()) - members.push_back(MemberList::Member( + members.emplace_back( function->name(), FunctionType(*function).asCallableFunction(true), function - )); + ); if (isBase) { // We are accessing the type of a base contract, so add all public and protected // members. Note that this does not add inherited functions on purpose. for (Declaration const* decl: contract.inheritableMembers()) - members.push_back(MemberList::Member(decl->name(), decl->type(), decl)); + members.emplace_back(decl->name(), decl->type(), decl); } else { for (auto const& stru: contract.definedStructs()) - members.push_back(MemberList::Member(stru->name(), stru->type(), stru)); + members.emplace_back(stru->name(), stru->type(), stru); for (auto const& enu: contract.definedEnums()) - members.push_back(MemberList::Member(enu->name(), enu->type(), enu)); + members.emplace_back(enu->name(), enu->type(), enu); } } else if (m_actualType->category() == Category::Enum) @@ -3232,7 +3231,7 @@ MemberList::MemberMap TypeType::nativeMembers(ContractDefinition const* _current EnumDefinition const& enumDef = dynamic_cast<EnumType const&>(*m_actualType).enumDefinition(); auto enumType = make_shared<EnumType>(enumDef); for (ASTPointer<EnumValue> const& enumValue: enumDef.members()) - members.push_back(MemberList::Member(enumValue->name(), enumType)); + members.emplace_back(enumValue->name(), enumType); } return members; } @@ -3297,7 +3296,7 @@ MemberList::MemberMap ModuleType::nativeMembers(ContractDefinition const*) const MemberList::MemberMap symbols; for (auto const& symbolName: m_sourceUnit.annotation().exportedSymbols) for (Declaration const* symbol: symbolName.second) - symbols.push_back(MemberList::Member(symbolName.first, symbol->type(), symbol)); + symbols.emplace_back(symbolName.first, symbol->type(), symbol); return symbols; } diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h index 0f0548d3..bee00661 100644 --- a/libsolidity/ast/Types.h +++ b/libsolidity/ast/Types.h @@ -22,22 +22,23 @@ #pragma once -#include <liblangutil/Exceptions.h> -#include <libsolidity/ast/ASTForward.h> #include <libsolidity/ast/ASTEnums.h> +#include <libsolidity/ast/ASTForward.h> #include <libsolidity/parsing/Token.h> +#include <liblangutil/Exceptions.h> #include <libdevcore/Common.h> #include <libdevcore/CommonIO.h> +#include <libdevcore/Result.h> +#include <boost/optional.hpp> #include <boost/noncopyable.hpp> #include <boost/rational.hpp> -#include <boost/optional.hpp> -#include <memory> -#include <string> #include <map> +#include <memory> #include <set> +#include <string> namespace dev { @@ -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; } @@ -598,11 +601,10 @@ private: class BoolType: public Type { 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 +626,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 +704,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 +759,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 +823,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 +878,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 +891,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 +919,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 +1067,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 +1199,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 +1232,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 +1257,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 +1283,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 +1310,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 +1341,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; } |