aboutsummaryrefslogtreecommitdiffstats
path: root/Types.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Types.cpp')
-rw-r--r--Types.cpp163
1 files changed, 87 insertions, 76 deletions
diff --git a/Types.cpp b/Types.cpp
index f30085ec..5f573a6d 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -26,6 +26,8 @@
#include <libsolidity/Types.h>
#include <libsolidity/AST.h>
+#include <limits>
+
using namespace std;
namespace dev
@@ -37,24 +39,24 @@ shared_ptr<Type const> Type::fromElementaryTypeName(Token::Value _typeToken)
{
solAssert(Token::isElementaryTypeName(_typeToken), "Elementary type name expected.");
- if (Token::INT <= _typeToken && _typeToken <= Token::HASH256)
+ if (Token::Int <= _typeToken && _typeToken <= Token::Hash256)
{
- int offset = _typeToken - Token::INT;
+ int offset = _typeToken - Token::Int;
int bytes = offset % 33;
if (bytes == 0)
bytes = 32;
int modifier = offset / 33;
return make_shared<IntegerType>(bytes * 8,
- modifier == 0 ? IntegerType::Modifier::SIGNED :
- modifier == 1 ? IntegerType::Modifier::UNSIGNED :
- IntegerType::Modifier::HASH);
+ modifier == 0 ? IntegerType::Modifier::Signed :
+ modifier == 1 ? IntegerType::Modifier::Unsigned :
+ IntegerType::Modifier::Hash);
}
- else if (_typeToken == Token::ADDRESS)
- return make_shared<IntegerType>(0, IntegerType::Modifier::ADDRESS);
- else if (_typeToken == Token::BOOL)
+ else if (_typeToken == Token::Address)
+ return make_shared<IntegerType>(0, IntegerType::Modifier::Address);
+ else if (_typeToken == Token::Bool)
return make_shared<BoolType>();
- else if (Token::STRING0 <= _typeToken && _typeToken <= Token::STRING32)
- return make_shared<StaticStringType>(int(_typeToken) - int(Token::STRING0));
+ else if (Token::String0 <= _typeToken && _typeToken <= Token::String32)
+ return make_shared<StaticStringType>(int(_typeToken) - int(Token::String0));
else
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to convert elementary typename " +
std::string(Token::toString(_typeToken)) + " to type."));
@@ -87,12 +89,12 @@ shared_ptr<Type const> Type::forLiteral(Literal const& _literal)
{
switch (_literal.getToken())
{
- case Token::TRUE_LITERAL:
- case Token::FALSE_LITERAL:
+ case Token::TrueLiteral:
+ case Token::FalseLiteral:
return make_shared<BoolType>();
- case Token::NUMBER:
+ case Token::Number:
return make_shared<IntegerConstantType>(_literal);
- case Token::STRING_LITERAL:
+ case Token::StringLiteral:
//@todo put larger strings into dynamic strings
return StaticStringType::smallestTypeForLiteral(_literal.getValue());
default:
@@ -140,31 +142,31 @@ bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
bool IntegerType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
- if (_convertTo.getCategory() == Category::STRING)
+ if (_convertTo.getCategory() == Category::String)
{
StaticStringType const& convertTo = dynamic_cast<StaticStringType const&>(_convertTo);
return isHash() && (m_bits == convertTo.getNumBytes() * 8);
}
- return _convertTo.getCategory() == getCategory() || _convertTo.getCategory() == Category::CONTRACT;
+ return _convertTo.getCategory() == getCategory() || _convertTo.getCategory() == Category::Contract;
}
TypePointer IntegerType::unaryOperatorResult(Token::Value _operator) const
{
// "delete" is ok for all integer types
- if (_operator == Token::DELETE)
+ if (_operator == Token::Delete)
return make_shared<VoidType>();
// no further unary operators for addresses
else if (isAddress())
return TypePointer();
// "~" is ok for all other types
- else if (_operator == Token::BIT_NOT)
+ else if (_operator == Token::BitNot)
return shared_from_this();
// nothing else for hashes
else if (isHash())
return TypePointer();
// for non-hash integers, we allow +, -, ++ and --
- else if (_operator == Token::ADD || _operator == Token::SUB ||
- _operator == Token::INC || _operator == Token::DEC)
+ else if (_operator == Token::Add || _operator == Token::Sub ||
+ _operator == Token::Inc || _operator == Token::Dec)
return shared_from_this();
else
return TypePointer();
@@ -188,7 +190,7 @@ string IntegerType::toString() const
TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
{
- if (_other->getCategory() != Category::INTEGER_CONSTANT && _other->getCategory() != getCategory())
+ if (_other->getCategory() != Category::IntegerConstant && _other->getCategory() != getCategory())
return TypePointer();
auto commonType = dynamic_pointer_cast<IntegerType const>(Type::commonType(shared_from_this(), _other));
@@ -210,11 +212,8 @@ TypePointer IntegerType::binaryOperatorResult(Token::Value _operator, TypePointe
const MemberList IntegerType::AddressMemberList =
MemberList({{"balance", make_shared<IntegerType >(256)},
- {"callstring32", make_shared<FunctionType>(strings{"string32"}, strings{},
- FunctionType::Location::BARE)},
- {"callstring32string32", make_shared<FunctionType>(strings{"string32", "string32"},
- strings{}, FunctionType::Location::BARE)},
- {"send", make_shared<FunctionType>(strings{"uint"}, strings{}, FunctionType::Location::SEND)}});
+ {"call", make_shared<FunctionType>(strings(), strings(), FunctionType::Location::Bare, true)},
+ {"send", make_shared<FunctionType>(strings{"uint"}, strings{}, FunctionType::Location::Send)}});
IntegerConstantType::IntegerConstantType(Literal const& _literal)
{
@@ -254,13 +253,13 @@ TypePointer IntegerConstantType::unaryOperatorResult(Token::Value _operator) con
bigint value;
switch (_operator)
{
- case Token::BIT_NOT:
+ case Token::BitNot:
value = ~m_value;
break;
- case Token::ADD:
+ case Token::Add:
value = m_value;
break;
- case Token::SUB:
+ case Token::Sub:
value = -m_value;
break;
default:
@@ -271,7 +270,7 @@ TypePointer IntegerConstantType::unaryOperatorResult(Token::Value _operator) con
TypePointer IntegerConstantType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
{
- if (_other->getCategory() == Category::INTEGER)
+ if (_other->getCategory() == Category::Integer)
{
shared_ptr<IntegerType const> integerType = getIntegerType();
if (!integerType)
@@ -295,34 +294,42 @@ TypePointer IntegerConstantType::binaryOperatorResult(Token::Value _operator, Ty
bigint value;
switch (_operator)
{
- case Token::BIT_OR:
+ case Token::BitOr:
value = m_value | other.m_value;
break;
- case Token::BIT_XOR:
+ case Token::BitXor:
value = m_value ^ other.m_value;
break;
- case Token::BIT_AND:
+ case Token::BitAnd:
value = m_value & other.m_value;
break;
- case Token::ADD:
+ case Token::Add:
value = m_value + other.m_value;
break;
- case Token::SUB:
+ case Token::Sub:
value = m_value - other.m_value;
break;
- case Token::MUL:
+ case Token::Mul:
value = m_value * other.m_value;
break;
- case Token::DIV:
+ case Token::Div:
if (other.m_value == 0)
return TypePointer();
value = m_value / other.m_value;
break;
- case Token::MOD:
+ case Token::Mod:
if (other.m_value == 0)
return TypePointer();
value = m_value % other.m_value;
break;
+ case Token::Exp:
+ if (other.m_value < 0)
+ return TypePointer();
+ else if (other.m_value > std::numeric_limits<unsigned int>::max())
+ return TypePointer();
+ else
+ value = boost::multiprecision::pow(m_value, other.m_value.convert_to<unsigned int>());
+ break;
default:
return TypePointer();
}
@@ -374,8 +381,8 @@ shared_ptr<IntegerType const> IntegerConstantType::getIntegerType() const
return shared_ptr<IntegerType const>();
else
return make_shared<IntegerType>(max(bytesRequired(value), 1u) * 8,
- negative ? IntegerType::Modifier::SIGNED
- : IntegerType::Modifier::UNSIGNED);
+ negative ? IntegerType::Modifier::Signed
+ : IntegerType::Modifier::Unsigned);
}
shared_ptr<StaticStringType> StaticStringType::smallestTypeForLiteral(string const& _literal)
@@ -401,13 +408,16 @@ bool StaticStringType::isImplicitlyConvertibleTo(Type const& _convertTo) const
bool StaticStringType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
- if (_convertTo.getCategory() == Category::INTEGER)
+ if (_convertTo.getCategory() == getCategory())
+ return true;
+ if (_convertTo.getCategory() == Category::Integer)
{
IntegerType const& convertTo = dynamic_cast<IntegerType const&>(_convertTo);
if (convertTo.isHash() && (m_bytes * 8 == convertTo.getNumBits()))
return true;
}
- return isImplicitlyConvertibleTo(_convertTo);
+
+ return false;
}
bool StaticStringType::operator==(Type const& _other) const
@@ -443,9 +453,9 @@ bool BoolType::isExplicitlyConvertibleTo(Type const& _convertTo) const
u256 BoolType::literalValue(Literal const* _literal) const
{
solAssert(_literal, "");
- if (_literal->getToken() == Token::TRUE_LITERAL)
+ if (_literal->getToken() == Token::TrueLiteral)
return u256(1);
- else if (_literal->getToken() == Token::FALSE_LITERAL)
+ else if (_literal->getToken() == Token::FalseLiteral)
return u256(0);
else
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Bool type constructed from non-boolean literal."));
@@ -453,16 +463,16 @@ u256 BoolType::literalValue(Literal const* _literal) const
TypePointer BoolType::unaryOperatorResult(Token::Value _operator) const
{
- if (_operator == Token::DELETE)
+ if (_operator == Token::Delete)
return make_shared<VoidType>();
- return (_operator == Token::NOT) ? shared_from_this() : TypePointer();
+ return (_operator == Token::Not) ? shared_from_this() : TypePointer();
}
TypePointer BoolType::binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const
{
if (getCategory() != _other->getCategory())
return TypePointer();
- if (Token::isCompareOp(_operator) || _operator == Token::AND || _operator == Token::OR)
+ if (Token::isCompareOp(_operator) || _operator == Token::And || _operator == Token::Or)
return _other;
else
return TypePointer();
@@ -472,9 +482,9 @@ bool ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const
{
if (*this == _convertTo)
return true;
- if (_convertTo.getCategory() == Category::INTEGER)
+ if (_convertTo.getCategory() == Category::Integer)
return dynamic_cast<IntegerType const&>(_convertTo).isAddress();
- if (_convertTo.getCategory() == Category::CONTRACT)
+ if (_convertTo.getCategory() == Category::Contract)
{
auto const& bases = getContractDefinition().getLinearizedBaseContracts();
if (m_super && bases.size() <= 1)
@@ -487,13 +497,13 @@ bool ContractType::isImplicitlyConvertibleTo(Type const& _convertTo) const
bool ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
- return isImplicitlyConvertibleTo(_convertTo) || _convertTo.getCategory() == Category::INTEGER ||
- _convertTo.getCategory() == Category::CONTRACT;
+ return isImplicitlyConvertibleTo(_convertTo) || _convertTo.getCategory() == Category::Integer ||
+ _convertTo.getCategory() == Category::Contract;
}
TypePointer ContractType::unaryOperatorResult(Token::Value _operator) const
{
- return _operator == Token::DELETE ? make_shared<VoidType>() : TypePointer();
+ return _operator == Token::Delete ? make_shared<VoidType>() : TypePointer();
}
bool ContractType::operator==(Type const& _other) const
@@ -557,7 +567,7 @@ u256 ContractType::getFunctionIdentifier(string const& _functionName) const
TypePointer StructType::unaryOperatorResult(Token::Value _operator) const
{
- return _operator == Token::DELETE ? make_shared<VoidType>() : TypePointer();
+ return _operator == Token::Delete ? make_shared<VoidType>() : TypePointer();
}
bool StructType::operator==(Type const& _other) const
@@ -616,7 +626,7 @@ u256 StructType::getStorageOffsetOfMember(string const& _name) const
}
FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal):
- m_location(_isInternal ? Location::INTERNAL : Location::EXTERNAL),
+ m_location(_isInternal ? Location::Internal : Location::External),
m_isConstant(_function.isDeclaredConst()),
m_declaration(&_function)
{
@@ -646,7 +656,7 @@ FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal
}
FunctionType::FunctionType(VariableDeclaration const& _varDecl):
- m_location(Location::EXTERNAL), m_isConstant(true), m_declaration(&_varDecl)
+ m_location(Location::External), m_isConstant(true), m_declaration(&_varDecl)
{
TypePointers params;
vector<string> paramNames;
@@ -683,7 +693,7 @@ FunctionType::FunctionType(VariableDeclaration const& _varDecl):
}
FunctionType::FunctionType(const EventDefinition& _event):
- m_location(Location::EVENT), m_declaration(&_event)
+ m_location(Location::Event), m_declaration(&_event)
{
TypePointers params;
vector<string> paramNames;
@@ -740,9 +750,9 @@ string FunctionType::toString() const
unsigned FunctionType::getSizeOnStack() const
{
unsigned size = 0;
- if (m_location == Location::EXTERNAL)
+ if (m_location == Location::External)
size = 2;
- else if (m_location == Location::INTERNAL || m_location == Location::BARE)
+ else if (m_location == Location::Internal || m_location == Location::Bare)
size = 1;
if (m_gasSet)
size++;
@@ -755,22 +765,22 @@ MemberList const& FunctionType::getMembers() const
{
switch (m_location)
{
- case Location::EXTERNAL:
- case Location::CREATION:
- case Location::ECRECOVER:
+ case Location::External:
+ case Location::Creation:
+ case Location::ECRecover:
case Location::SHA256:
case Location::RIPEMD160:
- case Location::BARE:
+ case Location::Bare:
if (!m_members)
{
map<string, TypePointer> members{
{"gas", make_shared<FunctionType>(parseElementaryTypeVector({"uint"}),
TypePointers{copyAndSetGasOrValue(true, false)},
- Location::SET_GAS, m_gasSet, m_valueSet)},
+ Location::SetGas, false, m_gasSet, m_valueSet)},
{"value", make_shared<FunctionType>(parseElementaryTypeVector({"uint"}),
TypePointers{copyAndSetGasOrValue(false, true)},
- Location::SET_VALUE, m_gasSet, m_valueSet)}};
- if (m_location == Location::CREATION)
+ Location::SetValue, false, m_gasSet, m_valueSet)}};
+ if (m_location == Location::Creation)
members.erase("gas");
m_members.reset(new MemberList(members));
}
@@ -808,6 +818,7 @@ TypePointers FunctionType::parseElementaryTypeVector(strings const& _types)
TypePointer FunctionType::copyAndSetGasOrValue(bool _setGas, bool _setValue) const
{
return make_shared<FunctionType>(m_parameterTypes, m_returnParameterTypes, m_location,
+ m_arbitraryParameters,
m_gasSet || _setGas, m_valueSet || _setValue);
}
@@ -865,7 +876,7 @@ MemberList const& TypeType::getMembers() const
if (!m_members)
{
map<string, TypePointer> members;
- if (m_actualType->getCategory() == Category::CONTRACT && m_currentContract != nullptr)
+ if (m_actualType->getCategory() == Category::Contract && m_currentContract != nullptr)
{
ContractDefinition const& contract = dynamic_cast<ContractType const&>(*m_actualType).getContractDefinition();
vector<ContractDefinition const*> currentBases = m_currentContract->getLinearizedBaseContracts();
@@ -919,21 +930,21 @@ MagicType::MagicType(MagicType::Kind _kind):
{
switch (m_kind)
{
- case Kind::BLOCK:
- m_members = MemberList({{"coinbase", make_shared<IntegerType>(0, IntegerType::Modifier::ADDRESS)},
+ case Kind::Block:
+ m_members = MemberList({{"coinbase", make_shared<IntegerType>(0, IntegerType::Modifier::Address)},
{"timestamp", make_shared<IntegerType>(256)},
- {"blockhash", make_shared<FunctionType>(strings{"uint"}, strings{"hash"}, FunctionType::Location::BLOCKHASH)},
+ {"blockhash", make_shared<FunctionType>(strings{"uint"}, strings{"hash"}, FunctionType::Location::BlockHash)},
{"difficulty", make_shared<IntegerType>(256)},
{"number", make_shared<IntegerType>(256)},
{"gaslimit", make_shared<IntegerType>(256)}});
break;
- case Kind::MSG:
- m_members = MemberList({{"sender", make_shared<IntegerType>(0, IntegerType::Modifier::ADDRESS)},
+ case Kind::Message:
+ m_members = MemberList({{"sender", make_shared<IntegerType>(0, IntegerType::Modifier::Address)},
{"gas", make_shared<IntegerType>(256)},
{"value", make_shared<IntegerType>(256)}});
break;
- case Kind::TX:
- m_members = MemberList({{"origin", make_shared<IntegerType>(0, IntegerType::Modifier::ADDRESS)},
+ case Kind::Transaction:
+ m_members = MemberList({{"origin", make_shared<IntegerType>(0, IntegerType::Modifier::Address)},
{"gasprice", make_shared<IntegerType>(256)}});
break;
default:
@@ -953,11 +964,11 @@ string MagicType::toString() const
{
switch (m_kind)
{
- case Kind::BLOCK:
+ case Kind::Block:
return "block";
- case Kind::MSG:
+ case Kind::Message:
return "msg";
- case Kind::TX:
+ case Kind::Transaction:
return "tx";
default:
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unknown kind of magic."));