1 /*
2 This file is part of solidity.
3
4 solidity is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
8
9 solidity is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with solidity. If not, see <http://www.gnu.org/licenses/>.
16 */
17 // SPDX-License-Identifier: GPL-3.0
18 /**
19 * @author Christian <c@ethdev.com>
20 * @date 2014
21 * Solidity data types
22 */
23
24 #pragma once
25
26 #include <libsolidity/ast/ASTEnums.h>
27 #include <libsolidity/ast/ASTForward.h>
28 #include <libsolidity/parsing/Token.h>
29 #include <liblangutil/Exceptions.h>
30
31 #include <libsolutil/Common.h>
32 #include <libsolutil/Numeric.h>
33 #include <libsolutil/CommonIO.h>
34 #include <libsolutil/LazyInit.h>
35 #include <libsolutil/Result.h>
36
37 #include <boost/rational.hpp>
38
39 #include <map>
40 #include <memory>
41 #include <optional>
42 #include <set>
43 #include <string>
44 #include <utility>
45
46 namespace solidity::frontend
47 {
48
49 class TypeProvider;
50 class Type; // forward
51 class FunctionType; // forward
52 using FunctionTypePointer = FunctionType const*;
53 using TypePointers = std::vector<Type const*>;
54 using rational = boost::rational<bigint>;
55 using TypeResult = util::Result<Type const*>;
56 using BoolResult = util::Result<bool>;
57
58 }
59
60 namespace solidity::frontend
61 {
62
makeRational(bigint const & _numerator,bigint const & _denominator)63 inline rational makeRational(bigint const& _numerator, bigint const& _denominator)
64 {
65 solAssert(_denominator != 0, "division by zero");
66 // due to a bug in certain versions of boost the denominator has to be positive
67 if (_denominator < 0)
68 return rational(-_numerator, -_denominator);
69 else
70 return rational(_numerator, _denominator);
71 }
72
73 enum class DataLocation { Storage, CallData, Memory };
74
75
76 /**
77 * Helper class to compute storage offsets of members of structs and contracts.
78 */
79 class StorageOffsets
80 {
81 public:
82 /// Resets the StorageOffsets objects and determines the position in storage for each
83 /// of the elements of @a _types.
84 void computeOffsets(TypePointers const& _types);
85 /// @returns the offset of the given member, might be null if the member is not part of storage.
86 std::pair<u256, unsigned> const* offset(size_t _index) const;
87 /// @returns the total number of slots occupied by all members.
storageSize()88 u256 const& storageSize() const { return m_storageSize; }
89
90 private:
91 u256 m_storageSize;
92 std::map<size_t, std::pair<u256, unsigned>> m_offsets;
93 };
94
95 /**
96 * List of members of a type.
97 */
98 class MemberList
99 {
100 public:
101 struct Member
102 {
103 /// Manual constructor for members that are not taken from a declaration.
MemberMember104 Member(char const* _name, Type const* _type):
105 name(_name),
106 type(_type),
107 declaration(nullptr)
108 {
109 }
110
111 /// Constructs a Member with the name extracted from @p _declaration's name.
112 Member(Declaration const* _declaration, Type const* _type);
113 Member(Declaration const* _declaration, Type const* _type, std::string _name);
114
115 std::string name;
116 Type const* type = nullptr;
117 Declaration const* declaration = nullptr;
118 };
119
120 using MemberMap = std::vector<Member>;
121
MemberList(MemberMap _members)122 explicit MemberList(MemberMap _members): m_memberTypes(std::move(_members)) {}
123
124 void combine(MemberList const& _other);
memberType(std::string const & _name)125 Type const* memberType(std::string const& _name) const
126 {
127 Type const* type = nullptr;
128 for (auto const& it: m_memberTypes)
129 if (it.name == _name)
130 {
131 solAssert(!type, "Requested member type by non-unique name.");
132 type = it.type;
133 }
134 return type;
135 }
membersByName(std::string const & _name)136 MemberMap membersByName(std::string const& _name) const
137 {
138 MemberMap members;
139 for (auto const& it: m_memberTypes)
140 if (it.name == _name)
141 members.push_back(it);
142 return members;
143 }
144 /// @returns the offset of the given member in storage slots and bytes inside a slot or
145 /// a nullptr if the member is not part of storage.
146 std::pair<u256, unsigned> const* memberStorageOffset(std::string const& _name) const;
147 /// @returns the number of storage slots occupied by the members.
148 u256 const& storageSize() const;
149
begin()150 MemberMap::const_iterator begin() const { return m_memberTypes.begin(); }
end()151 MemberMap::const_iterator end() const { return m_memberTypes.end(); }
152
153 private:
154 StorageOffsets const& storageOffsets() const;
155
156 MemberMap m_memberTypes;
157 util::LazyInit<StorageOffsets> m_storageOffsets;
158 };
159
160 static_assert(std::is_nothrow_move_constructible<MemberList>::value, "MemberList should be noexcept move constructible");
161
162 /**
163 * Abstract base class that forms the root of the type hierarchy.
164 */
165 class Type
166 {
167 public:
168 Type() = default;
169 Type(Type const&) = delete;
170 Type(Type&&) = delete;
171 Type& operator=(Type const&) = delete;
172 Type& operator=(Type&&) = delete;
173 virtual ~Type() = default;
174
175 enum class Category
176 {
177 Address, Integer, RationalNumber, StringLiteral, Bool, FixedPoint, Array, ArraySlice,
178 FixedBytes, Contract, Struct, Function, Enum, UserDefinedValueType, Tuple,
179 Mapping, TypeType, Modifier, Magic, Module,
180 InaccessibleDynamic
181 };
182
183 /// @returns a pointer to _a or _b if the other is implicitly convertible to it or nullptr otherwise
184 static Type const* commonType(Type const* _a, Type const* _b);
185
186 virtual Category category() const = 0;
187 /// @returns a valid solidity identifier such that two types should compare equal if and
188 /// only if they have the same identifier.
189 /// The identifier should start with "t_".
190 /// Can contain characters which are invalid in identifiers.
191 virtual std::string richIdentifier() const = 0;
192 /// @returns a valid solidity identifier such that two types should compare equal if and
193 /// only if they have the same identifier.
194 /// The identifier should start with "t_".
195 /// Will not contain any character which would be invalid as an identifier.
196 std::string identifier() const;
197
198 /// More complex identifier strings use "parentheses", where $_ is interpreted as
199 /// "opening parenthesis", _$ as "closing parenthesis", _$_ as "comma" and any $ that
200 /// appears as part of a user-supplied identifier is escaped as _$$$_.
201 /// @returns an escaped identifier (will not contain any parenthesis or commas)
202 static std::string escapeIdentifier(std::string const& _identifier);
203
isImplicitlyConvertibleTo(Type const & _other)204 virtual BoolResult isImplicitlyConvertibleTo(Type const& _other) const { return *this == _other; }
isExplicitlyConvertibleTo(Type const & _convertTo)205 virtual BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const
206 {
207 return isImplicitlyConvertibleTo(_convertTo);
208 }
209 /// @returns the resulting type of applying the given unary operator or an empty pointer if
210 /// this is not possible.
211 /// The default implementation does not allow any unary operator.
unaryOperatorResult(Token)212 virtual TypeResult unaryOperatorResult(Token) const { return nullptr; }
213 /// @returns the resulting type of applying the given binary operator or an empty pointer if
214 /// this is not possible.
215 /// The default implementation allows comparison operators if a common type exists
binaryOperatorResult(Token _operator,Type const * _other)216 virtual TypeResult binaryOperatorResult(Token _operator, Type const* _other) const
217 {
218 return TokenTraits::isCompareOp(_operator) ? commonType(this, _other) : nullptr;
219 }
220
221 virtual bool operator==(Type const& _other) const { return category() == _other.category(); }
222 virtual bool operator!=(Type const& _other) const { return !this->operator ==(_other); }
223
224 /// @returns number of bytes used by this type when encoded for CALL. Cannot be used for
225 /// dynamically encoded types.
226 /// Always returns a value greater than zero and throws if the type cannot be encoded in calldata
227 /// (or is dynamically encoded).
228 /// If @a _padded then it is assumed that each element is padded to a multiple of 32 bytes.
calldataEncodedSize(bool _padded)229 virtual unsigned calldataEncodedSize([[maybe_unused]] bool _padded) const { solAssert(false, ""); }
230 /// Convenience version of @see calldataEncodedSize(bool)
calldataEncodedSize()231 unsigned calldataEncodedSize() const { return calldataEncodedSize(true); }
232 /// @returns the distance between two elements of this type in a calldata array, tuple or struct.
233 /// For statically encoded types this is the same as calldataEncodedSize(true).
234 /// For dynamically encoded types this is the distance between two tail pointers, i.e. 32.
235 /// Always returns a value greater than zero and throws if the type cannot be encoded in calldata.
calldataHeadSize()236 unsigned calldataHeadSize() const { return isDynamicallyEncoded() ? 32 : calldataEncodedSize(true); }
237 /// @returns the (minimal) size of the calldata tail for this type. Can only be used for
238 /// dynamically encoded types. For dynamically-sized arrays this is 32 (the size of the length),
239 /// for statically-sized, but dynamically encoded arrays this is 32*length(), for structs
240 /// this is the sum of the calldataHeadSize's of its members.
241 /// Always returns a value greater than zero and throws if the type cannot be encoded in calldata
242 /// (or is not dynamically encoded).
calldataEncodedTailSize()243 virtual unsigned calldataEncodedTailSize() const { solAssert(false, ""); }
244 /// @returns the size of this data type in bytes when stored in memory. For memory-reference
245 /// types, this is the size of the memory pointer.
memoryHeadSize()246 virtual unsigned memoryHeadSize() const { return calldataEncodedSize(); }
247 /// @returns the size of this data type in bytes when stored in memory. For memory-reference
248 /// types, this is the size of the actual data area, if it is statically-sized.
memoryDataSize()249 virtual u256 memoryDataSize() const { return calldataEncodedSize(); }
250 /// @returns true if the type is a dynamic array
isDynamicallySized()251 virtual bool isDynamicallySized() const { return false; }
252 /// @returns true if the type is dynamically encoded in the ABI
isDynamicallyEncoded()253 virtual bool isDynamicallyEncoded() const { return false; }
254 /// @returns the number of storage slots required to hold this value in storage.
255 /// For dynamically "allocated" types, it returns the size of the statically allocated head,
storageSize()256 virtual u256 storageSize() const { return 1; }
257 /// @returns an upper bound on the total storage size required by this type, descending
258 /// into structs and statically-sized arrays. This is mainly to ensure that the storage
259 /// slot allocation algorithm does not overflow, it is not a protection against collisions.
storageSizeUpperBound()260 virtual bigint storageSizeUpperBound() const { return 1; }
261 /// Multiple small types can be packed into a single storage slot. If such a packing is possible
262 /// this function @returns the size in bytes smaller than 32. Data is moved to the next slot if
263 /// it does not fit.
264 /// In order to avoid computation at runtime of whether such moving is necessary, structs and
265 /// array data (not each element) always start a new slot.
storageBytes()266 virtual unsigned storageBytes() const { return 32; }
267 /// Returns true if the type is a value type that is left-aligned on the stack with a size of
268 /// storageBytes() bytes. Returns false if the type is a value type that is right-aligned on
269 /// the stack with a size of storageBytes() bytes. Asserts if it is not a value type or the
270 /// encoding is more complicated.
271 /// Signed integers are not considered "more complicated" even though they need to be
272 /// sign-extended.
leftAligned()273 virtual bool leftAligned() const { solAssert(false, "Alignment property of non-value type requested."); }
274 /// Returns true if the type can be stored in storage.
canBeStored()275 virtual bool canBeStored() const { return true; }
276 /// Returns false if the type cannot live outside the storage, i.e. if it includes some mapping.
containsNestedMapping()277 virtual bool containsNestedMapping() const
278 {
279 solAssert(nameable(), "Called for a non nameable type.");
280 return false;
281 }
282 /// Returns true if the type can be stored as a value (as opposed to a reference) on the stack,
283 /// i.e. it behaves differently in lvalue context and in value context.
isValueType()284 virtual bool isValueType() const { return false; }
285 /// @returns true if this type can be used for variables. It returns false for
286 /// types like magic types, literals and function types with a kind that is not
287 /// internal or external.
nameable()288 virtual bool nameable() const { return false; }
289 /// @returns a list of named and typed stack items that determine the layout of this type on the stack.
290 /// A stack item either has an empty name and type ``nullptr`` referring to a single stack slot, or
291 /// has a non-empty name and a valid type referring to the stack layout of that type.
292 /// The complete layout of a type on the stack can be obtained from its stack items recursively as follows:
293 /// - Each unnamed stack item is untyped (its type is ``nullptr``) and contributes exactly one stack slot.
294 /// - Each named stack item is typed and contributes the stack slots given by the stack items of its type.
stackItems()295 std::vector<std::tuple<std::string, Type const*>> const& stackItems() const
296 {
297 if (!m_stackItems)
298 m_stackItems = makeStackItems();
299 return *m_stackItems;
300 }
301 /// Total number of stack slots occupied by this type. This is the sum of ``sizeOnStack`` of all ``stackItems()``.
302 // TODO: consider changing the return type to be size_t
sizeOnStack()303 unsigned sizeOnStack() const
304 {
305 if (!m_stackSize)
306 {
307 size_t sizeOnStack = 0;
308 for (auto const& slot: stackItems())
309 if (std::get<1>(slot))
310 sizeOnStack += std::get<1>(slot)->sizeOnStack();
311 else
312 ++sizeOnStack;
313 m_stackSize = sizeOnStack;
314 }
315 return static_cast<unsigned>(*m_stackSize);
316 }
317 /// If it is possible to initialize such a value in memory by just writing zeros
318 /// of the size memoryHeadSize().
hasSimpleZeroValueInMemory()319 virtual bool hasSimpleZeroValueInMemory() const { return true; }
320 /// @returns the mobile (in contrast to static) type corresponding to the given type.
321 /// This returns the corresponding IntegerType or FixedPointType for RationalNumberType
322 /// and the pointer type for storage reference types.
323 /// Might return a null pointer if there is no fitting type.
mobileType()324 virtual Type const* mobileType() const { return this; }
325 /// @returns true if this is a non-value type and the data of this type is stored at the
326 /// given location.
dataStoredIn(DataLocation)327 virtual bool dataStoredIn(DataLocation) const { return false; }
328
329 /// Returns the list of all members of this type. Default implementation: no members apart from bound.
330 /// @param _currentScope scope in which the members are accessed.
331 MemberList const& members(ASTNode const* _currentScope) const;
332 /// Convenience method, returns the type of the given named member or an empty pointer if no such member exists.
333 Type const* memberType(std::string const& _name, ASTNode const* _currentScope = nullptr) const
334 {
335 return members(_currentScope).memberType(_name);
336 }
337
338 virtual std::string toString(bool _short) const = 0;
toString()339 std::string toString() const { return toString(false); }
340 /// @returns the canonical name of this type for use in library function signatures.
canonicalName()341 virtual std::string canonicalName() const { return toString(true); }
342 /// @returns the signature of this type in external functions, i.e. `uint256` for integers
343 /// or `(uint256,bytes8)[2]` for an array of structs. If @a _structsByName,
344 /// structs are given by canonical name like `ContractName.StructName[2]`.
signatureInExternalFunction(bool)345 virtual std::string signatureInExternalFunction(bool /*_structsByName*/) const
346 {
347 return canonicalName();
348 }
literalValue(Literal const *)349 virtual u256 literalValue(Literal const*) const
350 {
351 solAssert(false, "Literal value requested for type without literals: " + toString(false));
352 }
353
354 /// @returns a (simpler) type that is encoded in the same way for external function calls.
355 /// This for example returns address for contract types.
356 /// If there is no such type, returns an empty shared pointer.
encodingType()357 virtual Type const* encodingType() const { return nullptr; }
358 /// @returns the encoding type used under the given circumstances for the type of an expression
359 /// when used for e.g. abi.encode(...) or the empty pointer if the object
360 /// cannot be encoded.
361 /// This is different from encodingType since it takes implicit conversions into account.
362 Type const* fullEncodingType(bool _inLibraryCall, bool _encoderV2, bool _packed) const;
363 /// @returns a (simpler) type that is used when decoding this type in calldata.
decodingType()364 virtual Type const* decodingType() const { return encodingType(); }
365 /// @returns a type that will be used outside of Solidity for e.g. function signatures.
366 /// This for example returns address for contract types.
367 /// If there is no such type, returns an empty shared pointer.
368 /// @param _inLibrary if set, returns types as used in a library, e.g. struct and contract types
369 /// are returned without modification.
interfaceType(bool)370 virtual TypeResult interfaceType(bool /*_inLibrary*/) const { return nullptr; }
371
372 /// Clears all internally cached values (if any).
373 virtual void clearCache() const;
374
375 private:
376 /// @returns a member list containing all members added to this type by `using for` directives.
377 static MemberList::MemberMap boundFunctions(Type const& _type, ASTNode const& _scope);
378
379 protected:
380 /// @returns the members native to this type depending on the given context. This function
381 /// is used (in conjunction with boundFunctions to fill m_members below.
nativeMembers(ASTNode const *)382 virtual MemberList::MemberMap nativeMembers(ASTNode const* /*_currentScope*/) const
383 {
384 return MemberList::MemberMap();
385 }
386 /// Generates the stack items to be returned by ``stackItems()``. Defaults
387 /// to exactly one unnamed and untyped stack item referring to a single stack slot.
makeStackItems()388 virtual std::vector<std::tuple<std::string, Type const*>> makeStackItems() const
389 {
390 return {std::make_tuple(std::string(), nullptr)};
391 }
392
393
394 /// List of member types (parameterised by scape), will be lazy-initialized.
395 mutable std::map<ASTNode const*, std::unique_ptr<MemberList>> m_members;
396 mutable std::optional<std::vector<std::tuple<std::string, Type const*>>> m_stackItems;
397 mutable std::optional<size_t> m_stackSize;
398 };
399
400 /**
401 * Type for addresses.
402 */
403 class AddressType: public Type
404 {
405 public:
406 explicit AddressType(StateMutability _stateMutability);
407
category()408 Category category() const override { return Category::Address; }
409
410 std::string richIdentifier() const override;
411 BoolResult isImplicitlyConvertibleTo(Type const& _other) const override;
412 BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
413 TypeResult unaryOperatorResult(Token _operator) const override;
414 TypeResult binaryOperatorResult(Token _operator, Type const* _other) const override;
415
416 bool operator==(Type const& _other) const override;
417
418 unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : 160 / 8; }
storageBytes()419 unsigned storageBytes() const override { return 160 / 8; }
leftAligned()420 bool leftAligned() const override { return false; }
isValueType()421 bool isValueType() const override { return true; }
nameable()422 bool nameable() const override { return true; }
423
424 MemberList::MemberMap nativeMembers(ASTNode const*) const override;
425
426 std::string toString(bool _short) const override;
427 std::string canonicalName() const override;
428
429 u256 literalValue(Literal const* _literal) const override;
430
encodingType()431 Type const* encodingType() const override { return this; }
interfaceType(bool)432 TypeResult interfaceType(bool) const override { return this; }
433
stateMutability(void)434 StateMutability stateMutability(void) const { return m_stateMutability; }
435
436 private:
437 StateMutability m_stateMutability;
438 };
439
440 /**
441 * Any kind of integer type (signed, unsigned).
442 */
443 class IntegerType: public Type
444 {
445 public:
446 enum class Modifier
447 {
448 Unsigned, Signed
449 };
450
451 explicit IntegerType(unsigned _bits, Modifier _modifier = Modifier::Unsigned);
452
category()453 Category category() const override { return Category::Integer; }
454
455 std::string richIdentifier() const override;
456 BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
457 BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
458 TypeResult unaryOperatorResult(Token _operator) const override;
459 TypeResult binaryOperatorResult(Token _operator, Type const* _other) const override;
460
461 bool operator==(Type const& _other) const override;
462
463 unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : m_bits / 8; }
storageBytes()464 unsigned storageBytes() const override { return m_bits / 8; }
leftAligned()465 bool leftAligned() const override { return false; }
isValueType()466 bool isValueType() const override { return true; }
nameable()467 bool nameable() const override { return true; }
468
469 std::string toString(bool _short) const override;
470
encodingType()471 Type const* encodingType() const override { return this; }
interfaceType(bool)472 TypeResult interfaceType(bool) const override { return this; }
473
numBits()474 unsigned numBits() const { return m_bits; }
isSigned()475 bool isSigned() const { return m_modifier == Modifier::Signed; }
476
477 u256 min() const;
478 u256 max() const;
479
480 bigint minValue() const;
481 bigint maxValue() const;
482
483 private:
484 unsigned const m_bits;
485 Modifier const m_modifier;
486 };
487
488 /**
489 * A fixed point type number (signed, unsigned).
490 */
491 class FixedPointType: public Type
492 {
493 public:
494 enum class Modifier
495 {
496 Unsigned, Signed
497 };
498
499 explicit FixedPointType(unsigned _totalBits, unsigned _fractionalDigits, Modifier _modifier = Modifier::Unsigned);
category()500 Category category() const override { return Category::FixedPoint; }
501
502 std::string richIdentifier() const override;
503 BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
504 BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
505 TypeResult unaryOperatorResult(Token _operator) const override;
506 TypeResult binaryOperatorResult(Token _operator, Type const* _other) const override;
507
508 bool operator==(Type const& _other) const override;
509
510 unsigned calldataEncodedSize(bool _padded = true) const override { return _padded ? 32 : m_totalBits / 8; }
storageBytes()511 unsigned storageBytes() const override { return m_totalBits / 8; }
leftAligned()512 bool leftAligned() const override { return false; }
isValueType()513 bool isValueType() const override { return true; }
nameable()514 bool nameable() const override { return true; }
515
516 std::string toString(bool _short) const override;
517
encodingType()518 Type const* encodingType() const override { return this; }
interfaceType(bool)519 TypeResult interfaceType(bool) const override { return this; }
520
521 /// Number of bits used for this type in total.
numBits()522 unsigned numBits() const { return m_totalBits; }
523 /// Number of decimal digits after the radix point.
fractionalDigits()524 unsigned fractionalDigits() const { return m_fractionalDigits; }
isSigned()525 bool isSigned() const { return m_modifier == Modifier::Signed; }
526 /// @returns the largest integer value this type con hold. Note that this is not the
527 /// largest value in general.
528 bigint maxIntegerValue() const;
529 /// @returns the smallest integer value this type can hold. Note hat this is not the
530 /// smallest value in general.
531 bigint minIntegerValue() const;
532
533 /// @returns the smallest integer type that can hold this type with fractional parts shifted to integers.
534 IntegerType const* asIntegerType() const;
535
536 private:
537 unsigned m_totalBits;
538 unsigned m_fractionalDigits;
539 Modifier m_modifier;
540 };
541
542 /**
543 * Integer and fixed point constants either literals or computed.
544 * Example expressions: 2, 3.14, 2+10.2, ~10.
545 * There is one distinct type per value.
546 */
547 class RationalNumberType: public Type
548 {
549 public:
550 explicit RationalNumberType(rational _value, Type const* _compatibleBytesType = nullptr):
m_value(std::move (_value))551 m_value(std::move(_value)), m_compatibleBytesType(_compatibleBytesType)
552 {}
553
category()554 Category category() const override { return Category::RationalNumber; }
555
556 BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
557 BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
558 TypeResult unaryOperatorResult(Token _operator) const override;
559 TypeResult binaryOperatorResult(Token _operator, Type const* _other) const override;
560
561 std::string richIdentifier() const override;
562 bool operator==(Type const& _other) const override;
563
canBeStored()564 bool canBeStored() const override { return false; }
565
566 std::string toString(bool _short) const override;
567 u256 literalValue(Literal const* _literal) const override;
568 Type const* mobileType() const override;
569
570 /// @returns the underlying raw literal value.
571 ///
572 /// @see literalValue(Literal const*))
value()573 rational const& value() const noexcept { return m_value; }
574
575 /// @returns the smallest integer type that can hold the value or an empty pointer if not possible.
576 IntegerType const* integerType() const;
577 /// @returns the smallest fixed type that can hold the value or incurs the least precision loss,
578 /// unless the value was truncated, then a suitable type will be chosen to indicate such event.
579 /// If the integer part does not fit, returns an empty pointer.
580 FixedPointType const* fixedPointType() const;
581
582 /// @returns true if the value is not an integer.
isFractional()583 bool isFractional() const { return m_value.denominator() != 1; }
584
585 /// @returns true if the value is negative.
isNegative()586 bool isNegative() const { return m_value < 0; }
587
588 /// @returns true if the value is zero.
isZero()589 bool isZero() const { return m_value == 0; }
590
591 /// @returns true if the literal is a valid integer.
592 static std::tuple<bool, rational> isValidLiteral(Literal const& _literal);
593
594 private:
595 rational m_value;
596
597 /// Bytes type to which the rational can be implicitly converted.
598 /// Empty for all rationals that are not directly parsed from hex literals.
599 Type const* m_compatibleBytesType;
600
601 /// @returns true if the literal is a valid rational number.
602 static std::tuple<bool, rational> parseRational(std::string const& _value);
603
604 /// @returns a truncated readable representation of the bigint keeping only
605 /// up to 4 leading and 4 trailing digits.
606 static std::string bigintToReadableString(bigint const& num);
607 };
608
609 /**
610 * Literal string, can be converted to bytes, bytesX or string.
611 */
612 class StringLiteralType: public Type
613 {
614 public:
615 explicit StringLiteralType(Literal const& _literal);
616 explicit StringLiteralType(std::string _value);
617
category()618 Category category() const override { return Category::StringLiteral; }
619
620 BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
binaryOperatorResult(Token,Type const *)621 TypeResult binaryOperatorResult(Token, Type const*) const override
622 {
623 return nullptr;
624 }
625
626 std::string richIdentifier() const override;
627 bool operator==(Type const& _other) const override;
628
canBeStored()629 bool canBeStored() const override { return false; }
630
631 std::string toString(bool) const override;
632 Type const* mobileType() const override;
633
value()634 std::string const& value() const { return m_value; }
635
636 protected:
makeStackItems()637 std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override { return {}; }
638 private:
639 std::string m_value;
640 };
641
642 /**
643 * Bytes type with fixed length of up to 32 bytes.
644 */
645 class FixedBytesType: public Type
646 {
647 public:
648 explicit FixedBytesType(unsigned _bytes);
649
category()650 Category category() const override { return Category::FixedBytes; }
651
652 BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
653 BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
654 std::string richIdentifier() const override;
655 bool operator==(Type const& _other) const override;
656 TypeResult unaryOperatorResult(Token _operator) const override;
657 TypeResult binaryOperatorResult(Token _operator, Type const* _other) const override;
658
calldataEncodedSize(bool _padded)659 unsigned calldataEncodedSize(bool _padded) const override { return _padded && m_bytes > 0 ? 32 : m_bytes; }
storageBytes()660 unsigned storageBytes() const override { return m_bytes; }
leftAligned()661 bool leftAligned() const override { return true; }
isValueType()662 bool isValueType() const override { return true; }
nameable()663 bool nameable() const override { return true; }
664
toString(bool)665 std::string toString(bool) const override { return "bytes" + util::toString(m_bytes); }
666 MemberList::MemberMap nativeMembers(ASTNode const*) const override;
encodingType()667 Type const* encodingType() const override { return this; }
interfaceType(bool)668 TypeResult interfaceType(bool) const override { return this; }
669
numBytes()670 unsigned numBytes() const { return m_bytes; }
671
672 private:
673 unsigned m_bytes;
674 };
675
676 /**
677 * The boolean type.
678 */
679 class BoolType: public Type
680 {
681 public:
category()682 Category category() const override { return Category::Bool; }
richIdentifier()683 std::string richIdentifier() const override { return "t_bool"; }
684 TypeResult unaryOperatorResult(Token _operator) const override;
685 TypeResult binaryOperatorResult(Token _operator, Type const* _other) const override;
686
calldataEncodedSize(bool _padded)687 unsigned calldataEncodedSize(bool _padded) const override{ return _padded ? 32 : 1; }
storageBytes()688 unsigned storageBytes() const override { return 1; }
leftAligned()689 bool leftAligned() const override { return false; }
isValueType()690 bool isValueType() const override { return true; }
nameable()691 bool nameable() const override { return true; }
692
toString(bool)693 std::string toString(bool) const override { return "bool"; }
694 u256 literalValue(Literal const* _literal) const override;
encodingType()695 Type const* encodingType() const override { return this; }
interfaceType(bool)696 TypeResult interfaceType(bool) const override { return this; }
697 };
698
699 /**
700 * Base class for types which can be thought of as several elements of other types put together.
701 * For example a struct is composed of its members, an array is composed of multiple copies of its
702 * base element and a mapping is composed of its value type elements (note that keys are not
703 * stored anywhere).
704 */
705 class CompositeType: public Type
706 {
707 protected:
708 CompositeType() = default;
709
710 public:
711 /// @returns a list containing the type itself, elements of its decomposition,
712 /// elements of decomposition of these elements and so on, up to non-composite types.
713 /// Each type is included only once.
714 std::vector<Type const*> fullDecomposition() const;
715
716 protected:
717 /// @returns a list of types that together make up the data part of this type.
718 /// Contains all types that will have to be implicitly stored, whenever an object of this type is stored.
719 /// In particular, it returns the base type for arrays and array slices, the member types for structs,
720 /// the component types for tuples and the value type for mappings
721 /// (note that the key type of a mapping is *not* part of the list).
722 virtual std::vector<Type const*> decomposition() const = 0;
723 };
724
725 /**
726 * Base class used by types which are not value types and can be stored either in storage, memory
727 * or calldata. This is currently used by arrays and structs.
728 */
729 class ReferenceType: public CompositeType
730 {
731 protected:
ReferenceType(DataLocation _location)732 explicit ReferenceType(DataLocation _location): m_location(_location) {}
733
734 public:
location()735 DataLocation location() const { return m_location; }
736
737 TypeResult unaryOperatorResult(Token _operator) const override;
binaryOperatorResult(Token,Type const *)738 TypeResult binaryOperatorResult(Token, Type const*) const override
739 {
740 return nullptr;
741 }
memoryHeadSize()742 unsigned memoryHeadSize() const override { return 32; }
743 u256 memoryDataSize() const override = 0;
744
745 unsigned calldataEncodedSize(bool) const override = 0;
746 unsigned calldataEncodedTailSize() const override = 0;
747
748 /// @returns a copy of this type with location (recursively) changed to @a _location,
749 /// whereas isPointer is only shallowly changed - the deep copy is always a bound reference.
750 virtual std::unique_ptr<ReferenceType> copyForLocation(DataLocation _location, bool _isPointer) const = 0;
751
mobileType()752 Type const* mobileType() const override { return withLocation(m_location, true); }
dataStoredIn(DataLocation _location)753 bool dataStoredIn(DataLocation _location) const override { return m_location == _location; }
hasSimpleZeroValueInMemory()754 bool hasSimpleZeroValueInMemory() const override { return false; }
755
756 /// Storage references can be pointers or bound references. In general, local variables are of
757 /// pointer type, state variables are bound references. Assignments to pointers or deleting
758 /// them will not modify storage (that will only change the pointer). Assignment from
759 /// non-storage objects to a variable of storage pointer type is not possible.
760 /// For anything other than storage, this always returns true because assignments
761 /// never change the contents of the original value.
762 bool isPointer() const;
763
764 /// @returns true if this is valid to be stored in data location _loc
765 /// The function mostly checks sizes. For calldata, this should only be called
766 /// if the type has an interfaceType.
767 virtual BoolResult validForLocation(DataLocation _loc) const = 0;
768
769 bool operator==(ReferenceType const& _other) const
770 {
771 return location() == _other.location() && isPointer() == _other.isPointer();
772 }
773
774 Type const* withLocation(DataLocation _location, bool _isPointer) const;
775
776 protected:
777 Type const* copyForLocationIfReference(Type const* _type) const;
778 /// @returns a human-readable description of the reference part of the type.
779 std::string stringForReferencePart() const;
780 /// @returns the suffix computed from the reference part to be used by identifier();
781 std::string identifierLocationSuffix() const;
782
783 DataLocation m_location = DataLocation::Storage;
784 bool m_isPointer = true;
785 };
786
787 /**
788 * The type of an array. The flavours are byte array (bytes), statically- (<type>[<length>])
789 * and dynamically-sized array (<type>[]).
790 * In storage, all arrays are packed tightly (as long as more than one elementary type fits in
791 * one slot). Dynamically sized arrays (including byte arrays) start with their size as a uint and
792 * thus start on their own slot.
793 */
794 class ArrayType: public ReferenceType
795 {
796 public:
797 /// Constructor for a byte array ("bytes") and string.
798 explicit ArrayType(DataLocation _location, bool _isString = false);
799
800 /// Constructor for a dynamically sized array type ("type[]")
ArrayType(DataLocation _location,Type const * _baseType)801 ArrayType(DataLocation _location, Type const* _baseType):
802 ReferenceType(_location),
803 m_baseType(copyForLocationIfReference(_baseType))
804 {
805 }
806
807 /// Constructor for a fixed-size array type ("type[20]")
ArrayType(DataLocation _location,Type const * _baseType,u256 _length)808 ArrayType(DataLocation _location, Type const* _baseType, u256 _length):
809 ReferenceType(_location),
810 m_baseType(copyForLocationIfReference(_baseType)),
811 m_hasDynamicLength(false),
812 m_length(std::move(_length))
813 {}
814
category()815 Category category() const override { return Category::Array; }
816
817 BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
818 BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
819 std::string richIdentifier() const override;
820 bool operator==(Type const& _other) const override;
821 unsigned calldataEncodedSize(bool) const override;
822 unsigned calldataEncodedTailSize() const override;
isDynamicallySized()823 bool isDynamicallySized() const override { return m_hasDynamicLength; }
824 bool isDynamicallyEncoded() const override;
825 bigint storageSizeUpperBound() const override;
826 u256 storageSize() const override;
containsNestedMapping()827 bool containsNestedMapping() const override { return m_baseType->containsNestedMapping(); }
nameable()828 bool nameable() const override { return true; }
829
830 std::string toString(bool _short) const override;
831 std::string canonicalName() const override;
832 std::string signatureInExternalFunction(bool _structsByName) const override;
833 MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
834 Type const* encodingType() const override;
835 Type const* decodingType() const override;
836 TypeResult interfaceType(bool _inLibrary) const override;
837
838 BoolResult validForLocation(DataLocation _loc) const override;
839
840 /// @returns true if this is a byte array or a string
isByteArray()841 bool isByteArray() const { return m_arrayKind != ArrayKind::Ordinary; }
842 /// @returns true if this is a string
isString()843 bool isString() const { return m_arrayKind == ArrayKind::String; }
baseType()844 Type const* baseType() const { solAssert(!!m_baseType, ""); return m_baseType; }
845 Type const* finalBaseType(bool breakIfDynamicArrayType) const;
length()846 u256 const& length() const { return m_length; }
847 u256 memoryDataSize() const override;
848
849 std::unique_ptr<ReferenceType> copyForLocation(DataLocation _location, bool _isPointer) const override;
850
851 /// The offset to advance in calldata to move from one array element to the next.
calldataStride()852 unsigned calldataStride() const { return isByteArray() ? 1 : m_baseType->calldataHeadSize(); }
853 /// The offset to advance in memory to move from one array element to the next.
memoryStride()854 unsigned memoryStride() const { return isByteArray() ? 1 : m_baseType->memoryHeadSize(); }
855 /// The offset to advance in storage to move from one array element to the next.
storageStride()856 unsigned storageStride() const { return isByteArray() ? 1 : m_baseType->storageBytes(); }
857
858 void clearCache() const override;
859
860 protected:
861 std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;
decomposition()862 std::vector<Type const*> decomposition() const override { return {m_baseType}; }
863
864 private:
865 /// String is interpreted as a subtype of Bytes.
866 enum class ArrayKind { Ordinary, Bytes, String };
867
868 bigint unlimitedStaticCalldataSize(bool _padded) const;
869
870 ///< Byte arrays ("bytes") and strings have different semantics from ordinary arrays.
871 ArrayKind m_arrayKind = ArrayKind::Ordinary;
872 Type const* m_baseType;
873 bool m_hasDynamicLength = true;
874 u256 m_length;
875 mutable std::optional<TypeResult> m_interfaceType;
876 mutable std::optional<TypeResult> m_interfaceType_library;
877 };
878
879 class ArraySliceType: public ReferenceType
880 {
881 public:
ArraySliceType(ArrayType const & _arrayType)882 explicit ArraySliceType(ArrayType const& _arrayType): ReferenceType(_arrayType.location()), m_arrayType(_arrayType) {}
category()883 Category category() const override { return Category::ArraySlice; }
884
885 BoolResult isImplicitlyConvertibleTo(Type const& _other) const override;
886 BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
887 std::string richIdentifier() const override;
888 bool operator==(Type const& _other) const override;
calldataEncodedSize(bool)889 unsigned calldataEncodedSize(bool) const override { solAssert(false, ""); }
calldataEncodedTailSize()890 unsigned calldataEncodedTailSize() const override { return 32; }
isDynamicallySized()891 bool isDynamicallySized() const override { return true; }
isDynamicallyEncoded()892 bool isDynamicallyEncoded() const override { return true; }
893 std::string toString(bool _short) const override;
894 Type const* mobileType() const override;
895
validForLocation(DataLocation _loc)896 BoolResult validForLocation(DataLocation _loc) const override { return m_arrayType.validForLocation(_loc); }
897
arrayType()898 ArrayType const& arrayType() const { return m_arrayType; }
memoryDataSize()899 u256 memoryDataSize() const override { solAssert(false, ""); }
900
copyForLocation(DataLocation,bool)901 std::unique_ptr<ReferenceType> copyForLocation(DataLocation, bool) const override { solAssert(false, ""); }
902
903 protected:
904 std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;
decomposition()905 std::vector<Type const*> decomposition() const override { return {m_arrayType.baseType()}; }
906
907 private:
908 ArrayType const& m_arrayType;
909 };
910
911 /**
912 * The type of a contract instance or library, there is one distinct type for each contract definition.
913 */
914 class ContractType: public Type
915 {
916 public:
917 explicit ContractType(ContractDefinition const& _contract, bool _super = false):
m_contract(_contract)918 m_contract(_contract), m_super(_super) {}
919
category()920 Category category() const override { return Category::Contract; }
921 /// Contracts can be implicitly converted only to base contracts.
922 BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
923 /// Contracts can only be explicitly converted to address types and base contracts.
924 BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
925 TypeResult unaryOperatorResult(Token _operator) const override;
926 std::string richIdentifier() const override;
927 bool operator==(Type const& _other) const override;
calldataEncodedSize(bool _padded)928 unsigned calldataEncodedSize(bool _padded ) const override
929 {
930 solAssert(!isSuper(), "");
931 return encodingType()->calldataEncodedSize(_padded);
932 }
storageBytes()933 unsigned storageBytes() const override { solAssert(!isSuper(), ""); return 20; }
leftAligned()934 bool leftAligned() const override { solAssert(!isSuper(), ""); return false; }
isValueType()935 bool isValueType() const override { return !isSuper(); }
nameable()936 bool nameable() const override { return !isSuper(); }
937 std::string toString(bool _short) const override;
938 std::string canonicalName() const override;
939
940 MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
941
942 Type const* encodingType() const override;
943
interfaceType(bool _inLibrary)944 TypeResult interfaceType(bool _inLibrary) const override
945 {
946 if (isSuper())
947 return nullptr;
948 return _inLibrary ? this : encodingType();
949 }
950
951 /// See documentation of m_super
isSuper()952 bool isSuper() const { return m_super; }
953
954 // @returns true if and only if the contract has a receive ether function or a payable fallback function, i.e.
955 // if it has code that will be executed on plain ether transfers
956 bool isPayable() const;
957
contractDefinition()958 ContractDefinition const& contractDefinition() const { return m_contract; }
959
960 /// Returns the function type of the constructor modified to return an object of the contract's type.
961 FunctionType const* newExpressionType() const;
962
963 /// @returns a list of all state variables (including inherited) of the contract and their
964 /// offsets in storage.
965 std::vector<std::tuple<VariableDeclaration const*, u256, unsigned>> stateVariables() const;
966 /// @returns a list of all immutable variables (including inherited) of the contract.
967 std::vector<VariableDeclaration const*> immutableVariables() const;
968 protected:
969 std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;
970 private:
971 ContractDefinition const& m_contract;
972 /// If true, this is a special "super" type of m_contract containing only members that m_contract inherited
973 bool m_super = false;
974 /// Type of the constructor, @see constructorType. Lazily initialized.
975 mutable FunctionType const* m_constructorType = nullptr;
976 };
977
978 /**
979 * The type of a struct instance, there is one distinct type per struct definition.
980 */
981 class StructType: public ReferenceType
982 {
983 public:
984 explicit StructType(StructDefinition const& _struct, DataLocation _location = DataLocation::Storage):
ReferenceType(_location)985 ReferenceType(_location), m_struct(_struct) {}
986
category()987 Category category() const override { return Category::Struct; }
988 BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
989 std::string richIdentifier() const override;
990 bool operator==(Type const& _other) const override;
991 unsigned calldataEncodedSize(bool) const override;
992 unsigned calldataEncodedTailSize() const override;
993 bool isDynamicallyEncoded() const override;
994 u256 memoryDataSize() const override;
995 bigint storageSizeUpperBound() const override;
996 u256 storageSize() const override;
997 bool containsNestedMapping() const override;
nameable()998 bool nameable() const override { return true; }
999 std::string toString(bool _short) const override;
1000
1001 MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
1002
1003 Type const* encodingType() const override;
1004 TypeResult interfaceType(bool _inLibrary) const override;
1005
1006 BoolResult validForLocation(DataLocation _loc) const override;
1007
1008 bool recursive() const;
1009
1010 std::unique_ptr<ReferenceType> copyForLocation(DataLocation _location, bool _isPointer) const override;
1011
1012 std::string canonicalName() const override;
1013 std::string signatureInExternalFunction(bool _structsByName) const override;
1014
1015 /// @returns a function that performs the type conversion between a list of struct members
1016 /// and a memory struct of this type.
1017 FunctionType const* constructorType() const;
1018
1019 std::pair<u256, unsigned> const& storageOffsetsOfMember(std::string const& _name) const;
1020 u256 memoryOffsetOfMember(std::string const& _name) const;
1021 unsigned calldataOffsetOfMember(std::string const& _name) const;
1022
structDefinition()1023 StructDefinition const& structDefinition() const { return m_struct; }
1024
1025 /// @returns the vector of types of members available in memory.
1026 TypePointers memoryMemberTypes() const;
1027
1028 void clearCache() const override;
1029
1030 protected:
1031 std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;
1032 std::vector<Type const*> decomposition() const override;
1033
1034 private:
1035 StructDefinition const& m_struct;
1036 // Caches for interfaceType(bool)
1037 mutable std::optional<TypeResult> m_interfaceType;
1038 mutable std::optional<TypeResult> m_interfaceType_library;
1039 };
1040
1041 /**
1042 * The type of an enum instance, there is one distinct type per enum definition.
1043 */
1044 class EnumType: public Type
1045 {
1046 public:
EnumType(EnumDefinition const & _enum)1047 explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}
1048
category()1049 Category category() const override { return Category::Enum; }
1050 TypeResult unaryOperatorResult(Token _operator) const override;
1051 std::string richIdentifier() const override;
1052 bool operator==(Type const& _other) const override;
calldataEncodedSize(bool _padded)1053 unsigned calldataEncodedSize(bool _padded) const override
1054 {
1055 return encodingType()->calldataEncodedSize(_padded);
1056 }
1057 unsigned storageBytes() const override;
leftAligned()1058 bool leftAligned() const override { return false; }
1059 std::string toString(bool _short) const override;
1060 std::string canonicalName() const override;
isValueType()1061 bool isValueType() const override { return true; }
nameable()1062 bool nameable() const override { return true; }
1063
1064 BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
1065 Type const* encodingType() const override;
interfaceType(bool _inLibrary)1066 TypeResult interfaceType(bool _inLibrary) const override
1067 {
1068 return _inLibrary ? this : encodingType();
1069 }
1070
enumDefinition()1071 EnumDefinition const& enumDefinition() const { return m_enum; }
1072 /// @returns the value that the string has in the Enum
1073 unsigned int memberValue(ASTString const& _member) const;
1074 size_t numberOfMembers() const;
minValue()1075 unsigned int minValue() const { return 0; }
maxValue()1076 unsigned int maxValue() const
1077 {
1078 solAssert(numberOfMembers() <= 256, "");
1079 return static_cast<unsigned int>(numberOfMembers()) - 1;
1080 }
1081
1082 private:
1083 EnumDefinition const& m_enum;
1084 };
1085
1086 /**
1087 * The type of a UserDefinedValueType.
1088 */
1089 class UserDefinedValueType: public Type
1090 {
1091 public:
UserDefinedValueType(UserDefinedValueTypeDefinition const & _definition)1092 explicit UserDefinedValueType(UserDefinedValueTypeDefinition const& _definition):
1093 m_definition(_definition)
1094 {}
1095
category()1096 Category category() const override { return Category::UserDefinedValueType; }
1097 Type const& underlyingType() const;
definition()1098 UserDefinedValueTypeDefinition const& definition() const { return m_definition; }
1099
binaryOperatorResult(Token,Type const *)1100 TypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }
encodingType()1101 Type const* encodingType() const override { return &underlyingType(); }
interfaceType(bool)1102 TypeResult interfaceType(bool /* _inLibrary */) const override {return &underlyingType(); }
1103 std::string richIdentifier() const override;
1104 bool operator==(Type const& _other) const override;
1105
calldataEncodedSize(bool _padded)1106 unsigned calldataEncodedSize(bool _padded) const override { return underlyingType().calldataEncodedSize(_padded); }
1107
leftAligned()1108 bool leftAligned() const override { return underlyingType().leftAligned(); }
canBeStored()1109 bool canBeStored() const override { return underlyingType().canBeStored(); }
storageSize()1110 u256 storageSize() const override { return underlyingType().storageSize(); }
storageBytes()1111 unsigned storageBytes() const override { return underlyingType().storageBytes(); }
1112
isValueType()1113 bool isValueType() const override
1114 {
1115 solAssert(underlyingType().isValueType(), "");
1116 return true;
1117 }
nameable()1118 bool nameable() const override
1119 {
1120 solAssert(underlyingType().nameable(), "");
1121 return true;
1122 }
1123
containsNestedMapping()1124 bool containsNestedMapping() const override
1125 {
1126 solAssert(nameable(), "Called for a non nameable type.");
1127 // DeclarationTypeChecker::endVisit(VariableDeclaration const&)
1128 // assumes that this will never be true.
1129 solAssert(!underlyingType().containsNestedMapping(), "");
1130 return false;
1131 }
1132
hasSimpleZeroValueInMemory()1133 bool hasSimpleZeroValueInMemory() const override
1134 {
1135 solAssert(underlyingType().hasSimpleZeroValueInMemory(), "");
1136 return true;
1137 }
1138
dataStoredIn(DataLocation _loc)1139 bool dataStoredIn(DataLocation _loc) const override
1140 {
1141 solAssert(!underlyingType().dataStoredIn(_loc), "");
1142 return false;
1143 }
1144
1145 std::string toString(bool _short) const override;
1146 std::string canonicalName() const override;
signatureInExternalFunction(bool)1147 std::string signatureInExternalFunction(bool) const override { solAssert(false, ""); }
1148
1149 protected:
1150 std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;
1151
1152 private:
1153 UserDefinedValueTypeDefinition const& m_definition;
1154 };
1155
1156 /**
1157 * Type that can hold a finite sequence of values of different types.
1158 * In some cases, the components are empty pointers (when used as placeholders).
1159 */
1160 class TupleType: public CompositeType
1161 {
1162 public:
m_components(std::move (_types))1163 explicit TupleType(std::vector<Type const*> _types = {}): m_components(std::move(_types)) {}
1164
category()1165 Category category() const override { return Category::Tuple; }
1166
1167 BoolResult isImplicitlyConvertibleTo(Type const& _other) const override;
1168 std::string richIdentifier() const override;
1169 bool operator==(Type const& _other) const override;
binaryOperatorResult(Token,Type const *)1170 TypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }
1171 std::string toString(bool) const override;
canBeStored()1172 bool canBeStored() const override { return false; }
1173 u256 storageSize() const override;
hasSimpleZeroValueInMemory()1174 bool hasSimpleZeroValueInMemory() const override { return false; }
1175 Type const* mobileType() const override;
1176
components()1177 std::vector<Type const*> const& components() const { return m_components; }
1178
1179 protected:
1180 std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;
decomposition()1181 std::vector<Type const*> decomposition() const override
1182 {
1183 // Currently calling TupleType::decomposition() is not expected, because we cannot declare a variable of a tuple type.
1184 // If that changes, before removing the solAssert, make sure the function does the right thing and is used properly.
1185 // Note that different tuple members can have different data locations, so using decomposition() to check
1186 // the tuple validity for a data location might require special care.
1187 solUnimplemented("Tuple decomposition is not expected.");
1188 return m_components;
1189 }
1190
1191 private:
1192 std::vector<Type const*> const m_components;
1193 };
1194
1195 /**
1196 * The type of a function, identified by its (return) parameter types.
1197 * @todo the return parameters should also have names, i.e. return parameters should be a struct
1198 * type.
1199 */
1200 class FunctionType: public Type
1201 {
1202 public:
1203 /// How this function is invoked on the EVM.
1204 enum class Kind
1205 {
1206 Internal, ///< stack-call using plain JUMP
1207 External, ///< external call using CALL
1208 DelegateCall, ///< external call using DELEGATECALL, i.e. not exchanging the storage
1209 BareCall, ///< CALL without function hash
1210 BareCallCode, ///< CALLCODE without function hash
1211 BareDelegateCall, ///< DELEGATECALL without function hash
1212 BareStaticCall, ///< STATICCALL without function hash
1213 Creation, ///< external call using CREATE
1214 Send, ///< CALL, but without data and gas
1215 Transfer, ///< CALL, but without data and throws on error
1216 KECCAK256, ///< KECCAK256
1217 Selfdestruct, ///< SELFDESTRUCT
1218 Revert, ///< REVERT
1219 ECRecover, ///< CALL to special contract for ecrecover
1220 SHA256, ///< CALL to special contract for sha256
1221 RIPEMD160, ///< CALL to special contract for ripemd160
1222 Event, ///< syntactic sugar for LOG*
1223 Error, ///< creating an error instance in revert or require
1224 Wrap, ///< customType.wrap(...) for user defined value types
1225 Unwrap, ///< customType.unwrap(...) for user defined value types
1226 SetGas, ///< modify the default gas value for the function call
1227 SetValue, ///< modify the default value transfer for the function call
1228 BlockHash, ///< BLOCKHASH
1229 AddMod, ///< ADDMOD
1230 MulMod, ///< MULMOD
1231 ArrayPush, ///< .push() to a dynamically sized array in storage
1232 ArrayPop, ///< .pop() from a dynamically sized array in storage
1233 BytesConcat, ///< .concat() on bytes (type type)
1234 ObjectCreation, ///< array creation using new
1235 Assert, ///< assert()
1236 Require, ///< require()
1237 ABIEncode,
1238 ABIEncodePacked,
1239 ABIEncodeWithSelector,
1240 ABIEncodeCall,
1241 ABIEncodeWithSignature,
1242 ABIDecode,
1243 GasLeft, ///< gasleft()
1244 MetaType, ///< type(...)
1245 /// Refers to a function declaration without calling context
1246 /// (i.e. when accessed directly via the name of the containing contract).
1247 /// Cannot be called.
1248 Declaration,
1249 };
1250
1251 /// Creates the type of a function.
1252 /// @arg _kind must be Kind::Internal, Kind::External or Kind::Declaration.
1253 explicit FunctionType(FunctionDefinition const& _function, Kind _kind = Kind::Declaration);
1254 /// Creates the accessor function type of a state variable.
1255 explicit FunctionType(VariableDeclaration const& _varDecl);
1256 /// Creates the function type of an event.
1257 explicit FunctionType(EventDefinition const& _event);
1258 explicit FunctionType(ErrorDefinition const& _error);
1259 /// Creates the type of a function type name.
1260 explicit FunctionType(FunctionTypeName const& _typeName);
1261 /// Function type constructor to be used for a plain type (not derived from a declaration).
1262 FunctionType(
1263 strings const& _parameterTypes,
1264 strings const& _returnParameterTypes,
1265 Kind _kind,
1266 bool _arbitraryParameters = false,
1267 StateMutability _stateMutability = StateMutability::NonPayable
1268 ): FunctionType(
parseElementaryTypeVector(_parameterTypes)1269 parseElementaryTypeVector(_parameterTypes),
1270 parseElementaryTypeVector(_returnParameterTypes),
1271 strings(_parameterTypes.size(), ""),
1272 strings(_returnParameterTypes.size(), ""),
1273 _kind,
1274 _arbitraryParameters,
1275 _stateMutability
1276 )
1277 {
1278 }
1279
1280 /// Detailed constructor, use with care.
1281 FunctionType(
1282 TypePointers _parameterTypes,
1283 TypePointers _returnParameterTypes,
1284 strings _parameterNames = strings(),
1285 strings _returnParameterNames = strings(),
1286 Kind _kind = Kind::Internal,
1287 bool _arbitraryParameters = false,
1288 StateMutability _stateMutability = StateMutability::NonPayable,
1289 Declaration const* _declaration = nullptr,
1290 bool _gasSet = false,
1291 bool _valueSet = false,
1292 bool _saltSet = false,
1293 bool _bound = false
1294 ):
m_parameterTypes(std::move (_parameterTypes))1295 m_parameterTypes(std::move(_parameterTypes)),
1296 m_returnParameterTypes(std::move(_returnParameterTypes)),
1297 m_parameterNames(std::move(_parameterNames)),
1298 m_returnParameterNames(std::move(_returnParameterNames)),
1299 m_kind(_kind),
1300 m_stateMutability(_stateMutability),
1301 m_arbitraryParameters(_arbitraryParameters),
1302 m_gasSet(_gasSet),
1303 m_valueSet(_valueSet),
1304 m_bound(_bound),
1305 m_declaration(_declaration),
1306 m_saltSet(_saltSet)
1307 {
1308 solAssert(
1309 m_parameterNames.size() == m_parameterTypes.size(),
1310 "Parameter names list must match parameter types list!"
1311 );
1312 solAssert(
1313 m_returnParameterNames.size() == m_returnParameterTypes.size(),
1314 "Return parameter names list must match return parameter types list!"
1315 );
1316 solAssert(
1317 !m_bound || !m_parameterTypes.empty(),
1318 "Attempted construction of bound function without self type"
1319 );
1320 }
1321
category()1322 Category category() const override { return Category::Function; }
1323
1324 /// @returns the type of the "new Contract" function, i.e. basically the constructor.
1325 static FunctionTypePointer newExpressionType(ContractDefinition const& _contract);
1326
1327 TypePointers parameterTypes() const;
1328 TypePointers const& parameterTypesIncludingSelf() const;
1329 std::vector<std::string> parameterNames() const;
returnParameterTypes()1330 TypePointers const& returnParameterTypes() const { return m_returnParameterTypes; }
1331 /// @returns the list of return parameter types. All dynamically-sized types (this excludes
1332 /// storage pointers) are replaced by InaccessibleDynamicType instances.
1333 TypePointers returnParameterTypesWithoutDynamicTypes() const;
returnParameterNames()1334 std::vector<std::string> const& returnParameterNames() const { return m_returnParameterNames; }
1335 /// @returns the "self" parameter type for a bound function
1336 Type const* selfType() const;
1337
1338 std::string richIdentifier() const override;
1339 bool operator==(Type const& _other) const override;
1340 BoolResult isImplicitlyConvertibleTo(Type const& _convertTo) const override;
1341 BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
1342 TypeResult unaryOperatorResult(Token _operator) const override;
1343 TypeResult binaryOperatorResult(Token, Type const*) const override;
1344 std::string canonicalName() const override;
1345 std::string toString(bool _short) const override;
1346 unsigned calldataEncodedSize(bool _padded) const override;
canBeStored()1347 bool canBeStored() const override { return m_kind == Kind::Internal || m_kind == Kind::External; }
1348 u256 storageSize() const override;
1349 bool leftAligned() const override;
1350 unsigned storageBytes() const override;
isValueType()1351 bool isValueType() const override { return true; }
1352 bool nameable() const override;
hasSimpleZeroValueInMemory()1353 bool hasSimpleZeroValueInMemory() const override { return false; }
1354 MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
1355 Type const* encodingType() const override;
1356 TypeResult interfaceType(bool _inLibrary) const override;
1357 Type const* mobileType() const override;
1358
1359 /// @returns Type const* of a new FunctionType object. All input/return parameters are an
1360 /// appropriate external types (i.e. the interfaceType()s) of input/return parameters of
1361 /// current function.
1362 /// @returns an empty shared pointer if one of the input/return parameters does not have an
1363 /// external type.
1364 FunctionTypePointer interfaceFunctionType() const;
1365
1366 /// @returns true if this function can take the given arguments (possibly
1367 /// after implicit conversion).
1368 /// @param _selfType if the function is bound, this has to be supplied and is the type of the
1369 /// expression the function is called on.
1370 bool canTakeArguments(
1371 FuncCallArguments const& _arguments,
1372 Type const* _selfType = nullptr
1373 ) const;
1374
1375 /// @returns true if the types of parameters are equal (does not check return parameter types)
1376 bool hasEqualParameterTypes(FunctionType const& _other) const;
1377 /// @returns true iff the return types are equal (does not check parameter types)
1378 bool hasEqualReturnTypes(FunctionType const& _other) const;
1379 /// @returns true iff the function type is equal to the given type, ignoring state mutability differences.
1380 bool equalExcludingStateMutability(FunctionType const& _other) const;
1381
1382 /// @returns true if the ABI is NOT used for this call (only meaningful for external calls)
1383 bool isBareCall() const;
kind()1384 Kind const& kind() const { return m_kind; }
stateMutability()1385 StateMutability stateMutability() const { return m_stateMutability; }
1386 /// @returns the external signature of this function type given the function name
1387 std::string externalSignature() const;
1388 /// @returns the external identifier of this function (the hash of the signature).
1389 u256 externalIdentifier() const;
1390 /// @returns the external identifier of this function (the hash of the signature) as a hex string.
1391 std::string externalIdentifierHex() const;
declaration()1392 Declaration const& declaration() const
1393 {
1394 solAssert(m_declaration, "Requested declaration from a FunctionType that has none");
1395 return *m_declaration;
1396 }
hasDeclaration()1397 bool hasDeclaration() const { return !!m_declaration; }
1398 /// @returns true if the result of this function only depends on its arguments,
1399 /// does not modify the state and is a compile-time constant.
1400 /// Currently, this will only return true for internal functions like keccak and ecrecover.
1401 bool isPure() const;
isPayable()1402 bool isPayable() const { return m_stateMutability == StateMutability::Payable; }
1403 /// @return A shared pointer of StructuredDocumentation.
1404 /// Can contain a nullptr in which case indicates absence of documentation.
1405 ASTPointer<StructuredDocumentation> documentation() const;
1406
1407 /// true iff arguments are to be padded to multiples of 32 bytes for external calls
1408 /// The only functions that do not pad are hash functions, the low-level call functions
1409 /// and abi.encodePacked.
1410 bool padArguments() const;
takesArbitraryParameters()1411 bool takesArbitraryParameters() const { return m_arbitraryParameters; }
1412 /// true iff the function takes a single bytes parameter and it is passed on without padding.
takesSinglePackedBytesParameter()1413 bool takesSinglePackedBytesParameter() const
1414 {
1415 switch (m_kind)
1416 {
1417 case FunctionType::Kind::KECCAK256:
1418 case FunctionType::Kind::SHA256:
1419 case FunctionType::Kind::RIPEMD160:
1420 case FunctionType::Kind::BareCall:
1421 case FunctionType::Kind::BareCallCode:
1422 case FunctionType::Kind::BareDelegateCall:
1423 case FunctionType::Kind::BareStaticCall:
1424 return true;
1425 default:
1426 return false;
1427 }
1428 }
1429
gasSet()1430 bool gasSet() const { return m_gasSet; }
valueSet()1431 bool valueSet() const { return m_valueSet; }
saltSet()1432 bool saltSet() const { return m_saltSet; }
bound()1433 bool bound() const { return m_bound; }
1434
1435 /// @returns a copy of this type, where gas or value are set manually. This will never set one
1436 /// of the parameters to false.
1437 Type const* copyAndSetCallOptions(bool _setGas, bool _setValue, bool _setSalt) const;
1438
1439 /// @returns a copy of this function type with the `bound` flag set to true.
1440 /// Should only be called on library functions.
1441 FunctionTypePointer asBoundFunction() const;
1442
1443 /// @returns a copy of this function type where the location of reference types is changed
1444 /// from CallData to Memory. This is the type that would be used when the function is
1445 /// called externally, as opposed to the parameter types that are available inside the function body.
1446 /// Also supports variants to be used for library or bound calls.
1447 /// @param _inLibrary if true, uses DelegateCall as location.
1448 FunctionTypePointer asExternallyCallableFunction(bool _inLibrary) const;
1449
1450 protected:
1451 std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;
1452 private:
1453 static TypePointers parseElementaryTypeVector(strings const& _types);
1454
1455 TypePointers m_parameterTypes;
1456 TypePointers m_returnParameterTypes;
1457 std::vector<std::string> m_parameterNames;
1458 std::vector<std::string> m_returnParameterNames;
1459 Kind const m_kind;
1460 StateMutability m_stateMutability = StateMutability::NonPayable;
1461 /// true if the function takes an arbitrary number of arguments of arbitrary types
1462 bool const m_arbitraryParameters = false;
1463 bool const m_gasSet = false; ///< true iff the gas value to be used is on the stack
1464 bool const m_valueSet = false; ///< true iff the value to be sent is on the stack
1465 /// true iff the function is called as arg1.fun(arg2, ..., argn).
1466 /// This is achieved through the "using for" directive.
1467 bool const m_bound = false;
1468 Declaration const* m_declaration = nullptr;
1469 bool m_saltSet = false; ///< true iff the salt value to be used is on the stack
1470 };
1471
1472 /**
1473 * The type of a mapping, there is one distinct type per key/value type pair.
1474 * Mappings always occupy their own storage slot, but do not actually use it.
1475 */
1476 class MappingType: public CompositeType
1477 {
1478 public:
MappingType(Type const * _keyType,Type const * _valueType)1479 MappingType(Type const* _keyType, Type const* _valueType):
1480 m_keyType(_keyType), m_valueType(_valueType) {}
1481
category()1482 Category category() const override { return Category::Mapping; }
1483
1484 std::string richIdentifier() const override;
1485 bool operator==(Type const& _other) const override;
1486 std::string toString(bool _short) const override;
1487 std::string canonicalName() const override;
containsNestedMapping()1488 bool containsNestedMapping() const override { return true; }
binaryOperatorResult(Token,Type const *)1489 TypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }
1490 Type const* encodingType() const override;
1491 TypeResult interfaceType(bool _inLibrary) const override;
dataStoredIn(DataLocation _location)1492 bool dataStoredIn(DataLocation _location) const override { return _location == DataLocation::Storage; }
1493 /// Cannot be stored in memory, but just in case.
hasSimpleZeroValueInMemory()1494 bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
nameable()1495 bool nameable() const override { return true; }
1496
keyType()1497 Type const* keyType() const { return m_keyType; }
valueType()1498 Type const* valueType() const { return m_valueType; }
1499
1500 protected:
decomposition()1501 std::vector<Type const*> decomposition() const override { return {m_valueType}; }
1502
1503 private:
1504 Type const* m_keyType;
1505 Type const* m_valueType;
1506 };
1507
1508 /**
1509 * The type of a type reference. The type of "uint32" when used in "a = uint32(2)" is an example
1510 * of a TypeType.
1511 * For super contracts or libraries, this has members directly.
1512 */
1513 class TypeType: public Type
1514 {
1515 public:
TypeType(Type const * _actualType)1516 explicit TypeType(Type const* _actualType): m_actualType(_actualType) {}
1517
category()1518 Category category() const override { return Category::TypeType; }
actualType()1519 Type const* actualType() const { return m_actualType; }
1520
binaryOperatorResult(Token,Type const *)1521 TypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }
1522 std::string richIdentifier() const override;
1523 bool operator==(Type const& _other) const override;
canBeStored()1524 bool canBeStored() const override { return false; }
1525 u256 storageSize() const override;
hasSimpleZeroValueInMemory()1526 bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
toString(bool _short)1527 std::string toString(bool _short) const override { return "type(" + m_actualType->toString(_short) + ")"; }
1528 MemberList::MemberMap nativeMembers(ASTNode const* _currentScope) const override;
1529
1530 BoolResult isExplicitlyConvertibleTo(Type const& _convertTo) const override;
1531 protected:
1532 std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override;
1533 private:
1534 Type const* m_actualType;
1535 };
1536
1537
1538 /**
1539 * The type of a function modifier. Not used for anything for now.
1540 */
1541 class ModifierType: public Type
1542 {
1543 public:
1544 explicit ModifierType(ModifierDefinition const& _modifier);
1545
category()1546 Category category() const override { return Category::Modifier; }
1547
binaryOperatorResult(Token,Type const *)1548 TypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }
canBeStored()1549 bool canBeStored() const override { return false; }
1550 u256 storageSize() const override;
hasSimpleZeroValueInMemory()1551 bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
1552 std::string richIdentifier() const override;
1553 bool operator==(Type const& _other) const override;
1554 std::string toString(bool _short) const override;
1555 protected:
makeStackItems()1556 std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override { return {}; }
1557 private:
1558 TypePointers m_parameterTypes;
1559 };
1560
1561
1562
1563 /**
1564 * Special type for imported modules. These mainly give access to their scope via members.
1565 */
1566 class ModuleType: public Type
1567 {
1568 public:
ModuleType(SourceUnit const & _source)1569 explicit ModuleType(SourceUnit const& _source): m_sourceUnit(_source) {}
1570
category()1571 Category category() const override { return Category::Module; }
1572
binaryOperatorResult(Token,Type const *)1573 TypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }
1574 std::string richIdentifier() const override;
1575 bool operator==(Type const& _other) const override;
canBeStored()1576 bool canBeStored() const override { return false; }
hasSimpleZeroValueInMemory()1577 bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
1578 MemberList::MemberMap nativeMembers(ASTNode const*) const override;
1579
1580 std::string toString(bool _short) const override;
1581
1582 protected:
makeStackItems()1583 std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override { return {}; }
1584 private:
1585 SourceUnit const& m_sourceUnit;
1586 };
1587
1588 /**
1589 * Special type for magic variables (block, msg, tx, type(...)), similar to a struct but without any reference.
1590 */
1591 class MagicType: public Type
1592 {
1593 public:
1594 enum class Kind {
1595 Block, ///< "block"
1596 Message, ///< "msg"
1597 Transaction, ///< "tx"
1598 ABI, ///< "abi"
1599 MetaType ///< "type(...)"
1600 };
1601
1602 public:
MagicType(Kind _kind)1603 explicit MagicType(Kind _kind): m_kind(_kind) {}
MagicType(Type const * _metaTypeArg)1604 explicit MagicType(Type const* _metaTypeArg): m_kind{Kind::MetaType}, m_typeArgument{_metaTypeArg} {}
1605
category()1606 Category category() const override { return Category::Magic; }
1607
binaryOperatorResult(Token,Type const *)1608 TypeResult binaryOperatorResult(Token, Type const*) const override
1609 {
1610 return nullptr;
1611 }
1612
1613 std::string richIdentifier() const override;
1614 bool operator==(Type const& _other) const override;
canBeStored()1615 bool canBeStored() const override { return false; }
hasSimpleZeroValueInMemory()1616 bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
1617 MemberList::MemberMap nativeMembers(ASTNode const*) const override;
1618
1619 std::string toString(bool _short) const override;
1620
kind()1621 Kind kind() const { return m_kind; }
1622
1623 Type const* typeArgument() const;
1624
1625 protected:
makeStackItems()1626 std::vector<std::tuple<std::string, Type const*>> makeStackItems() const override { return {}; }
1627 private:
1628 Kind m_kind;
1629 /// Contract type used for contract metadata magic.
1630 Type const* m_typeArgument;
1631 };
1632
1633 /**
1634 * Special type that is used for dynamic types in returns from external function calls
1635 * (The EVM currently cannot access dynamically-sized return values).
1636 */
1637 class InaccessibleDynamicType: public Type
1638 {
1639 public:
category()1640 Category category() const override { return Category::InaccessibleDynamic; }
1641
richIdentifier()1642 std::string richIdentifier() const override { return "t_inaccessible"; }
isImplicitlyConvertibleTo(Type const &)1643 BoolResult isImplicitlyConvertibleTo(Type const&) const override { return false; }
isExplicitlyConvertibleTo(Type const &)1644 BoolResult isExplicitlyConvertibleTo(Type const&) const override { return false; }
binaryOperatorResult(Token,Type const *)1645 TypeResult binaryOperatorResult(Token, Type const*) const override { return nullptr; }
calldataEncodedSize(bool)1646 unsigned calldataEncodedSize(bool) const override { return 32; }
canBeStored()1647 bool canBeStored() const override { return false; }
isValueType()1648 bool isValueType() const override { return true; }
hasSimpleZeroValueInMemory()1649 bool hasSimpleZeroValueInMemory() const override { solAssert(false, ""); }
toString(bool)1650 std::string toString(bool) const override { return "inaccessible dynamic type"; }
1651 Type const* decodingType() const override;
1652 };
1653
1654 }
1655