aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Changelog.md1
-rw-r--r--libsolidity/ast/Types.cpp189
-rw-r--r--libsolidity/ast/Types.h24
-rw-r--r--test/libsolidity/SolidityTypes.cpp66
4 files changed, 277 insertions, 3 deletions
diff --git a/Changelog.md b/Changelog.md
index 1e5dd8e1..b9e4ecc0 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -3,6 +3,7 @@
Features:
* Compiler Interface: Contracts and libraries can be referenced with a `file:` prefix to make them unique.
* AST: Use deterministic node identifiers.
+ * Type system: Introduce type identifier strings.
* Metadata: Do not include platform in the version number.
### 0.4.8 (2017-01-13)
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 03ff8471..9e722474 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -272,7 +272,15 @@ IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier):
solAssert(
m_bits > 0 && m_bits <= 256 && m_bits % 8 == 0,
"Invalid bit number for integer type: " + dev::toString(_bits)
- );
+ );
+}
+
+string IntegerType::identifier() const
+{
+ if (isAddress())
+ return "t_address";
+ else
+ return "t_" + string(isSigned() ? "" : "u") + "int" + std::to_string(numBits());
}
bool IntegerType::isImplicitlyConvertibleTo(Type const& _convertTo) const
@@ -412,7 +420,12 @@ FixedPointType::FixedPointType(int _integerBits, int _fractionalBits, FixedPoint
m_fractionalBits % 8 == 0,
"Invalid bit number(s) for fixed type: " +
dev::toString(_integerBits) + "x" + dev::toString(_fractionalBits)
- );
+ );
+}
+
+string FixedPointType::identifier() const
+{
+ return "t_" + string(isSigned() ? "" : "u") + "fixed" + std::to_string(integerBits()) + "x" + std::to_string(fractionalBits());
}
bool FixedPointType::isImplicitlyConvertibleTo(Type const& _convertTo) const
@@ -770,6 +783,11 @@ TypePointer RationalNumberType::binaryOperatorResult(Token::Value _operator, Typ
}
}
+string RationalNumberType::identifier() const
+{
+ return "t_rational_" + m_value.numerator().str() + "_by_" + m_value.denominator().str();
+}
+
bool RationalNumberType::operator==(Type const& _other) const
{
if (_other.category() != category())
@@ -909,6 +927,13 @@ bool StringLiteralType::isImplicitlyConvertibleTo(Type const& _convertTo) const
return false;
}
+string StringLiteralType::identifier() const
+{
+ // Since we have to return a valid identifier and the string itself may contain
+ // anything, we hash it.
+ return "t_stringliteral_" + toHex(keccak256(m_value).asBytes());
+}
+
bool StringLiteralType::operator==(const Type& _other) const
{
if (_other.category() != category())
@@ -1002,6 +1027,11 @@ MemberList::MemberMap FixedBytesType::nativeMembers(const ContractDefinition*) c
return MemberList::MemberMap{MemberList::Member{"length", make_shared<IntegerType>(8)}};
}
+string FixedBytesType::identifier() const
+{
+ return "t_bytes" + std::to_string(m_bytes);
+}
+
bool FixedBytesType::operator==(Type const& _other) const
{
if (_other.category() != category())
@@ -1115,6 +1145,20 @@ string ReferenceType::stringForReferencePart() const
return "";
}
+string ReferenceType::identifierLocationSuffix() const
+{
+ string id;
+ if (location() == DataLocation::Storage)
+ id += "_storage";
+ else if (location() == DataLocation::Memory)
+ id += "_memory";
+ else
+ id += "_calldata";
+ if (isPointer())
+ id += "_ptr";
+ return id;
+}
+
bool ArrayType::isImplicitlyConvertibleTo(const Type& _convertTo) const
{
if (_convertTo.category() != category())
@@ -1170,6 +1214,26 @@ bool ArrayType::isExplicitlyConvertibleTo(const Type& _convertTo) const
return true;
}
+string ArrayType::identifier() const
+{
+ string id;
+ if (isString())
+ id += "t_string";
+ else if (isByteArray())
+ id += "t_bytes";
+ else
+ {
+ id = baseType()->identifier();
+ if (isDynamicallySized())
+ id += "_arraydyn";
+ else
+ id += string("_array") + length().str();
+ }
+ id += identifierLocationSuffix();
+
+ return id;
+}
+
bool ArrayType::operator==(Type const& _other) const
{
if (_other.category() != category())
@@ -1184,7 +1248,7 @@ bool ArrayType::operator==(Type const& _other) const
return false;
if (*other.baseType() != *baseType())
return false;
- return isDynamicallySized() || length() == other.length();
+ return isDynamicallySized() || length() == other.length();
}
unsigned ArrayType::calldataEncodedSize(bool _padded) const
@@ -1356,6 +1420,11 @@ TypePointer ArrayType::copyForLocation(DataLocation _location, bool _isPointer)
return copy;
}
+string ContractType::identifier() const
+{
+ return (m_super ? "t_super_" : "t_contract_") + m_contract.name() + "_" + std::to_string(m_contract.id());
+}
+
bool ContractType::operator==(Type const& _other) const
{
if (_other.category() != category())
@@ -1465,6 +1534,11 @@ bool StructType::isImplicitlyConvertibleTo(const Type& _convertTo) const
return this->m_struct == convertTo.m_struct;
}
+string StructType::identifier() const
+{
+ return "t_struct_" + m_struct.name() + "_" + std::to_string(m_struct.id()) + identifierLocationSuffix();
+}
+
bool StructType::operator==(Type const& _other) const
{
if (_other.category() != category())
@@ -1605,6 +1679,11 @@ TypePointer EnumType::unaryOperatorResult(Token::Value _operator) const
return _operator == Token::Delete ? make_shared<TupleType>() : TypePointer();
}
+string EnumType::identifier() const
+{
+ return "t_enum_" + m_enum.name() + "_" + std::to_string(m_enum.id());
+}
+
bool EnumType::operator==(Type const& _other) const
{
if (_other.category() != category())
@@ -1686,6 +1765,18 @@ bool TupleType::isImplicitlyConvertibleTo(Type const& _other) const
return false;
}
+string TupleType::identifier() const
+{
+ string id = "t_tuple" + std::to_string(components().size()) + "_";
+ for (auto const& c: components())
+ if (c)
+ id += c->identifier() + "_";
+ else
+ id += "t_empty_";
+ id += "tuple_end";
+ return id;
+}
+
bool TupleType::operator==(Type const& _other) const
{
if (auto tupleType = dynamic_cast<TupleType const*>(&_other))
@@ -1934,6 +2025,59 @@ TypePointers FunctionType::parameterTypes() const
return TypePointers(m_parameterTypes.cbegin() + 1, m_parameterTypes.cend());
}
+string FunctionType::identifier() const
+{
+ string id = "t_function_";
+ switch (location())
+ {
+ case Location::Internal: id += "internal"; break;
+ case Location::External: id += "external"; break;
+ case Location::CallCode: id += "callcode"; break;
+ case Location::DelegateCall: id += "delegatecall"; break;
+ case Location::Bare: id += "bare"; break;
+ case Location::BareCallCode: id += "barecallcode"; break;
+ case Location::BareDelegateCall: id += "baredelegatecall"; break;
+ case Location::Creation: id += "creation"; break;
+ case Location::Send: id += "send"; break;
+ case Location::SHA3: id += "sha3"; break;
+ case Location::Selfdestruct: id += "selfdestruct"; break;
+ case Location::ECRecover: id += "ecrecover"; break;
+ case Location::SHA256: id += "sha256"; break;
+ case Location::RIPEMD160: id += "ripemd160"; break;
+ case Location::Log0: id += "log0"; break;
+ case Location::Log1: id += "log1"; break;
+ case Location::Log2: id += "log2"; break;
+ case Location::Log3: id += "log3"; break;
+ case Location::Log4: id += "log4"; break;
+ case Location::Event: id += "event"; break;
+ case Location::SetGas: id += "setgas"; break;
+ case Location::SetValue: id += "setvalue"; break;
+ case Location::BlockHash: id += "blockhash"; break;
+ case Location::AddMod: id += "addmod"; break;
+ case Location::MulMod: id += "mulmod"; break;
+ case Location::ArrayPush: id += "arraypush"; break;
+ case Location::ByteArrayPush: id += "bytearraypush"; break;
+ case Location::ObjectCreation: id += "objectcreation"; break;
+ default: solAssert(false, "Unknown function location."); break;
+ }
+ if (isConstant())
+ id += "_constant";
+ id += "_param" + std::to_string(m_parameterTypes.size()) + "_";
+ for (auto const& p: m_parameterTypes)
+ id += p->identifier() + "_";
+ id += "return" + std::to_string(m_returnParameterTypes.size()) + "_";
+ for (auto const& r: m_returnParameterTypes)
+ id += r->identifier() + "_";
+ if (m_gasSet)
+ id += "gas_set_";
+ if (m_valueSet)
+ id += "value_set_";
+ if (bound())
+ id += "bound_to" + selfType()->identifier() + "_";
+ id += "function_end";
+ return id;
+}
+
bool FunctionType::operator==(Type const& _other) const
{
if (_other.category() != category())
@@ -2354,6 +2498,11 @@ ASTPointer<ASTString> FunctionType::documentation() const
return ASTPointer<ASTString>();
}
+string MappingType::identifier() const
+{
+ return "t_mapping_" + m_keyType->identifier() + "_to_" + m_valueType->identifier() + "_mapping_end";
+}
+
bool MappingType::operator==(Type const& _other) const
{
if (_other.category() != category())
@@ -2372,6 +2521,11 @@ string MappingType::canonicalName(bool) const
return "mapping(" + keyType()->canonicalName(false) + " => " + valueType()->canonicalName(false) + ")";
}
+string TypeType::identifier() const
+{
+ return "t_type_" + actualType()->identifier();
+}
+
bool TypeType::operator==(Type const& _other) const
{
if (_other.category() != category())
@@ -2456,6 +2610,14 @@ u256 ModifierType::storageSize() const
<< errinfo_comment("Storage size of non-storable type type requested."));
}
+string ModifierType::identifier() const
+{
+ string id = "t_modifier_param" + std::to_string(m_parameterTypes.size()) + "_";
+ for (auto const& p: m_parameterTypes)
+ id += p->identifier() + "_";
+ return id + "end_modifier";
+}
+
bool ModifierType::operator==(Type const& _other) const
{
if (_other.category() != category())
@@ -2480,6 +2642,11 @@ string ModifierType::toString(bool _short) const
return name + ")";
}
+string ModuleType::identifier() const
+{
+ return "t_module_" + std::to_string(m_sourceUnit.id());
+}
+
bool ModuleType::operator==(Type const& _other) const
{
if (_other.category() != category())
@@ -2501,6 +2668,22 @@ string ModuleType::toString(bool) const
return string("module \"") + m_sourceUnit.annotation().path + string("\"");
}
+string MagicType::identifier() const
+{
+ switch (m_kind)
+ {
+ case Kind::Block:
+ return "t_magic_block";
+ case Kind::Message:
+ return "t_magic_message";
+ case Kind::Transaction:
+ return "t_magic_transaction";
+ default:
+ solAssert(false, "Unknown kind of magic");
+ }
+ return "";
+}
+
bool MagicType::operator==(Type const& _other) const
{
if (_other.category() != category())
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index 26e2b8f2..c1f6a476 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -155,6 +155,10 @@ public:
static TypePointer commonType(TypePointer const& _a, TypePointer const& _b);
virtual Category category() const = 0;
+ /// @returns a valid solidity identifier such that two types should compare equal if and
+ /// only if they have the same identifier.
+ /// The identifier should start with "t_".
+ virtual std::string identifier() const = 0;
virtual bool isImplicitlyConvertibleTo(Type const& _other) const { return *this == _other; }
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const
{
@@ -288,6 +292,7 @@ public:
explicit IntegerType(int _bits, Modifier _modifier = Modifier::Unsigned);
+ virtual std::string identifier() const override;
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
@@ -329,6 +334,7 @@ public:
explicit FixedPointType(int _integerBits, int _fractionalBits, Modifier _modifier = Modifier::Unsigned);
+ virtual std::string identifier() const override;
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
@@ -378,6 +384,7 @@ public:
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual bool canBeStored() const override { return false; }
@@ -416,6 +423,7 @@ public:
return TypePointer();
}
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual bool canBeStored() const override { return false; }
@@ -449,6 +457,7 @@ public:
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
@@ -476,6 +485,7 @@ class BoolType: public Type
public:
BoolType() {}
virtual Category category() const override { return Category::Bool; }
+ virtual std::string identifier() const override { return "t_bool"; }
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
virtual TypePointer binaryOperatorResult(Token::Value _operator, TypePointer const& _other) const override;
@@ -533,6 +543,8 @@ protected:
TypePointer copyForLocationIfReference(TypePointer const& _type) const;
/// @returns a human-readable description of the reference part of the type.
std::string stringForReferencePart() const;
+ /// @returns the suffix computed from the reference part to be used by identifier();
+ std::string identifierLocationSuffix() const;
DataLocation m_location = DataLocation::Storage;
bool m_isPointer = true;
@@ -573,6 +585,7 @@ public:
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
+ virtual std::string identifier() const override;
virtual bool operator==(const Type& _other) const override;
virtual unsigned calldataEncodedSize(bool _padded) const override;
virtual bool isDynamicallySized() const override { return m_hasDynamicLength; }
@@ -622,6 +635,7 @@ public:
/// Contracts can be converted to themselves and to integers.
virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual unsigned calldataEncodedSize(bool _padded ) const override
{
@@ -677,6 +691,7 @@ public:
explicit StructType(StructDefinition const& _struct, DataLocation _location = DataLocation::Storage):
ReferenceType(_location), m_struct(_struct) {}
virtual bool isImplicitlyConvertibleTo(const Type& _convertTo) const override;
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual unsigned calldataEncodedSize(bool _padded) const override;
u256 memorySize() const;
@@ -720,6 +735,7 @@ public:
virtual Category category() const override { return Category::Enum; }
explicit EnumType(EnumDefinition const& _enum): m_enum(_enum) {}
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual unsigned calldataEncodedSize(bool _padded) const override
{
@@ -760,6 +776,7 @@ public:
virtual Category category() const override { return Category::Tuple; }
explicit TupleType(std::vector<TypePointer> const& _types = std::vector<TypePointer>()): m_components(_types) {}
virtual bool isImplicitlyConvertibleTo(Type const& _other) const override;
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
virtual std::string toString(bool) const override;
@@ -897,6 +914,7 @@ public:
/// @returns the "self" parameter type for a bound function
TypePointer selfType() const;
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
virtual std::string canonicalName(bool /*_addDataLocation*/) const override;
@@ -995,6 +1013,7 @@ public:
MappingType(TypePointer const& _keyType, TypePointer const& _valueType):
m_keyType(_keyType), m_valueType(_valueType) {}
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual std::string toString(bool _short) const override;
virtual std::string canonicalName(bool _addDataLocation) const override;
@@ -1029,6 +1048,7 @@ public:
TypePointer const& actualType() const { return m_actualType; }
virtual TypePointer binaryOperatorResult(Token::Value, TypePointer const&) const override { return TypePointer(); }
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual bool canBeStored() const override { return false; }
virtual u256 storageSize() const override;
@@ -1056,6 +1076,7 @@ public:
virtual u256 storageSize() const override;
virtual bool canLiveOutsideStorage() const override { return false; }
virtual unsigned sizeOnStack() const override { return 0; }
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual std::string toString(bool _short) const override;
@@ -1080,6 +1101,7 @@ public:
return TypePointer();
}
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual bool canBeStored() const override { return false; }
virtual bool canLiveOutsideStorage() const override { return true; }
@@ -1109,6 +1131,7 @@ public:
return TypePointer();
}
+ virtual std::string identifier() const override;
virtual bool operator==(Type const& _other) const override;
virtual bool canBeStored() const override { return false; }
virtual bool canLiveOutsideStorage() const override { return true; }
@@ -1132,6 +1155,7 @@ class InaccessibleDynamicType: public Type
public:
virtual Category category() const override { return Category::InaccessibleDynamic; }
+ virtual std::string identifier() const override { return "t_inaccessible"; }
virtual bool isImplicitlyConvertibleTo(Type const&) const override { return false; }
virtual bool isExplicitlyConvertibleTo(Type const&) const override { return false; }
virtual unsigned calldataEncodedSize(bool _padded) const override { (void)_padded; return 32; }
diff --git a/test/libsolidity/SolidityTypes.cpp b/test/libsolidity/SolidityTypes.cpp
index dc3143c8..1e7bcc7b 100644
--- a/test/libsolidity/SolidityTypes.cpp
+++ b/test/libsolidity/SolidityTypes.cpp
@@ -21,6 +21,8 @@
*/
#include <libsolidity/ast/Types.h>
+#include <libsolidity/ast/AST.h>
+#include <libdevcore/SHA3.h>
#include <boost/test/unit_test.hpp>
using namespace std;
@@ -86,6 +88,70 @@ BOOST_AUTO_TEST_CASE(storage_layout_arrays)
BOOST_CHECK(ArrayType(DataLocation::Storage, make_shared<FixedBytesType>(32), 9).storageSize() == 9);
}
+BOOST_AUTO_TEST_CASE(type_identifiers)
+{
+ BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("uint128")->identifier(), "t_uint128");
+ BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("int128")->identifier(), "t_int128");
+ BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("address")->identifier(), "t_address");
+ BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("uint8")->identifier(), "t_uint8");
+ BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("ufixed8x64")->identifier(), "t_ufixed8x64");
+ BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("fixed128x8")->identifier(), "t_fixed128x8");
+ BOOST_CHECK_EQUAL(RationalNumberType(rational(7, 1)).identifier(), "t_rational_7_by_1");
+ BOOST_CHECK_EQUAL(RationalNumberType(rational(200, 77)).identifier(), "t_rational_200_by_77");
+ BOOST_CHECK_EQUAL(RationalNumberType(rational(2 * 200, 2 * 77)).identifier(), "t_rational_200_by_77");
+ BOOST_CHECK_EQUAL(
+ StringLiteralType(Literal(SourceLocation{}, Token::StringLiteral, make_shared<string>("abc - def"))).identifier(),
+ "t_stringliteral_196a9142ee0d40e274a6482393c762b16dd8315713207365e1e13d8d85b74fc4"
+ );
+ BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("bytes8")->identifier(), "t_bytes8");
+ BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("bytes32")->identifier(), "t_bytes32");
+ BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("bool")->identifier(), "t_bool");
+ BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("bytes")->identifier(), "t_bytes_storage_ptr");
+ BOOST_CHECK_EQUAL(Type::fromElementaryTypeName("string")->identifier(), "t_string_storage_ptr");
+ ArrayType largeintArray(DataLocation::Memory, Type::fromElementaryTypeName("int128"), u256("2535301200456458802993406410752"));
+ BOOST_CHECK_EQUAL(largeintArray.identifier(), "t_int128_array2535301200456458802993406410752_memory_ptr");
+ TypePointer stringArray = make_shared<ArrayType>(DataLocation::Storage, Type::fromElementaryTypeName("string"), u256("20"));
+ TypePointer multiArray = make_shared<ArrayType>(DataLocation::Storage, stringArray);
+ BOOST_CHECK_EQUAL(multiArray->identifier(), "t_string_storage_array20_storage_arraydyn_storage_ptr");
+
+ ContractDefinition c(SourceLocation{}, make_shared<string>("MyContract"), {}, {}, {}, false);
+ BOOST_CHECK_EQUAL(c.type()->identifier(), "t_type_t_contract_MyContract_2");
+ BOOST_CHECK_EQUAL(ContractType(c, true).identifier(), "t_super_MyContract_2");
+
+ StructDefinition s({}, make_shared<string>("Struct"), {});
+ BOOST_CHECK_EQUAL(s.type()->identifier(), "t_type_t_struct_Struct_3_storage_ptr");
+
+ EnumDefinition e({}, make_shared<string>("Enum"), {});
+ BOOST_CHECK_EQUAL(e.type()->identifier(), "t_type_t_enum_Enum_4");
+
+ TupleType t({e.type(), s.type(), stringArray, nullptr});
+ BOOST_CHECK_EQUAL(t.identifier(), "t_tuple4_t_type_t_enum_Enum_4_t_type_t_struct_Struct_3_storage_ptr_t_string_storage_array20_storage_ptr_t_empty_tuple_end");
+
+ TypePointer sha3fun = make_shared<FunctionType>(strings{}, strings{}, FunctionType::Location::SHA3);
+ BOOST_CHECK_EQUAL(sha3fun->identifier(), "t_function_sha3_param0_return0_function_end");
+
+ FunctionType metaFun(TypePointers{sha3fun}, TypePointers{s.type()});
+ BOOST_CHECK_EQUAL(metaFun.identifier(), "t_function_internal_param1_t_function_sha3_param0_return0_function_end_return1_t_type_t_struct_Struct_3_storage_ptr_function_end");
+
+ TypePointer m = make_shared<MappingType>(Type::fromElementaryTypeName("bytes32"), s.type());
+ MappingType m2(Type::fromElementaryTypeName("uint64"), m);
+ BOOST_CHECK_EQUAL(m2.identifier(), "t_mapping_t_uint64_to_t_mapping_t_bytes32_to_t_type_t_struct_Struct_3_storage_ptr_mapping_end_mapping_end");
+
+ // TypeType is tested with contract
+
+ auto emptyParams = make_shared<ParameterList>(SourceLocation(), std::vector<ASTPointer<VariableDeclaration>>());
+ ModifierDefinition mod(SourceLocation{}, make_shared<string>("modif"), {}, emptyParams, {});
+ BOOST_CHECK_EQUAL(ModifierType(mod).identifier(), "t_modifier_param0_end_modifier");
+
+ SourceUnit su({}, {});
+ BOOST_CHECK_EQUAL(ModuleType(su).identifier(), "t_module_7");
+ BOOST_CHECK_EQUAL(MagicType(MagicType::Kind::Block).identifier(), "t_magic_block");
+ BOOST_CHECK_EQUAL(MagicType(MagicType::Kind::Message).identifier(), "t_magic_message");
+ BOOST_CHECK_EQUAL(MagicType(MagicType::Kind::Transaction).identifier(), "t_magic_transaction");
+
+ BOOST_CHECK_EQUAL(InaccessibleDynamicType().identifier(), "t_inaccessible");
+}
+
BOOST_AUTO_TEST_SUITE_END()
}