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{};
|
|
};
|
|
|
|
}
|