mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			242 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			242 lines
		
	
	
		
			9.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
| 	This file is part of solidity.
 | |
| 
 | |
| 	solidity 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.
 | |
| 
 | |
| 	solidity 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.
 | |
| 
 | |
| 	You should have received a copy of the GNU General Public License
 | |
| 	along with solidity.  If not, see <http://www.gnu.org/licenses/>.
 | |
| */
 | |
| // SPDX-License-Identifier: GPL-3.0
 | |
| 
 | |
| #pragma once
 | |
| 
 | |
| #include <libsolidity/ast/Types.h>
 | |
| 
 | |
| #include <array>
 | |
| #include <map>
 | |
| #include <memory>
 | |
| #include <optional>
 | |
| #include <utility>
 | |
| 
 | |
| namespace solidity::frontend
 | |
| {
 | |
| 
 | |
| /**
 | |
|  * API for accessing the Solidity Type System.
 | |
|  *
 | |
|  * This is the Solidity Compiler's type provider. Use it to request for types. The caller does
 | |
|  * <b>not</b> own the types.
 | |
|  *
 | |
|  * It is not recommended to explicitly instantiate types unless you really know what and why
 | |
|  * you are doing it.
 | |
|  */
 | |
| class TypeProvider
 | |
| {
 | |
| public:
 | |
| 	TypeProvider() = default;
 | |
| 	TypeProvider(TypeProvider&&) = default;
 | |
| 	TypeProvider(TypeProvider const&) = delete;
 | |
| 	TypeProvider& operator=(TypeProvider&&) = default;
 | |
| 	TypeProvider& operator=(TypeProvider const&) = delete;
 | |
| 	~TypeProvider() = default;
 | |
| 
 | |
| 	/// Resets state of this TypeProvider to initial state, wiping all mutable types.
 | |
| 	/// This invalidates all dangling pointers to types provided by this TypeProvider.
 | |
| 	static void reset();
 | |
| 
 | |
| 	/// @name Factory functions
 | |
| 	/// Factory functions that convert an AST @ref TypeName to a Type.
 | |
| 	static Type const* fromElementaryTypeName(ElementaryTypeNameToken const& _type, std::optional<StateMutability> _stateMutability = {});
 | |
| 
 | |
| 	/// Converts a given elementary type name with optional data location
 | |
| 	/// suffix " storage", " calldata" or " memory" to a type pointer. If suffix not given, defaults to " storage".
 | |
| 	static Type const* fromElementaryTypeName(std::string const& _name);
 | |
| 
 | |
| 	/// @returns boolean type.
 | |
| 	static BoolType const* boolean() noexcept { return &m_boolean; }
 | |
| 
 | |
| 	static FixedBytesType const* byte() { return fixedBytes(1); }
 | |
| 	static FixedBytesType const* fixedBytes(unsigned m) { return m_bytesM.at(m - 1).get(); }
 | |
| 
 | |
| 	static ArrayType const* bytesStorage();
 | |
| 	static ArrayType const* bytesMemory();
 | |
| 	static ArrayType const* bytesCalldata();
 | |
| 	static ArrayType const* stringStorage();
 | |
| 	static ArrayType const* stringMemory();
 | |
| 
 | |
| 	/// Constructor for a byte array ("bytes") and string.
 | |
| 	static ArrayType const* array(DataLocation _location, bool _isString = false);
 | |
| 
 | |
| 	/// Constructor for a dynamically sized array type ("type[]")
 | |
| 	static ArrayType const* array(DataLocation _location, Type const* _baseType);
 | |
| 
 | |
| 	/// Constructor for a fixed-size array type ("type[20]")
 | |
| 	static ArrayType const* array(DataLocation _location, Type const* _baseType, u256 const& _length);
 | |
| 
 | |
| 	static ArraySliceType const* arraySlice(ArrayType const& _arrayType);
 | |
| 
 | |
| 	static AddressType const* payableAddress() noexcept { return &m_payableAddress; }
 | |
| 	static AddressType const* address() noexcept { return &m_address; }
 | |
| 
 | |
| 	static IntegerType const* integer(unsigned _bits, IntegerType::Modifier _modifier)
 | |
| 	{
 | |
| 		solAssert((_bits % 8) == 0, "");
 | |
| 		if (_modifier == IntegerType::Modifier::Unsigned)
 | |
| 			return m_uintM.at(_bits / 8 - 1).get();
 | |
| 		else
 | |
| 			return m_intM.at(_bits / 8 - 1).get();
 | |
| 	}
 | |
| 	static IntegerType const* uint(unsigned _bits) { return integer(_bits, IntegerType::Modifier::Unsigned); }
 | |
| 
 | |
| 	static IntegerType const* uint256() { return uint(256); }
 | |
| 	static IntegerType const* int256() { return integer(256, IntegerType::Modifier::Signed); }
 | |
| 
 | |
| 	static FixedPointType const* fixedPoint(unsigned m, unsigned n, FixedPointType::Modifier _modifier);
 | |
| 
 | |
| 	static StringLiteralType const* stringLiteral(std::string const& literal);
 | |
| 
 | |
| 	/// @param members the member types the tuple type must contain. This is passed by value on purspose.
 | |
| 	/// @returns a tuple type with the given members.
 | |
| 	static TupleType const* tuple(std::vector<Type const*> members);
 | |
| 
 | |
| 	static TupleType const* emptyTuple() noexcept { return &m_emptyTuple; }
 | |
| 
 | |
| 	static ReferenceType const* withLocation(ReferenceType const* _type, DataLocation _location, bool _isPointer);
 | |
| 
 | |
| 	/// @returns a copy of @a _type having the same location as this (and is not a pointer type)
 | |
| 	///          if _type is a reference type and an unmodified copy of _type otherwise.
 | |
| 	///          This function is mostly useful to modify inner types appropriately.
 | |
| 	static Type const* withLocationIfReference(DataLocation _location, Type const* _type, bool _isPointer = false)
 | |
| 	{
 | |
| 		if (auto refType = dynamic_cast<ReferenceType const*>(_type))
 | |
| 			return withLocation(refType, _location, _isPointer);
 | |
| 
 | |
| 		return _type;
 | |
| 	}
 | |
| 
 | |
| 	static bool isReferenceWithLocation(Type const* _type, DataLocation _location)
 | |
| 	{
 | |
| 		if (auto const* refType = dynamic_cast<ReferenceType const*>(_type))
 | |
| 			if (refType->location() == _location)
 | |
| 				return true;
 | |
| 		return false;
 | |
| 	}
 | |
| 
 | |
| 	/// @returns the internally-facing or externally-facing type of a function or the type of a function declaration.
 | |
| 	static FunctionType const* function(FunctionDefinition const& _function, FunctionType::Kind _kind = FunctionType::Kind::Declaration);
 | |
| 
 | |
| 	/// @returns the accessor function type of a state variable.
 | |
| 	static FunctionType const* function(VariableDeclaration const& _varDecl);
 | |
| 
 | |
| 	/// @returns the function type of an event.
 | |
| 	static FunctionType const* function(EventDefinition const& _event);
 | |
| 
 | |
| 	static FunctionType const* function(ErrorDefinition const& _error);
 | |
| 
 | |
| 	/// @returns the type of a function type name.
 | |
| 	static FunctionType const* function(FunctionTypeName const& _typeName);
 | |
| 
 | |
| 	/// @returns the function type to be used for a plain type (not derived from a declaration).
 | |
| 	static FunctionType const* function(
 | |
| 		strings const& _parameterTypes,
 | |
| 		strings const& _returnParameterTypes,
 | |
| 		FunctionType::Kind _kind = FunctionType::Kind::Internal,
 | |
| 		bool _arbitraryParameters = false,
 | |
| 		StateMutability _stateMutability = StateMutability::NonPayable
 | |
| 	);
 | |
| 
 | |
| 	/// @returns a highly customized FunctionType, use with care.
 | |
| 	static FunctionType const* function(
 | |
| 		TypePointers const& _parameterTypes,
 | |
| 		TypePointers const& _returnParameterTypes,
 | |
| 		strings _parameterNames = strings{},
 | |
| 		strings _returnParameterNames = strings{},
 | |
| 		FunctionType::Kind _kind = FunctionType::Kind::Internal,
 | |
| 		bool _arbitraryParameters = false,
 | |
| 		StateMutability _stateMutability = StateMutability::NonPayable,
 | |
| 		Declaration const* _declaration = nullptr,
 | |
| 		bool _gasSet = false,
 | |
| 		bool _valueSet = false,
 | |
| 		bool _bound = false,
 | |
| 		bool _saltSet = false
 | |
| 	);
 | |
| 
 | |
| 	/// Auto-detect the proper type for a literal. @returns an empty pointer if the literal does
 | |
| 	/// not fit any type.
 | |
| 	static Type const* forLiteral(Literal const& _literal);
 | |
| 	static RationalNumberType const* rationalNumber(Literal const& _literal);
 | |
| 
 | |
| 	static RationalNumberType const* rationalNumber(
 | |
| 		rational const& _value,
 | |
| 		Type const* _compatibleBytesType = nullptr
 | |
| 	);
 | |
| 
 | |
| 	static ContractType const* contract(ContractDefinition const& _contract, bool _isSuper = false);
 | |
| 
 | |
| 	static InaccessibleDynamicType const* inaccessibleDynamic() noexcept { return &m_inaccessibleDynamic; }
 | |
| 
 | |
| 	/// @returns the type of an enum instance for given definition, there is one distinct type per enum definition.
 | |
| 	static EnumType const* enumType(EnumDefinition const& _enum);
 | |
| 
 | |
| 	/// @returns special type for imported modules. These mainly give access to their scope via members.
 | |
| 	static ModuleType const* module(SourceUnit const& _source);
 | |
| 
 | |
| 	static TypeType const* typeType(Type const* _actualType);
 | |
| 
 | |
| 	static StructType const* structType(StructDefinition const& _struct, DataLocation _location);
 | |
| 
 | |
| 	static ModifierType const* modifier(ModifierDefinition const& _modifierDef);
 | |
| 
 | |
| 	static MagicType const* magic(MagicType::Kind _kind);
 | |
| 
 | |
| 	static MagicType const* meta(Type const* _type);
 | |
| 
 | |
| 	static MappingType const* mapping(Type const* _keyType, Type const* _valueType);
 | |
| 
 | |
| 	static UserDefinedValueType const* userDefinedValueType(UserDefinedValueTypeDefinition const& _definition);
 | |
| 
 | |
| private:
 | |
| 	/// Global TypeProvider instance.
 | |
| 	static TypeProvider& instance()
 | |
| 	{
 | |
| 		static TypeProvider _provider;
 | |
| 		return _provider;
 | |
| 	}
 | |
| 
 | |
| 	template <typename T, typename... Args>
 | |
| 	static inline T const* createAndGet(Args&& ... _args);
 | |
| 
 | |
| 	static BoolType const m_boolean;
 | |
| 	static InaccessibleDynamicType const m_inaccessibleDynamic;
 | |
| 
 | |
| 	/// These are lazy-initialized because they depend on `byte` being available.
 | |
| 	static std::unique_ptr<ArrayType> m_bytesStorage;
 | |
| 	static std::unique_ptr<ArrayType> m_bytesMemory;
 | |
| 	static std::unique_ptr<ArrayType> m_bytesCalldata;
 | |
| 	static std::unique_ptr<ArrayType> m_stringStorage;
 | |
| 	static std::unique_ptr<ArrayType> m_stringMemory;
 | |
| 
 | |
| 	static TupleType const m_emptyTuple;
 | |
| 	static AddressType const m_payableAddress;
 | |
| 	static AddressType const m_address;
 | |
| 	static std::array<std::unique_ptr<IntegerType>, 32> const m_intM;
 | |
| 	static std::array<std::unique_ptr<IntegerType>, 32> const m_uintM;
 | |
| 	static std::array<std::unique_ptr<FixedBytesType>, 32> const m_bytesM;
 | |
| 	static std::array<std::unique_ptr<MagicType>, 4> const m_magics;        ///< MagicType's except MetaType
 | |
| 
 | |
| 	std::map<std::pair<unsigned, unsigned>, std::unique_ptr<FixedPointType>> m_ufixedMxN{};
 | |
| 	std::map<std::pair<unsigned, unsigned>, std::unique_ptr<FixedPointType>> m_fixedMxN{};
 | |
| 	std::map<std::string, std::unique_ptr<StringLiteralType>> m_stringLiteralTypes{};
 | |
| 	std::vector<std::unique_ptr<Type>> m_generalTypes{};
 | |
| };
 | |
| 
 | |
| }
 |