2014-10-13 16:22:15 +00:00
/*
2014-10-16 12:08:54 +00:00
This file is part of cpp - ethereum .
2014-10-13 16:22:15 +00:00
2014-10-16 12:08:54 +00:00
cpp - ethereum 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 .
2014-10-13 16:22:15 +00:00
2014-10-16 12:08:54 +00:00
cpp - ethereum 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 .
2014-10-13 16:22:15 +00:00
2014-10-16 12:08:54 +00:00
You should have received a copy of the GNU General Public License
along with cpp - ethereum . If not , see < http : //www.gnu.org/licenses/>.
2014-10-13 16:22:15 +00:00
*/
/**
* @ author Christian < c @ ethdev . com >
* @ date 2014
* Solidity data types
*/
# pragma once
# include <memory>
# include <string>
2014-11-20 09:19:43 +00:00
# include <map>
2014-10-13 16:22:15 +00:00
# include <boost/noncopyable.hpp>
2014-10-20 10:41:56 +00:00
# include <libdevcore/Common.h>
2014-11-05 13:20:56 +00:00
# include <libsolidity/Exceptions.h>
2014-10-20 12:00:37 +00:00
# include <libsolidity/ASTForward.h>
2014-10-13 16:22:15 +00:00
# include <libsolidity/Token.h>
2015-01-23 18:27:56 +00:00
# include <libdevcore/UndefMacros.h>
2015-01-21 17:21:14 +00:00
2014-10-16 12:08:54 +00:00
namespace dev
{
namespace solidity
{
2014-10-13 16:22:15 +00:00
2014-11-20 09:19:43 +00:00
class Type ; // forward
2014-12-12 15:49:26 +00:00
class FunctionType ; // forward
2014-11-25 13:43:23 +00:00
using TypePointer = std : : shared_ptr < Type const > ;
2015-01-29 15:39:30 +00:00
using FunctionTypePointer = std : : shared_ptr < FunctionType const > ;
2014-11-25 13:43:23 +00:00
using TypePointers = std : : vector < TypePointer > ;
2014-11-20 09:19:43 +00:00
2015-03-13 18:48:24 +00:00
/**
* Helper class to compute storage offsets of members of structs and contracts .
*/
class StorageOffsets
{
public :
/// Resets the StorageOffsets objects and determines the position in storage for each
/// of the elements of @a _types.
void computeOffsets ( TypePointers const & _types ) ;
/// @returns the offset of the given member, might be null if the member is not part of storage.
std : : pair < u256 , unsigned > const * getOffset ( size_t _index ) const ;
/// @returns the total number of slots occupied by all members.
u256 const & getStorageSize ( ) const { return m_storageSize ; }
private :
u256 m_storageSize ;
std : : map < size_t , std : : pair < u256 , unsigned > > m_offsets ;
} ;
2014-11-20 09:19:43 +00:00
/**
* List of members of a type .
*/
class MemberList
{
public :
2015-02-17 15:19:11 +00:00
using MemberMap = std : : vector < std : : pair < std : : string , TypePointer > > ;
2014-11-20 09:19:43 +00:00
MemberList ( ) { }
explicit MemberList ( MemberMap const & _members ) : m_memberTypes ( _members ) { }
2015-03-16 18:00:09 +00:00
MemberList & operator = ( MemberList & & _other ) ;
2014-11-20 09:19:43 +00:00
TypePointer getMemberType ( std : : string const & _name ) const
{
2015-02-17 15:19:11 +00:00
for ( auto const & it : m_memberTypes )
if ( it . first = = _name )
return it . second ;
return TypePointer ( ) ;
2014-11-20 09:19:43 +00:00
}
2015-03-13 09:52:34 +00:00
/// @returns the offset of the given member in storage slots and bytes inside a slot or
/// a nullptr if the member is not part of storage.
std : : pair < u256 , unsigned > const * getMemberStorageOffset ( std : : string const & _name ) const ;
/// @returns the number of storage slots occupied by the members.
u256 const & getStorageSize ( ) const ;
2014-11-20 09:19:43 +00:00
MemberMap : : const_iterator begin ( ) const { return m_memberTypes . begin ( ) ; }
MemberMap : : const_iterator end ( ) const { return m_memberTypes . end ( ) ; }
private :
MemberMap m_memberTypes ;
2015-03-13 18:48:24 +00:00
mutable std : : unique_ptr < StorageOffsets > m_storageOffsets ;
2014-11-20 09:19:43 +00:00
} ;
2014-10-28 15:51:26 +00:00
/**
* Abstract base class that forms the root of the type hierarchy .
*/
2015-01-06 17:55:31 +00:00
class Type : private boost : : noncopyable , public std : : enable_shared_from_this < Type >
2014-10-13 16:22:15 +00:00
{
public :
2014-10-16 12:08:54 +00:00
enum class Category
{
2015-02-20 14:52:30 +00:00
Integer , IntegerConstant , Bool , Real , Array ,
2015-03-05 15:54:55 +00:00
FixedBytes , Contract , Struct , Function , Enum ,
2015-02-11 15:37:46 +00:00
Mapping , Void , TypeType , Modifier , Magic
2014-10-13 16:22:15 +00:00
} ;
2015-03-05 15:54:55 +00:00
/// @{
/// @name Factory functions
2014-10-23 15:06:12 +00:00
/// Factory functions that convert an AST @ref TypeName to a Type.
2014-12-18 17:53:43 +00:00
static TypePointer fromElementaryTypeName ( Token : : Value _typeToken ) ;
2015-02-10 16:53:43 +00:00
static TypePointer fromElementaryTypeName ( std : : string const & _name ) ;
2014-12-18 17:53:43 +00:00
static TypePointer fromUserDefinedTypeName ( UserDefinedTypeName const & _typeName ) ;
2015-02-20 14:52:30 +00:00
static TypePointer fromMapping ( ElementaryTypeName & _keyType , TypeName & _valueType ) ;
static TypePointer fromArrayTypeName ( TypeName & _baseTypeName , Expression * _length ) ;
2014-10-23 15:06:12 +00:00
/// @}
2014-10-13 16:22:15 +00:00
2014-11-04 12:24:35 +00:00
/// Auto-detect the proper type for a literal. @returns an empty pointer if the literal does
/// not fit any type.
2014-12-18 17:53:43 +00:00
static TypePointer forLiteral ( Literal const & _literal ) ;
/// @returns a pointer to _a or _b if the other is implicitly convertible to it or nullptr otherwise
static TypePointer commonType ( TypePointer const & _a , TypePointer const & _b ) ;
2014-10-13 16:22:15 +00:00
2015-03-13 09:52:34 +00:00
/// Calculates the
2014-10-13 16:22:15 +00:00
virtual Category getCategory ( ) const = 0 ;
2014-10-20 10:41:56 +00:00
virtual bool isImplicitlyConvertibleTo ( Type const & _other ) const { return * this = = _other ; }
2014-10-20 11:02:06 +00:00
virtual bool isExplicitlyConvertibleTo ( Type const & _convertTo ) const
2014-10-16 12:08:54 +00:00
{
return isImplicitlyConvertibleTo ( _convertTo ) ;
}
2015-01-06 18:08:24 +00:00
/// @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 : : Value ) const { return TypePointer ( ) ; }
2015-01-06 17:55:31 +00:00
/// @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 : : Value _operator , TypePointer const & _other ) const
{
return Token : : isCompareOp ( _operator ) ? commonType ( shared_from_this ( ) , _other ) : TypePointer ( ) ;
}
2014-10-16 15:57:27 +00:00
2014-10-20 10:41:56 +00:00
virtual bool operator = = ( Type const & _other ) const { return getCategory ( ) = = _other . getCategory ( ) ; }
virtual bool operator ! = ( Type const & _other ) const { return ! this - > operator = = ( _other ) ; }
2014-10-30 17:15:25 +00:00
/// @returns number of bytes used by this type when encoded for CALL, or 0 if the encoding
2015-01-08 23:58:32 +00:00
/// is not a simple big-endian encoding or the type cannot be stored in calldata.
2015-03-05 17:22:17 +00:00
/// If @a _padded then it is assumed that each element is padded to a multiple of 32 bytes.
virtual unsigned getCalldataEncodedSize ( bool _padded ) const { ( void ) _padded ; return 0 ; }
2015-03-06 14:39:21 +00:00
/// Convenience version of @see getCalldataEncodedSize(bool)
2015-03-05 17:22:17 +00:00
unsigned getCalldataEncodedSize ( ) const { return getCalldataEncodedSize ( true ) ; }
2015-02-15 01:00:33 +00:00
/// @returns true if the type is dynamically encoded in calldata
virtual bool isDynamicallySized ( ) const { return false ; }
2015-03-13 09:52:34 +00:00
/// @returns the number of storage slots required to hold this value in storage.
2014-11-07 01:06:37 +00:00
/// For dynamically "allocated" types, it returns the size of the statically allocated head,
virtual u256 getStorageSize ( ) const { return 1 ; }
2015-03-13 09:52:34 +00:00
/// Multiple small types can be packed into a single storage slot. If such a packing is possible
/// this function @returns the size in bytes smaller than 32. Data is moved to the next slot if
/// it does not fit.
/// In order to avoid computation at runtime of whether such moving is necessary, structs and
/// array data (not each element) always start a new slot.
virtual unsigned getStorageBytes ( ) const { return 32 ; }
2014-11-20 17:33:23 +00:00
/// Returns true if the type can be stored in storage.
virtual bool canBeStored ( ) const { return true ; }
2014-11-10 16:31:09 +00:00
/// Returns false if the type cannot live outside the storage, i.e. if it includes some mapping.
virtual bool canLiveOutsideStorage ( ) const { return true ; }
2014-11-21 18:14:56 +00:00
/// Returns true if the type can be stored as a value (as opposed to a reference) on the stack,
/// i.e. it behaves differently in lvalue context and in value context.
virtual bool isValueType ( ) const { return false ; }
2014-11-25 17:23:39 +00:00
virtual unsigned getSizeOnStack ( ) const { return 1 ; }
2015-02-06 12:42:51 +00:00
/// @returns the real type of some types, like e.g: IntegerConstant
2015-02-06 19:57:04 +00:00
virtual TypePointer getRealType ( ) const { return shared_from_this ( ) ; }
2014-10-30 17:15:25 +00:00
2014-11-20 09:19:43 +00:00
/// Returns the list of all members of this type. Default implementation: no members.
virtual MemberList const & getMembers ( ) const { return EmptyMemberList ; }
/// Convenience method, returns the type of the given named member or an empty pointer if no such member exists.
2014-11-25 13:43:23 +00:00
TypePointer getMemberType ( std : : string const & _name ) const { return getMembers ( ) . getMemberType ( _name ) ; }
2014-11-20 09:19:43 +00:00
2014-10-16 15:57:27 +00:00
virtual std : : string toString ( ) const = 0 ;
2014-12-19 10:31:17 +00:00
virtual u256 literalValue ( Literal const * ) const
2014-11-05 13:20:56 +00:00
{
BOOST_THROW_EXCEPTION ( InternalCompilerError ( ) < < errinfo_comment ( " Literal value requested "
2015-02-06 12:42:51 +00:00
" for type without literals. " ) ) ;
2014-11-05 13:20:56 +00:00
}
2014-11-20 09:19:43 +00:00
2015-03-20 16:02:24 +00:00
/// @returns a type suitable for outside of Solidity, i.e. for contract types it returns address.
/// If there is no such type, returns an empty shared pointer.
2015-03-19 15:48:54 +00:00
virtual TypePointer externalType ( ) const { return TypePointer ( ) ; }
2015-03-17 13:21:22 +00:00
2014-11-20 09:19:43 +00:00
protected :
/// Convenience object used when returning an empty member list.
static const MemberList EmptyMemberList ;
2014-10-13 16:22:15 +00:00
} ;
2014-10-28 15:51:26 +00:00
/**
2015-03-11 16:52:18 +00:00
* Any kind of integer type ( signed , unsigned , address ) .
2014-10-28 15:51:26 +00:00
*/
2014-10-16 21:49:45 +00:00
class IntegerType : public Type
2014-10-13 16:22:15 +00:00
{
public :
2014-10-16 12:08:54 +00:00
enum class Modifier
{
2015-03-05 15:54:55 +00:00
Unsigned , Signed , Address
2014-10-13 16:22:15 +00:00
} ;
2015-02-09 13:00:12 +00:00
virtual Category getCategory ( ) const override { return Category : : Integer ; }
2014-10-13 16:22:15 +00:00
2015-02-09 13:08:48 +00:00
explicit IntegerType ( int _bits , Modifier _modifier = Modifier : : Unsigned ) ;
2014-10-13 16:22:15 +00:00
virtual bool isImplicitlyConvertibleTo ( Type const & _convertTo ) const override ;
2014-10-20 11:02:06 +00:00
virtual bool isExplicitlyConvertibleTo ( Type const & _convertTo ) const override ;
2015-01-06 18:08:24 +00:00
virtual TypePointer unaryOperatorResult ( Token : : Value _operator ) const override ;
2015-01-06 17:55:31 +00:00
virtual TypePointer binaryOperatorResult ( Token : : Value _operator , TypePointer const & _other ) const override ;
2014-10-13 16:22:15 +00:00
2014-10-20 10:41:56 +00:00
virtual bool operator = = ( Type const & _other ) const override ;
2015-03-05 17:22:17 +00:00
virtual unsigned getCalldataEncodedSize ( bool _padded = true ) const override { return _padded ? 32 : m_bits / 8 ; }
2015-03-13 09:52:34 +00:00
virtual unsigned getStorageBytes ( ) const override { return m_bits / 8 ; }
2014-11-21 18:14:56 +00:00
virtual bool isValueType ( ) const override { return true ; }
2015-03-17 13:21:22 +00:00
virtual MemberList const & getMembers ( ) const override { return isAddress ( ) ? AddressMemberList : EmptyMemberList ; }
2014-10-30 17:15:25 +00:00
2014-10-16 15:57:27 +00:00
virtual std : : string toString ( ) const override ;
2015-03-19 15:48:54 +00:00
virtual TypePointer externalType ( ) const override { return shared_from_this ( ) ; }
2015-03-17 13:21:22 +00:00
2014-10-13 16:22:15 +00:00
int getNumBits ( ) const { return m_bits ; }
2015-02-09 13:00:12 +00:00
bool isAddress ( ) const { return m_modifier = = Modifier : : Address ; }
2015-02-09 13:08:48 +00:00
bool isSigned ( ) const { return m_modifier = = Modifier : : Signed ; }
2014-10-20 12:00:37 +00:00
2015-01-07 21:54:56 +00:00
static const MemberList AddressMemberList ;
2014-10-13 16:22:15 +00:00
private :
int m_bits ;
Modifier m_modifier ;
} ;
2014-12-19 10:31:17 +00:00
/**
* Integer constants either literals or computed . Example expressions : 2 , 2 + 10 , ~ 10.
* There is one distinct type per value .
*/
class IntegerConstantType : public Type
{
public :
2015-02-09 13:00:12 +00:00
virtual Category getCategory ( ) const override { return Category : : IntegerConstant ; }
2014-12-19 10:31:17 +00:00
2015-02-06 12:38:10 +00:00
explicit IntegerConstantType ( Literal const & _literal ) ;
2014-12-19 10:31:17 +00:00
explicit IntegerConstantType ( bigint _value ) : m_value ( _value ) { }
virtual bool isImplicitlyConvertibleTo ( Type const & _convertTo ) const override ;
virtual bool isExplicitlyConvertibleTo ( Type const & _convertTo ) const override ;
virtual TypePointer unaryOperatorResult ( Token : : Value _operator ) const override ;
virtual TypePointer binaryOperatorResult ( Token : : Value _operator , TypePointer const & _other ) const override ;
virtual bool operator = = ( Type const & _other ) const override ;
virtual bool canBeStored ( ) const override { return false ; }
virtual bool canLiveOutsideStorage ( ) const override { return false ; }
virtual unsigned getSizeOnStack ( ) const override { return 1 ; }
virtual std : : string toString ( ) const override ;
virtual u256 literalValue ( Literal const * _literal ) const override ;
2015-02-06 12:42:51 +00:00
virtual TypePointer getRealType ( ) const override ;
2014-12-19 10:31:17 +00:00
/// @returns the smallest integer type that can hold the value or an empty pointer if not possible.
std : : shared_ptr < IntegerType const > getIntegerType ( ) const ;
private :
bigint m_value ;
} ;
2014-12-09 17:46:18 +00:00
/**
2015-03-11 16:52:18 +00:00
* Bytes type with fixed length of up to 32 bytes .
2014-12-09 17:46:18 +00:00
*/
2015-03-05 15:54:55 +00:00
class FixedBytesType : public Type
2014-12-09 17:46:18 +00:00
{
public :
2015-03-05 15:54:55 +00:00
virtual Category getCategory ( ) const override { return Category : : FixedBytes ; }
2014-12-09 17:46:18 +00:00
2015-03-05 15:54:55 +00:00
/// @returns the smallest bytes type for the given literal or an empty pointer
2014-12-09 17:46:18 +00:00
/// if no type fits.
2015-03-05 15:54:55 +00:00
static std : : shared_ptr < FixedBytesType > smallestTypeForLiteral ( std : : string const & _literal ) ;
2014-12-09 17:46:18 +00:00
2015-03-05 15:54:55 +00:00
explicit FixedBytesType ( int _bytes ) ;
2014-12-09 17:46:18 +00:00
virtual bool isImplicitlyConvertibleTo ( Type const & _convertTo ) const override ;
2015-01-23 16:36:12 +00:00
virtual bool isExplicitlyConvertibleTo ( Type const & _convertTo ) const override ;
2014-12-09 17:46:18 +00:00
virtual bool operator = = ( Type const & _other ) const override ;
2015-03-05 15:54:55 +00:00
virtual TypePointer unaryOperatorResult ( Token : : Value _operator ) const override ;
virtual TypePointer binaryOperatorResult ( Token : : Value _operator , TypePointer const & _other ) const override ;
2014-12-09 17:46:18 +00:00
2015-03-05 17:22:17 +00:00
virtual unsigned getCalldataEncodedSize ( bool _padded ) const override { return _padded & & m_bytes > 0 ? 32 : m_bytes ; }
2015-03-13 09:52:34 +00:00
virtual unsigned getStorageBytes ( ) const override { return m_bytes ; }
2014-12-09 17:46:18 +00:00
virtual bool isValueType ( ) const override { return true ; }
2015-03-05 15:54:55 +00:00
virtual std : : string toString ( ) const override { return " bytes " + dev : : toString ( m_bytes ) ; }
2014-12-19 10:31:17 +00:00
virtual u256 literalValue ( Literal const * _literal ) const override ;
2015-03-20 12:30:00 +00:00
virtual TypePointer externalType ( ) const override { return shared_from_this ( ) ; }
2014-12-09 17:46:18 +00:00
int getNumBytes ( ) const { return m_bytes ; }
private :
int m_bytes ;
} ;
2014-10-28 15:51:26 +00:00
/**
* The boolean type .
*/
2014-10-16 21:49:45 +00:00
class BoolType : public Type
2014-10-13 16:22:15 +00:00
{
public :
2014-12-11 13:12:49 +00:00
BoolType ( ) { }
2015-02-09 17:45:00 +00:00
virtual Category getCategory ( ) const override { return Category : : Bool ; }
2014-10-20 11:02:06 +00:00
virtual bool isExplicitlyConvertibleTo ( Type const & _convertTo ) const override ;
2015-01-14 12:52:03 +00:00
virtual TypePointer unaryOperatorResult ( Token : : Value _operator ) const override ;
2015-01-06 17:55:31 +00:00
virtual TypePointer binaryOperatorResult ( Token : : Value _operator , TypePointer const & _other ) const override ;
2014-10-20 10:41:56 +00:00
2015-03-17 13:21:22 +00:00
virtual unsigned getCalldataEncodedSize ( bool _padded ) const override { return _padded ? 32 : 1 ; }
2015-03-13 09:52:34 +00:00
virtual unsigned getStorageBytes ( ) const override { return 1 ; }
2014-11-21 18:14:56 +00:00
virtual bool isValueType ( ) const override { return true ; }
2014-10-30 17:15:25 +00:00
2014-10-16 15:57:27 +00:00
virtual std : : string toString ( ) const override { return " bool " ; }
2014-12-19 10:31:17 +00:00
virtual u256 literalValue ( Literal const * _literal ) const override ;
2015-03-20 12:30:00 +00:00
virtual TypePointer externalType ( ) const override { return shared_from_this ( ) ; }
2014-10-13 16:22:15 +00:00
} ;
2015-02-09 17:45:00 +00:00
/**
2015-02-23 13:55:06 +00:00
* The type of an array . The flavours are byte array ( bytes ) , statically - ( < type > [ < length > ] )
2015-02-23 13:38:44 +00:00
* and dynamically - sized array ( < type > [ ] ) .
2015-03-11 17:09:35 +00:00
* In storage , all arrays are packed tightly ( as long as more than one elementary type fits in
* one slot ) . Dynamically sized arrays ( including byte arrays ) start with their size as a uint and
* thus start on their own slot .
2015-02-09 17:45:00 +00:00
*/
2015-02-20 14:52:30 +00:00
class ArrayType : public Type
2015-02-09 17:45:00 +00:00
{
public :
enum class Location { Storage , CallData , Memory } ;
2015-02-20 14:52:30 +00:00
virtual Category getCategory ( ) const override { return Category : : Array ; }
/// Constructor for a byte array ("bytes")
explicit ArrayType ( Location _location ) :
2015-03-16 16:52:19 +00:00
m_location ( _location ) ,
m_isByteArray ( true ) ,
m_baseType ( std : : make_shared < FixedBytesType > ( 8 ) )
{ }
2015-02-20 14:52:30 +00:00
/// Constructor for a dynamically sized array type ("type[]")
ArrayType ( Location _location , const TypePointer & _baseType ) :
2015-03-16 16:52:19 +00:00
m_location ( _location ) ,
m_baseType ( _baseType )
{ }
2015-02-20 14:52:30 +00:00
/// Constructor for a fixed-size array type ("type[20]")
ArrayType ( Location _location , const TypePointer & _baseType , u256 const & _length ) :
2015-03-16 16:52:19 +00:00
m_location ( _location ) ,
m_baseType ( _baseType ) ,
m_hasDynamicLength ( false ) ,
m_length ( _length )
{ }
2015-02-20 14:52:30 +00:00
2015-02-10 08:00:50 +00:00
virtual bool isImplicitlyConvertibleTo ( Type const & _convertTo ) const override ;
2015-02-10 13:57:01 +00:00
virtual TypePointer unaryOperatorResult ( Token : : Value _operator ) const override ;
2015-02-09 17:45:00 +00:00
virtual bool operator = = ( const Type & _other ) const override ;
2015-03-05 17:22:17 +00:00
virtual unsigned getCalldataEncodedSize ( bool _padded ) const override ;
2015-02-20 14:52:30 +00:00
virtual bool isDynamicallySized ( ) const { return m_hasDynamicLength ; }
2015-02-22 18:15:41 +00:00
virtual u256 getStorageSize ( ) const override ;
2015-02-10 13:57:01 +00:00
virtual unsigned getSizeOnStack ( ) const override ;
2015-02-20 14:52:30 +00:00
virtual std : : string toString ( ) const override ;
virtual MemberList const & getMembers ( ) const override { return s_arrayTypeMemberList ; }
2015-03-19 15:48:54 +00:00
virtual TypePointer externalType ( ) const override ;
2015-02-10 13:57:01 +00:00
Location getLocation ( ) const { return m_location ; }
2015-02-20 14:52:30 +00:00
bool isByteArray ( ) const { return m_isByteArray ; }
TypePointer const & getBaseType ( ) const { solAssert ( ! ! m_baseType , " " ) ; return m_baseType ; }
u256 const & getLength ( ) const { return m_length ; }
2015-02-10 13:57:01 +00:00
2015-02-16 16:33:13 +00:00
/// @returns a copy of this type with location changed to @a _location
/// @todo this might move as far up as Type later
2015-02-20 14:52:30 +00:00
std : : shared_ptr < ArrayType > copyForLocation ( Location _location ) const ;
2015-02-16 16:33:13 +00:00
2015-02-09 17:45:00 +00:00
private :
Location m_location ;
2015-02-20 14:52:30 +00:00
bool m_isByteArray = false ; ///< Byte arrays ("bytes") have different semantics from ordinary arrays.
TypePointer m_baseType ;
bool m_hasDynamicLength = true ;
u256 m_length ;
static const MemberList s_arrayTypeMemberList ;
2015-02-09 17:45:00 +00:00
} ;
2014-10-28 15:51:26 +00:00
/**
* The type of a contract instance , there is one distinct type for each contract definition .
*/
2014-10-16 21:49:45 +00:00
class ContractType : public Type
2014-10-13 16:22:15 +00:00
{
public :
2015-02-09 13:00:12 +00:00
virtual Category getCategory ( ) const override { return Category : : Contract ; }
2015-01-27 13:32:59 +00:00
explicit ContractType ( ContractDefinition const & _contract , bool _super = false ) :
m_contract ( _contract ) , m_super ( _super ) { }
2015-01-07 21:54:56 +00:00
/// Contracts can be implicitly converted to super classes and to addresses.
virtual bool isImplicitlyConvertibleTo ( Type const & _convertTo ) const override ;
/// Contracts can be converted to themselves and to integers.
2014-11-20 17:33:23 +00:00
virtual bool isExplicitlyConvertibleTo ( Type const & _convertTo ) const override ;
2015-01-14 12:52:03 +00:00
virtual TypePointer unaryOperatorResult ( Token : : Value _operator ) const override ;
2014-10-20 10:41:56 +00:00
virtual bool operator = = ( Type const & _other ) const override ;
2015-03-13 09:52:34 +00:00
virtual unsigned getStorageBytes ( ) const override { return 20 ; }
2014-12-04 18:38:24 +00:00
virtual bool isValueType ( ) const override { return true ; }
2014-11-20 17:33:23 +00:00
virtual std : : string toString ( ) const override ;
2014-10-16 15:57:27 +00:00
2014-12-04 18:38:24 +00:00
virtual MemberList const & getMembers ( ) const override ;
2015-03-19 15:48:54 +00:00
virtual TypePointer externalType ( ) const override { return std : : make_shared < IntegerType > ( 160 , IntegerType : : Modifier : : Address ) ; }
2014-12-04 18:38:24 +00:00
2015-01-27 13:32:59 +00:00
bool isSuper ( ) const { return m_super ; }
2015-01-13 17:12:19 +00:00
ContractDefinition const & getContractDefinition ( ) const { return m_contract ; }
2014-12-12 15:49:26 +00:00
/// Returns the function type of the constructor. Note that the location part of the function type
/// is not used, as this type cannot be the type of a variable or expression.
2015-01-29 15:48:39 +00:00
FunctionTypePointer const & getConstructorType ( ) const ;
2014-12-12 15:49:26 +00:00
2015-01-07 21:54:56 +00:00
/// @returns the identifier of the function with the given name or Invalid256 if such a name does
/// not exist.
2015-01-08 16:18:31 +00:00
u256 getFunctionIdentifier ( std : : string const & _functionName ) const ;
2014-12-04 18:38:24 +00:00
2015-03-16 15:15:13 +00:00
/// @returns a list of all state variables (including inherited) of the contract and their
/// offsets in storage.
std : : vector < std : : tuple < VariableDeclaration const * , u256 , unsigned > > getStateVariables ( ) const ;
2014-10-13 16:22:15 +00:00
private :
ContractDefinition const & m_contract ;
2015-01-27 13:32:59 +00:00
/// If true, it is the "super" type of the current contract, i.e. it contains only inherited
/// members.
bool m_super ;
2014-12-12 15:49:26 +00:00
/// Type of the constructor, @see getConstructorType. Lazily initialized.
2015-01-29 15:48:39 +00:00
mutable FunctionTypePointer m_constructorType ;
2014-12-04 18:38:24 +00:00
/// List of member types, will be lazy-initialized because of recursive references.
mutable std : : unique_ptr < MemberList > m_members ;
2014-10-13 16:22:15 +00:00
} ;
2014-10-28 15:51:26 +00:00
/**
* The type of a struct instance , there is one distinct type per struct definition .
*/
2014-10-16 21:49:45 +00:00
class StructType : public Type
2014-10-13 16:22:15 +00:00
{
public :
2015-02-09 13:00:12 +00:00
virtual Category getCategory ( ) const override { return Category : : Struct ; }
2015-01-27 13:32:59 +00:00
explicit StructType ( StructDefinition const & _struct ) : m_struct ( _struct ) { }
2015-01-14 12:52:03 +00:00
virtual TypePointer unaryOperatorResult ( Token : : Value _operator ) const override ;
2014-10-20 10:41:56 +00:00
virtual bool operator = = ( Type const & _other ) const override ;
2014-11-20 17:33:23 +00:00
virtual u256 getStorageSize ( ) const override ;
virtual bool canLiveOutsideStorage ( ) const override ;
2015-03-11 17:09:35 +00:00
virtual unsigned getSizeOnStack ( ) const override { return 2 ; }
2014-11-13 00:12:57 +00:00
virtual std : : string toString ( ) const override ;
2014-11-20 09:19:43 +00:00
virtual MemberList const & getMembers ( ) const override ;
2015-03-13 18:48:24 +00:00
std : : pair < u256 , unsigned > const & getStorageOffsetsOfMember ( std : : string const & _name ) const ;
2014-10-16 15:57:27 +00:00
2014-10-13 16:22:15 +00:00
private :
StructDefinition const & m_struct ;
2014-11-20 09:19:43 +00:00
/// List of member types, will be lazy-initialized because of recursive references.
mutable std : : unique_ptr < MemberList > m_members ;
2014-10-13 16:22:15 +00:00
} ;
2015-02-11 15:37:46 +00:00
/**
* The type of an enum instance , there is one distinct type per enum definition .
*/
class EnumType : public Type
{
public :
virtual Category getCategory ( ) const override { return Category : : Enum ; }
explicit EnumType ( EnumDefinition const & _enum ) : m_enum ( _enum ) { }
virtual TypePointer unaryOperatorResult ( Token : : Value _operator ) const override ;
virtual bool operator = = ( Type const & _other ) const override ;
2015-02-13 21:52:04 +00:00
virtual unsigned getSizeOnStack ( ) const override { return 1 ; }
2015-03-13 09:52:34 +00:00
virtual unsigned getStorageBytes ( ) const override ;
2015-02-11 15:37:46 +00:00
virtual std : : string toString ( ) const override ;
2015-02-12 14:19:04 +00:00
virtual bool isValueType ( ) const override { return true ; }
2015-02-11 15:37:46 +00:00
2015-02-12 16:59:52 +00:00
virtual bool isExplicitlyConvertibleTo ( Type const & _convertTo ) const override ;
2015-03-19 15:48:54 +00:00
virtual TypePointer externalType ( ) const override { return std : : make_shared < IntegerType > ( 8 * int ( getStorageBytes ( ) ) ) ; }
2015-02-12 16:59:52 +00:00
2015-02-12 14:19:04 +00:00
EnumDefinition const & getEnumDefinition ( ) const { return m_enum ; }
2015-02-13 22:03:32 +00:00
/// @returns the value that the string has in the Enum
unsigned int getMemberValue ( ASTString const & _member ) const ;
2015-02-11 15:37:46 +00:00
private :
EnumDefinition const & m_enum ;
/// List of member types, will be lazy-initialized because of recursive references.
mutable std : : unique_ptr < MemberList > m_members ;
} ;
2014-10-28 15:51:26 +00:00
/**
2014-11-25 13:43:23 +00:00
* The type of a function , identified by its ( return ) parameter types .
* @ todo the return parameters should also have names , i . e . return parameters should be a struct
* type .
2014-10-28 15:51:26 +00:00
*/
2014-10-16 21:49:45 +00:00
class FunctionType : public Type
2014-10-13 16:22:15 +00:00
{
public :
2014-11-25 17:23:39 +00:00
/// The meaning of the value(s) on the stack referencing the function:
2015-01-12 11:47:37 +00:00
/// INTERNAL: jump tag, EXTERNAL: contract address + function identifier,
2014-12-10 22:01:40 +00:00
/// BARE: contract address (non-abi contract call)
2014-11-25 17:23:39 +00:00
/// OTHERS: special virtual function, nothing on the stack
2015-01-29 13:35:28 +00:00
/// @todo This documentation is outdated, and Location should rather be named "Type"
2015-02-09 13:08:48 +00:00
enum class Location { Internal , External , Creation , Send ,
SHA3 , Suicide ,
ECRecover , SHA256 , RIPEMD160 ,
Log0 , Log1 , Log2 , Log3 , Log4 , Event ,
SetGas , SetValue , BlockHash ,
Bare } ;
2014-11-25 17:23:39 +00:00
2015-02-09 13:00:12 +00:00
virtual Category getCategory ( ) const override { return Category : : Function ; }
2015-03-27 12:28:32 +00:00
2015-04-01 13:19:33 +00:00
/// @returns TypePointer of a new FunctionType object. All input/return parameters are an appropriate external types of input/return parameters of current function.
2015-04-01 13:26:37 +00:00
/// Returns an empty shared pointer if one of the input/return parameters does not have an externaltype.
2015-03-27 12:28:32 +00:00
virtual TypePointer externalType ( ) const override ;
2014-12-04 18:38:24 +00:00
explicit FunctionType ( FunctionDefinition const & _function , bool _isInternal = true ) ;
2015-01-22 16:40:22 +00:00
explicit FunctionType ( VariableDeclaration const & _varDecl ) ;
2015-01-29 13:35:28 +00:00
explicit FunctionType ( EventDefinition const & _event ) ;
2015-01-12 12:29:16 +00:00
FunctionType ( strings const & _parameterTypes , strings const & _returnParameterTypes ,
2015-02-10 09:45:57 +00:00
Location _location = Location : : Internal , bool _arbitraryParameters = false ) :
2015-01-12 12:29:16 +00:00
FunctionType ( parseElementaryTypeVector ( _parameterTypes ) , parseElementaryTypeVector ( _returnParameterTypes ) ,
2015-02-10 09:45:57 +00:00
_location , _arbitraryParameters ) { }
2015-02-20 20:00:13 +00:00
FunctionType (
TypePointers const & _parameterTypes ,
TypePointers const & _returnParameterTypes ,
Location _location = Location : : Internal ,
bool _arbitraryParameters = false ,
bool _gasSet = false ,
bool _valueSet = false
) :
m_parameterTypes ( _parameterTypes ) ,
m_returnParameterTypes ( _returnParameterTypes ) ,
m_location ( _location ) ,
m_arbitraryParameters ( _arbitraryParameters ) ,
m_gasSet ( _gasSet ) ,
m_valueSet ( _valueSet )
{ }
2014-10-13 16:22:15 +00:00
2014-11-25 13:43:23 +00:00
TypePointers const & getParameterTypes ( ) const { return m_parameterTypes ; }
2015-01-23 15:37:06 +00:00
std : : vector < std : : string > const & getParameterNames ( ) const { return m_parameterNames ; }
2015-01-29 15:39:30 +00:00
std : : vector < std : : string > const getParameterTypeNames ( ) const ;
2014-11-25 13:43:23 +00:00
TypePointers const & getReturnParameterTypes ( ) const { return m_returnParameterTypes ; }
2015-01-23 15:37:06 +00:00
std : : vector < std : : string > const & getReturnParameterNames ( ) const { return m_returnParameterNames ; }
2015-01-29 15:39:30 +00:00
std : : vector < std : : string > const getReturnParameterTypeNames ( ) const ;
2014-10-20 12:00:37 +00:00
2014-10-20 10:41:56 +00:00
virtual bool operator = = ( Type const & _other ) const override ;
2014-11-13 00:12:57 +00:00
virtual std : : string toString ( ) const override ;
2014-11-20 17:33:23 +00:00
virtual bool canBeStored ( ) const override { return false ; }
2015-03-13 09:52:34 +00:00
virtual u256 getStorageSize ( ) const override ;
2014-11-20 17:33:23 +00:00
virtual bool canLiveOutsideStorage ( ) const override { return false ; }
2014-11-25 17:23:39 +00:00
virtual unsigned getSizeOnStack ( ) const override ;
2015-01-12 11:47:37 +00:00
virtual MemberList const & getMembers ( ) const override ;
2014-11-25 17:23:39 +00:00
2014-12-06 01:39:58 +00:00
Location const & getLocation ( ) const { return m_location ; }
2015-03-24 10:11:27 +00:00
/// @returns the external signature of this function type given the function name
2015-01-29 15:39:30 +00:00
/// If @a _name is not provided (empty string) then the @c m_declaration member of the
/// function type is used
2015-03-27 12:28:32 +00:00
std : : string externalSignature ( std : : string const & _name = " " ) const ;
2015-01-29 17:44:14 +00:00
Declaration const & getDeclaration ( ) const
{
solAssert ( m_declaration , " Requested declaration from a FunctionType that has none " ) ;
return * m_declaration ;
}
bool hasDeclaration ( ) const { return ! ! m_declaration ; }
2015-01-29 15:39:30 +00:00
bool isConstant ( ) const { return m_isConstant ; }
/// @return A shared pointer of an ASTString.
/// Can contain a nullptr in which case indicates absence of documentation
ASTPointer < ASTString > getDocumentation ( ) const ;
2014-10-20 10:41:56 +00:00
2015-02-10 09:45:57 +00:00
/// true iff arguments are to be padded to multiples of 32 bytes for external calls
bool padArguments ( ) const { return ! ( m_location = = Location : : SHA3 | | m_location = = Location : : SHA256 | | m_location = = Location : : RIPEMD160 ) ; }
bool takesArbitraryParameters ( ) const { return m_arbitraryParameters ; }
2015-01-12 11:47:37 +00:00
bool gasSet ( ) const { return m_gasSet ; }
bool valueSet ( ) const { return m_valueSet ; }
/// @returns a copy of this type, where gas or value are set manually. This will never set one
/// of the parameters to fals.
TypePointer copyAndSetGasOrValue ( bool _setGas , bool _setValue ) const ;
2014-10-13 16:22:15 +00:00
private :
2015-01-12 12:29:16 +00:00
static TypePointers parseElementaryTypeVector ( strings const & _types ) ;
2015-01-12 11:46:52 +00:00
2014-11-25 13:43:23 +00:00
TypePointers m_parameterTypes ;
TypePointers m_returnParameterTypes ;
2015-01-23 15:37:06 +00:00
std : : vector < std : : string > m_parameterNames ;
std : : vector < std : : string > m_returnParameterNames ;
2015-01-14 10:01:42 +00:00
Location const m_location ;
2015-03-03 11:58:01 +00:00
/// true if the function takes an arbitrary number of arguments of arbitrary types
2015-02-10 09:45:57 +00:00
bool const m_arbitraryParameters = false ;
2015-01-14 10:01:42 +00:00
bool const m_gasSet = false ; ///< true iff the gas value to be used is on the stack
bool const m_valueSet = false ; ///< true iff the value to be sent is on the stack
2015-02-20 20:00:13 +00:00
bool m_isConstant = false ;
2015-01-12 11:47:37 +00:00
mutable std : : unique_ptr < MemberList > m_members ;
2015-01-29 15:39:30 +00:00
Declaration const * m_declaration = nullptr ;
2014-10-13 16:22:15 +00:00
} ;
2014-10-28 15:51:26 +00:00
/**
* The type of a mapping , there is one distinct type per key / value type pair .
2015-03-11 17:09:35 +00:00
* Mappings always occupy their own storage slot , but do not actually use it .
2014-10-28 15:51:26 +00:00
*/
2014-10-16 21:49:45 +00:00
class MappingType : public Type
2014-10-13 16:22:15 +00:00
{
public :
2015-02-09 13:00:12 +00:00
virtual Category getCategory ( ) const override { return Category : : Mapping ; }
2014-11-25 13:43:23 +00:00
MappingType ( TypePointer const & _keyType , TypePointer const & _valueType ) :
2014-11-10 16:31:09 +00:00
m_keyType ( _keyType ) , m_valueType ( _valueType ) { }
2014-10-16 15:57:27 +00:00
2014-10-20 10:41:56 +00:00
virtual bool operator = = ( Type const & _other ) const override ;
2014-11-13 00:12:57 +00:00
virtual std : : string toString ( ) const override ;
2015-03-11 17:09:35 +00:00
virtual unsigned getSizeOnStack ( ) const override { return 2 ; }
2014-11-20 17:33:23 +00:00
virtual bool canLiveOutsideStorage ( ) const override { return false ; }
2014-10-20 10:41:56 +00:00
2014-12-12 15:49:26 +00:00
TypePointer const & getKeyType ( ) const { return m_keyType ; }
TypePointer const & getValueType ( ) const { return m_valueType ; }
2014-11-13 00:12:57 +00:00
2014-10-13 16:22:15 +00:00
private :
2014-11-25 13:43:23 +00:00
TypePointer m_keyType ;
TypePointer m_valueType ;
2014-10-13 16:22:15 +00:00
} ;
2014-10-28 15:51:26 +00:00
/**
* The void type , can only be implicitly used as the type that is returned by functions without
* return parameters .
*/
2014-10-16 21:49:45 +00:00
class VoidType : public Type
2014-10-13 16:22:15 +00:00
{
public :
2015-02-09 13:00:12 +00:00
virtual Category getCategory ( ) const override { return Category : : Void ; }
2014-10-13 16:22:15 +00:00
VoidType ( ) { }
2014-10-20 10:41:56 +00:00
2015-01-06 17:55:31 +00:00
virtual TypePointer binaryOperatorResult ( Token : : Value , TypePointer const & ) const override { return TypePointer ( ) ; }
2014-10-16 15:57:27 +00:00
virtual std : : string toString ( ) const override { return " void " ; }
2014-11-20 17:33:23 +00:00
virtual bool canBeStored ( ) const override { return false ; }
2015-03-13 09:52:34 +00:00
virtual u256 getStorageSize ( ) const override ;
2014-11-20 17:33:23 +00:00
virtual bool canLiveOutsideStorage ( ) const override { return false ; }
2014-11-25 17:23:39 +00:00
virtual unsigned getSizeOnStack ( ) const override { return 0 ; }
2014-10-13 16:22:15 +00:00
} ;
2014-10-28 15:51:26 +00:00
/**
* The type of a type reference . The type of " uint32 " when used in " a = uint32(2) " is an example
* of a TypeType .
*/
2014-10-16 21:49:45 +00:00
class TypeType : public Type
2014-10-13 16:22:15 +00:00
{
public :
2015-02-10 08:52:19 +00:00
virtual Category getCategory ( ) const override { return Category : : TypeType ; }
2015-01-27 13:32:59 +00:00
explicit TypeType ( TypePointer const & _actualType , ContractDefinition const * _currentContract = nullptr ) :
2015-01-19 18:18:34 +00:00
m_actualType ( _actualType ) , m_currentContract ( _currentContract ) { }
2014-11-25 13:43:23 +00:00
TypePointer const & getActualType ( ) const { return m_actualType ; }
2014-10-13 16:22:15 +00:00
2015-01-06 17:55:31 +00:00
virtual TypePointer binaryOperatorResult ( Token : : Value , TypePointer const & ) const override { return TypePointer ( ) ; }
2014-10-20 10:41:56 +00:00
virtual bool operator = = ( Type const & _other ) const override ;
2014-11-20 17:33:23 +00:00
virtual bool canBeStored ( ) const override { return false ; }
2015-03-13 09:52:34 +00:00
virtual u256 getStorageSize ( ) const override ;
2014-11-20 17:33:23 +00:00
virtual bool canLiveOutsideStorage ( ) const override { return false ; }
2015-01-28 17:19:01 +00:00
virtual unsigned getSizeOnStack ( ) const override { return 0 ; }
2014-10-16 15:57:27 +00:00
virtual std : : string toString ( ) const override { return " type( " + m_actualType - > toString ( ) + " ) " ; }
2015-01-19 18:18:34 +00:00
virtual MemberList const & getMembers ( ) const override ;
2014-10-16 15:57:27 +00:00
2014-10-13 16:22:15 +00:00
private :
2014-11-25 13:43:23 +00:00
TypePointer m_actualType ;
2015-01-19 18:18:34 +00:00
/// Context in which this type is used (influences visibility etc.), can be nullptr.
ContractDefinition const * m_currentContract ;
/// List of member types, will be lazy-initialized because of recursive references.
mutable std : : unique_ptr < MemberList > m_members ;
2014-10-13 16:22:15 +00:00
} ;
2015-01-22 00:02:38 +00:00
/**
* The type of a function modifier . Not used for anything for now .
*/
class ModifierType : public Type
{
public :
2015-02-09 13:00:12 +00:00
virtual Category getCategory ( ) const override { return Category : : Modifier ; }
2015-01-22 00:02:38 +00:00
explicit ModifierType ( ModifierDefinition const & _modifier ) ;
virtual TypePointer binaryOperatorResult ( Token : : Value , TypePointer const & ) const override { return TypePointer ( ) ; }
virtual bool canBeStored ( ) const override { return false ; }
2015-03-13 09:52:34 +00:00
virtual u256 getStorageSize ( ) const override ;
2015-01-22 00:02:38 +00:00
virtual bool canLiveOutsideStorage ( ) const override { return false ; }
2015-01-28 17:19:01 +00:00
virtual unsigned getSizeOnStack ( ) const override { return 0 ; }
2015-01-22 00:02:38 +00:00
virtual bool operator = = ( Type const & _other ) const override ;
virtual std : : string toString ( ) const override ;
private :
TypePointers m_parameterTypes ;
} ;
2014-11-24 12:23:58 +00:00
/**
* Special type for magic variables ( block , msg , tx ) , similar to a struct but without any reference
* ( it always references a global singleton by name ) .
*/
class MagicType : public Type
{
public :
2015-02-09 13:08:48 +00:00
enum class Kind { Block , Message , Transaction } ;
2015-02-09 13:00:12 +00:00
virtual Category getCategory ( ) const override { return Category : : Magic ; }
2014-11-24 12:23:58 +00:00
2015-01-27 13:32:59 +00:00
explicit MagicType ( Kind _kind ) ;
2015-01-06 17:55:31 +00:00
virtual TypePointer binaryOperatorResult ( Token : : Value , TypePointer const & ) const override
{
return TypePointer ( ) ;
}
2014-11-24 12:23:58 +00:00
virtual bool operator = = ( Type const & _other ) const ;
virtual bool canBeStored ( ) const override { return false ; }
virtual bool canLiveOutsideStorage ( ) const override { return true ; }
2014-11-25 17:23:39 +00:00
virtual unsigned getSizeOnStack ( ) const override { return 0 ; }
2014-11-24 12:23:58 +00:00
virtual MemberList const & getMembers ( ) const override { return m_members ; }
virtual std : : string toString ( ) const override ;
private :
Kind m_kind ;
MemberList m_members ;
} ;
2014-10-16 12:08:54 +00:00
}
}