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 #pragma once
20 
21 #include <libsolidity/ast/Types.h>
22 
23 #include <array>
24 #include <map>
25 #include <memory>
26 #include <optional>
27 #include <utility>
28 
29 namespace solidity::frontend
30 {
31 
32 /**
33  * API for accessing the Solidity Type System.
34  *
35  * This is the Solidity Compiler's type provider. Use it to request for types. The caller does
36  * <b>not</b> own the types.
37  *
38  * It is not recommended to explicitly instantiate types unless you really know what and why
39  * you are doing it.
40  */
41 class TypeProvider
42 {
43 public:
44 	TypeProvider() = default;
45 	TypeProvider(TypeProvider&&) = default;
46 	TypeProvider(TypeProvider const&) = delete;
47 	TypeProvider& operator=(TypeProvider&&) = default;
48 	TypeProvider& operator=(TypeProvider const&) = delete;
49 	~TypeProvider() = default;
50 
51 	/// Resets state of this TypeProvider to initial state, wiping all mutable types.
52 	/// This invalidates all dangling pointers to types provided by this TypeProvider.
53 	static void reset();
54 
55 	/// @name Factory functions
56 	/// Factory functions that convert an AST @ref TypeName to a Type.
57 	static Type const* fromElementaryTypeName(ElementaryTypeNameToken const& _type, std::optional<StateMutability> _stateMutability = {});
58 
59 	/// Converts a given elementary type name with optional data location
60 	/// suffix " storage", " calldata" or " memory" to a type pointer. If suffix not given, defaults to " storage".
61 	static Type const* fromElementaryTypeName(std::string const& _name);
62 
63 	/// @returns boolean type.
boolean()64 	static BoolType const* boolean() noexcept { return &m_boolean; }
65 
byte()66 	static FixedBytesType const* byte() { return fixedBytes(1); }
fixedBytes(unsigned m)67 	static FixedBytesType const* fixedBytes(unsigned m) { return m_bytesM.at(m - 1).get(); }
68 
69 	static ArrayType const* bytesStorage();
70 	static ArrayType const* bytesMemory();
71 	static ArrayType const* bytesCalldata();
72 	static ArrayType const* stringStorage();
73 	static ArrayType const* stringMemory();
74 
75 	/// Constructor for a byte array ("bytes") and string.
76 	static ArrayType const* array(DataLocation _location, bool _isString = false);
77 
78 	/// Constructor for a dynamically sized array type ("type[]")
79 	static ArrayType const* array(DataLocation _location, Type const* _baseType);
80 
81 	/// Constructor for a fixed-size array type ("type[20]")
82 	static ArrayType const* array(DataLocation _location, Type const* _baseType, u256 const& _length);
83 
84 	static ArraySliceType const* arraySlice(ArrayType const& _arrayType);
85 
payableAddress()86 	static AddressType const* payableAddress() noexcept { return &m_payableAddress; }
address()87 	static AddressType const* address() noexcept { return &m_address; }
88 
integer(unsigned _bits,IntegerType::Modifier _modifier)89 	static IntegerType const* integer(unsigned _bits, IntegerType::Modifier _modifier)
90 	{
91 		solAssert((_bits % 8) == 0, "");
92 		if (_modifier == IntegerType::Modifier::Unsigned)
93 			return m_uintM.at(_bits / 8 - 1).get();
94 		else
95 			return m_intM.at(_bits / 8 - 1).get();
96 	}
uint(unsigned _bits)97 	static IntegerType const* uint(unsigned _bits) { return integer(_bits, IntegerType::Modifier::Unsigned); }
98 
uint256()99 	static IntegerType const* uint256() { return uint(256); }
int256()100 	static IntegerType const* int256() { return integer(256, IntegerType::Modifier::Signed); }
101 
102 	static FixedPointType const* fixedPoint(unsigned m, unsigned n, FixedPointType::Modifier _modifier);
103 
104 	static StringLiteralType const* stringLiteral(std::string const& literal);
105 
106 	/// @param members the member types the tuple type must contain. This is passed by value on purspose.
107 	/// @returns a tuple type with the given members.
108 	static TupleType const* tuple(std::vector<Type const*> members);
109 
emptyTuple()110 	static TupleType const* emptyTuple() noexcept { return &m_emptyTuple; }
111 
112 	static ReferenceType const* withLocation(ReferenceType const* _type, DataLocation _location, bool _isPointer);
113 
114 	/// @returns a copy of @a _type having the same location as this (and is not a pointer type)
115 	///          if _type is a reference type and an unmodified copy of _type otherwise.
116 	///          This function is mostly useful to modify inner types appropriately.
117 	static Type const* withLocationIfReference(DataLocation _location, Type const* _type, bool _isPointer = false)
118 	{
119 		if (auto refType = dynamic_cast<ReferenceType const*>(_type))
120 			return withLocation(refType, _location, _isPointer);
121 
122 		return _type;
123 	}
124 
isReferenceWithLocation(Type const * _type,DataLocation _location)125 	static bool isReferenceWithLocation(Type const* _type, DataLocation _location)
126 	{
127 		if (auto const* refType = dynamic_cast<ReferenceType const*>(_type))
128 			if (refType->location() == _location)
129 				return true;
130 		return false;
131 	}
132 
133 	/// @returns the internally-facing or externally-facing type of a function or the type of a function declaration.
134 	static FunctionType const* function(FunctionDefinition const& _function, FunctionType::Kind _kind = FunctionType::Kind::Declaration);
135 
136 	/// @returns the accessor function type of a state variable.
137 	static FunctionType const* function(VariableDeclaration const& _varDecl);
138 
139 	/// @returns the function type of an event.
140 	static FunctionType const* function(EventDefinition const& _event);
141 
142 	static FunctionType const* function(ErrorDefinition const& _error);
143 
144 	/// @returns the type of a function type name.
145 	static FunctionType const* function(FunctionTypeName const& _typeName);
146 
147 	/// @returns the function type to be used for a plain type (not derived from a declaration).
148 	static FunctionType const* function(
149 		strings const& _parameterTypes,
150 		strings const& _returnParameterTypes,
151 		FunctionType::Kind _kind = FunctionType::Kind::Internal,
152 		bool _arbitraryParameters = false,
153 		StateMutability _stateMutability = StateMutability::NonPayable
154 	);
155 
156 	/// @returns a highly customized FunctionType, use with care.
157 	static FunctionType const* function(
158 		TypePointers const& _parameterTypes,
159 		TypePointers const& _returnParameterTypes,
160 		strings _parameterNames = strings{},
161 		strings _returnParameterNames = strings{},
162 		FunctionType::Kind _kind = FunctionType::Kind::Internal,
163 		bool _arbitraryParameters = false,
164 		StateMutability _stateMutability = StateMutability::NonPayable,
165 		Declaration const* _declaration = nullptr,
166 		bool _gasSet = false,
167 		bool _valueSet = false,
168 		bool _bound = false,
169 		bool _saltSet = false
170 	);
171 
172 	/// Auto-detect the proper type for a literal. @returns an empty pointer if the literal does
173 	/// not fit any type.
174 	static Type const* forLiteral(Literal const& _literal);
175 	static RationalNumberType const* rationalNumber(Literal const& _literal);
176 
177 	static RationalNumberType const* rationalNumber(
178 		rational const& _value,
179 		Type const* _compatibleBytesType = nullptr
180 	);
181 
182 	static ContractType const* contract(ContractDefinition const& _contract, bool _isSuper = false);
183 
inaccessibleDynamic()184 	static InaccessibleDynamicType const* inaccessibleDynamic() noexcept { return &m_inaccessibleDynamic; }
185 
186 	/// @returns the type of an enum instance for given definition, there is one distinct type per enum definition.
187 	static EnumType const* enumType(EnumDefinition const& _enum);
188 
189 	/// @returns special type for imported modules. These mainly give access to their scope via members.
190 	static ModuleType const* module(SourceUnit const& _source);
191 
192 	static TypeType const* typeType(Type const* _actualType);
193 
194 	static StructType const* structType(StructDefinition const& _struct, DataLocation _location);
195 
196 	static ModifierType const* modifier(ModifierDefinition const& _modifierDef);
197 
198 	static MagicType const* magic(MagicType::Kind _kind);
199 
200 	static MagicType const* meta(Type const* _type);
201 
202 	static MappingType const* mapping(Type const* _keyType, Type const* _valueType);
203 
204 	static UserDefinedValueType const* userDefinedValueType(UserDefinedValueTypeDefinition const& _definition);
205 
206 private:
207 	/// Global TypeProvider instance.
instance()208 	static TypeProvider& instance()
209 	{
210 		static TypeProvider _provider;
211 		return _provider;
212 	}
213 
214 	template <typename T, typename... Args>
215 	static inline T const* createAndGet(Args&& ... _args);
216 
217 	static BoolType const m_boolean;
218 	static InaccessibleDynamicType const m_inaccessibleDynamic;
219 
220 	/// These are lazy-initialized because they depend on `byte` being available.
221 	static std::unique_ptr<ArrayType> m_bytesStorage;
222 	static std::unique_ptr<ArrayType> m_bytesMemory;
223 	static std::unique_ptr<ArrayType> m_bytesCalldata;
224 	static std::unique_ptr<ArrayType> m_stringStorage;
225 	static std::unique_ptr<ArrayType> m_stringMemory;
226 
227 	static TupleType const m_emptyTuple;
228 	static AddressType const m_payableAddress;
229 	static AddressType const m_address;
230 	static std::array<std::unique_ptr<IntegerType>, 32> const m_intM;
231 	static std::array<std::unique_ptr<IntegerType>, 32> const m_uintM;
232 	static std::array<std::unique_ptr<FixedBytesType>, 32> const m_bytesM;
233 	static std::array<std::unique_ptr<MagicType>, 4> const m_magics;        ///< MagicType's except MetaType
234 
235 	std::map<std::pair<unsigned, unsigned>, std::unique_ptr<FixedPointType>> m_ufixedMxN{};
236 	std::map<std::pair<unsigned, unsigned>, std::unique_ptr<FixedPointType>> m_fixedMxN{};
237 	std::map<std::string, std::unique_ptr<StringLiteralType>> m_stringLiteralTypes{};
238 	std::vector<std::unique_ptr<Type>> m_generalTypes{};
239 };
240 
241 }
242