diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp index 6d5e89ce2..3201d60ff 100644 --- a/libsolidity/ast/AST.cpp +++ b/libsolidity/ast/AST.cpp @@ -335,6 +335,12 @@ TypeNameAnnotation& TypeName::annotation() const return initAnnotation(); } +Type const* UserDefinedValueTypeDefinition::type() const +{ + solAssert(m_underlyingType->annotation().type, ""); + return TypeProvider::typeType(TypeProvider::userDefinedValueType(*this)); +} + Type const* StructDefinition::type() const { solAssert(annotation().recursive.has_value(), "Requested struct type before DeclarationTypeChecker."); diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h index f02e93599..e1e5fc596 100644 --- a/libsolidity/ast/AST.h +++ b/libsolidity/ast/AST.h @@ -726,6 +726,37 @@ public: Type const* type() const override; }; +/** + * User defined value types, i.e., custom types, for example, `type MyInt is int`. Allows creating a + * zero cost abstraction over value type with stricter type requirements. + */ +class UserDefinedValueTypeDefinition: public Declaration +{ +public: + UserDefinedValueTypeDefinition( + int64_t _id, + SourceLocation const& _location, + ASTPointer _name, + SourceLocation _nameLocation, + ASTPointer _underlyingType + ): + Declaration(_id, _location, _name, std::move(_nameLocation), Visibility::Default), + m_underlyingType(std::move(_underlyingType)) + { + } + + void accept(ASTVisitor& _visitor) override; + void accept(ASTConstVisitor& _visitor) const override; + + Type const* type() const override; + + TypeName const* underlyingType() const { return m_underlyingType.get(); } + +private: + /// The name of the underlying type + ASTPointer m_underlyingType; +}; + /** * Parameter list, used as function parameter list, return list and for try and catch. * None of the parameters is allowed to contain mappings (not even recursively diff --git a/libsolidity/ast/ASTForward.h b/libsolidity/ast/ASTForward.h index 5b73eb3a3..79e6a4ecf 100644 --- a/libsolidity/ast/ASTForward.h +++ b/libsolidity/ast/ASTForward.h @@ -51,6 +51,7 @@ class UsingForDirective; class StructDefinition; class EnumDefinition; class EnumValue; +class UserDefinedValueTypeDefinition; class ParameterList; class FunctionDefinition; class VariableDeclaration; diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h index 398387b33..ef03e6339 100644 --- a/libsolidity/ast/ASTVisitor.h +++ b/libsolidity/ast/ASTVisitor.h @@ -61,6 +61,7 @@ public: virtual bool visit(IdentifierPath& _node) { return visitNode(_node); } virtual bool visit(InheritanceSpecifier& _node) { return visitNode(_node); } virtual bool visit(UsingForDirective& _node) { return visitNode(_node); } + virtual bool visit(UserDefinedValueTypeDefinition& _node) { return visitNode(_node); } virtual bool visit(StructDefinition& _node) { return visitNode(_node); } virtual bool visit(EnumDefinition& _node) { return visitNode(_node); } virtual bool visit(EnumValue& _node) { return visitNode(_node); } @@ -116,6 +117,7 @@ public: virtual void endVisit(IdentifierPath& _node) { endVisitNode(_node); } virtual void endVisit(InheritanceSpecifier& _node) { endVisitNode(_node); } virtual void endVisit(UsingForDirective& _node) { endVisitNode(_node); } + virtual void endVisit(UserDefinedValueTypeDefinition& _node) { endVisitNode(_node); } virtual void endVisit(StructDefinition& _node) { endVisitNode(_node); } virtual void endVisit(EnumDefinition& _node) { endVisitNode(_node); } virtual void endVisit(EnumValue& _node) { endVisitNode(_node); } @@ -194,6 +196,7 @@ public: virtual bool visit(InheritanceSpecifier const& _node) { return visitNode(_node); } virtual bool visit(StructDefinition const& _node) { return visitNode(_node); } virtual bool visit(UsingForDirective const& _node) { return visitNode(_node); } + virtual bool visit(UserDefinedValueTypeDefinition const& _node) { return visitNode(_node); } virtual bool visit(EnumDefinition const& _node) { return visitNode(_node); } virtual bool visit(EnumValue const& _node) { return visitNode(_node); } virtual bool visit(ParameterList const& _node) { return visitNode(_node); } @@ -248,6 +251,7 @@ public: virtual void endVisit(IdentifierPath const& _node) { endVisitNode(_node); } virtual void endVisit(InheritanceSpecifier const& _node) { endVisitNode(_node); } virtual void endVisit(UsingForDirective const& _node) { endVisitNode(_node); } + virtual void endVisit(UserDefinedValueTypeDefinition const& _node) { endVisitNode(_node); } virtual void endVisit(StructDefinition const& _node) { endVisitNode(_node); } virtual void endVisit(EnumDefinition const& _node) { endVisitNode(_node); } virtual void endVisit(EnumValue const& _node) { endVisitNode(_node); } diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h index 075e6fe5c..14ebfe621 100644 --- a/libsolidity/ast/AST_accept.h +++ b/libsolidity/ast/AST_accept.h @@ -164,6 +164,26 @@ void EnumValue::accept(ASTConstVisitor& _visitor) const _visitor.endVisit(*this); } +void UserDefinedValueTypeDefinition::accept(ASTConstVisitor& _visitor) const +{ + if (_visitor.visit(*this)) + { + if (m_underlyingType) + m_underlyingType->accept(_visitor); + } + _visitor.endVisit(*this); +} + +void UserDefinedValueTypeDefinition::accept(ASTVisitor& _visitor) +{ + if (_visitor.visit(*this)) + { + if (m_underlyingType) + m_underlyingType->accept(_visitor); + } + _visitor.endVisit(*this); +} + void UsingForDirective::accept(ASTVisitor& _visitor) { if (_visitor.visit(*this))