aboutsummaryrefslogtreecommitdiffstats
path: root/libsolidity/ast
diff options
context:
space:
mode:
Diffstat (limited to 'libsolidity/ast')
-rw-r--r--libsolidity/ast/AST.cpp8
-rw-r--r--libsolidity/ast/AST.h56
-rw-r--r--libsolidity/ast/ASTForward.h1
-rw-r--r--libsolidity/ast/ASTJsonConverter.cpp28
-rw-r--r--libsolidity/ast/ASTJsonConverter.h2
-rw-r--r--libsolidity/ast/ASTPrinter.cpp14
-rw-r--r--libsolidity/ast/ASTPrinter.h2
-rw-r--r--libsolidity/ast/ASTVisitor.h4
-rw-r--r--libsolidity/ast/AST_accept.h20
-rw-r--r--libsolidity/ast/Types.cpp149
-rw-r--r--libsolidity/ast/Types.h18
11 files changed, 269 insertions, 33 deletions
diff --git a/libsolidity/ast/AST.cpp b/libsolidity/ast/AST.cpp
index 695d9881..305668e7 100644
--- a/libsolidity/ast/AST.cpp
+++ b/libsolidity/ast/AST.cpp
@@ -160,22 +160,22 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::inter
return *m_interfaceFunctionList;
}
-string const& ContractDefinition::devDocumentation() const
+Json::Value const& ContractDefinition::devDocumentation() const
{
return m_devDocumentation;
}
-string const& ContractDefinition::userDocumentation() const
+Json::Value const& ContractDefinition::userDocumentation() const
{
return m_userDocumentation;
}
-void ContractDefinition::setDevDocumentation(string const& _devDocumentation)
+void ContractDefinition::setDevDocumentation(Json::Value const& _devDocumentation)
{
m_devDocumentation = _devDocumentation;
}
-void ContractDefinition::setUserDocumentation(string const& _userDocumentation)
+void ContractDefinition::setUserDocumentation(Json::Value const& _userDocumentation)
{
m_userDocumentation = _userDocumentation;
}
diff --git a/libsolidity/ast/AST.h b/libsolidity/ast/AST.h
index 7ed4ddce..a2b70fe9 100644
--- a/libsolidity/ast/AST.h
+++ b/libsolidity/ast/AST.h
@@ -35,6 +35,7 @@
#include <libsolidity/ast/Types.h>
#include <libsolidity/interface/Exceptions.h>
#include <libsolidity/ast/ASTAnnotations.h>
+#include <json/json.h>
namespace dev
{
@@ -343,11 +344,11 @@ public:
/// Returns the fallback function or nullptr if no fallback function was specified.
FunctionDefinition const* fallbackFunction() const;
- std::string const& userDocumentation() const;
- void setUserDocumentation(std::string const& _userDocumentation);
+ Json::Value const& userDocumentation() const;
+ void setUserDocumentation(Json::Value const& _userDocumentation);
- std::string const& devDocumentation() const;
- void setDevDocumentation(std::string const& _devDocumentation);
+ Json::Value const& devDocumentation() const;
+ void setDevDocumentation(Json::Value const& _devDocumentation);
virtual TypePointer type() const override;
@@ -359,8 +360,8 @@ private:
bool m_isLibrary;
// parsed Natspec documentation of the contract.
- std::string m_userDocumentation;
- std::string m_devDocumentation;
+ Json::Value m_userDocumentation;
+ Json::Value m_devDocumentation;
std::vector<ContractDefinition const*> m_linearizedBaseContracts;
mutable std::unique_ptr<std::vector<std::pair<FixedHash<4>, FunctionTypePointer>>> m_interfaceFunctionList;
@@ -822,6 +823,41 @@ private:
};
/**
+ * A literal function type. Its source form is "function (paramType1, paramType2) internal / external returns (retType1, retType2)"
+ */
+class FunctionTypeName: public TypeName
+{
+public:
+ FunctionTypeName(
+ SourceLocation const& _location,
+ ASTPointer<ParameterList> const& _parameterTypes,
+ ASTPointer<ParameterList> const& _returnTypes,
+ Declaration::Visibility _visibility,
+ bool _isDeclaredConst,
+ bool _isPayable
+ ):
+ TypeName(_location), m_parameterTypes(_parameterTypes), m_returnTypes(_returnTypes),
+ m_visibility(_visibility), m_isDeclaredConst(_isDeclaredConst), m_isPayable(_isPayable)
+ {}
+ virtual void accept(ASTVisitor& _visitor) override;
+ virtual void accept(ASTConstVisitor& _visitor) const override;
+
+ std::vector<ASTPointer<VariableDeclaration>> const& parameterTypes() const { return m_parameterTypes->parameters(); }
+ std::vector<ASTPointer<VariableDeclaration>> const& returnParameterTypes() const { return m_returnTypes->parameters(); }
+
+ Declaration::Visibility visibility() const { return m_visibility; }
+ bool isDeclaredConst() const { return m_isDeclaredConst; }
+ bool isPayable() const { return m_isPayable; }
+
+private:
+ ASTPointer<ParameterList> m_parameterTypes;
+ ASTPointer<ParameterList> m_returnTypes;
+ Declaration::Visibility m_visibility;
+ bool m_isDeclaredConst;
+ bool m_isPayable;
+};
+
+/**
* A mapping type. Its source form is "mapping('keyType' => 'valueType')"
*/
class Mapping: public TypeName
@@ -1005,18 +1041,22 @@ public:
SourceLocation const& _location,
ASTPointer<ASTString> const& _docString,
ASTPointer<Expression> const& _condition,
- ASTPointer<Statement> const& _body
+ ASTPointer<Statement> const& _body,
+ bool _isDoWhile
):
- BreakableStatement(_location, _docString), m_condition(_condition), m_body(_body) {}
+ BreakableStatement(_location, _docString), m_condition(_condition), m_body(_body),
+ m_isDoWhile(_isDoWhile) {}
virtual void accept(ASTVisitor& _visitor) override;
virtual void accept(ASTConstVisitor& _visitor) const override;
Expression const& condition() const { return *m_condition; }
Statement const& body() const { return *m_body; }
+ bool isDoWhile() const { return m_isDoWhile; }
private:
ASTPointer<Expression> m_condition;
ASTPointer<Statement> m_body;
+ bool m_isDoWhile;
};
/**
diff --git a/libsolidity/ast/ASTForward.h b/libsolidity/ast/ASTForward.h
index 59fc1b57..52bbf396 100644
--- a/libsolidity/ast/ASTForward.h
+++ b/libsolidity/ast/ASTForward.h
@@ -54,6 +54,7 @@ class MagicVariableDeclaration;
class TypeName;
class ElementaryTypeName;
class UserDefinedTypeName;
+class FunctionTypeName;
class Mapping;
class ArrayTypeName;
class Statement;
diff --git a/libsolidity/ast/ASTJsonConverter.cpp b/libsolidity/ast/ASTJsonConverter.cpp
index 0ea5e093..37dfd3c6 100644
--- a/libsolidity/ast/ASTJsonConverter.cpp
+++ b/libsolidity/ast/ASTJsonConverter.cpp
@@ -174,7 +174,8 @@ bool ASTJsonConverter::visit(FunctionDefinition const& _node)
addJsonNode(_node, "FunctionDefinition", {
make_pair("name", _node.name()),
make_pair("public", _node.isPublic()),
- make_pair("constant", _node.isDeclaredConst())
+ make_pair("constant", _node.isDeclaredConst()),
+ make_pair("payable", _node.isPayable())
}, true);
return true;
}
@@ -225,6 +226,20 @@ bool ASTJsonConverter::visit(UserDefinedTypeName const& _node)
return true;
}
+bool ASTJsonConverter::visit(FunctionTypeName const& _node)
+{
+ string visibility = "internal";
+ if (_node.visibility() == Declaration::Visibility::External)
+ visibility = "external";
+
+ addJsonNode(_node, "FunctionTypeName", {
+ make_pair("payable", _node.isPayable()),
+ make_pair("visibility", visibility),
+ make_pair("constant", _node.isDeclaredConst())
+ }, true);
+ return true;
+}
+
bool ASTJsonConverter::visit(Mapping const& _node)
{
addJsonNode(_node, "Mapping", {}, true);
@@ -263,7 +278,11 @@ bool ASTJsonConverter::visit(IfStatement const& _node)
bool ASTJsonConverter::visit(WhileStatement const& _node)
{
- addJsonNode(_node, "WhileStatement", {}, true);
+ addJsonNode(
+ _node,
+ _node.isDoWhile() ? "DoWhileStatement" : "WhileStatement",
+ {},
+ true);
return true;
}
@@ -502,6 +521,11 @@ void ASTJsonConverter::endVisit(UserDefinedTypeName const&)
{
}
+void ASTJsonConverter::endVisit(FunctionTypeName const&)
+{
+ goUp();
+}
+
void ASTJsonConverter::endVisit(Mapping const&)
{
goUp();
diff --git a/libsolidity/ast/ASTJsonConverter.h b/libsolidity/ast/ASTJsonConverter.h
index 7c7b37f8..0a71779c 100644
--- a/libsolidity/ast/ASTJsonConverter.h
+++ b/libsolidity/ast/ASTJsonConverter.h
@@ -69,6 +69,7 @@ public:
bool visit(TypeName const& _node) override;
bool visit(ElementaryTypeName const& _node) override;
bool visit(UserDefinedTypeName const& _node) override;
+ bool visit(FunctionTypeName const& _node) override;
bool visit(Mapping const& _node) override;
bool visit(ArrayTypeName const& _node) override;
bool visit(InlineAssembly const& _node) override;
@@ -114,6 +115,7 @@ public:
void endVisit(TypeName const&) override;
void endVisit(ElementaryTypeName const&) override;
void endVisit(UserDefinedTypeName const&) override;
+ void endVisit(FunctionTypeName const&) override;
void endVisit(Mapping const&) override;
void endVisit(ArrayTypeName const&) override;
void endVisit(InlineAssembly const&) override;
diff --git a/libsolidity/ast/ASTPrinter.cpp b/libsolidity/ast/ASTPrinter.cpp
index a9de457a..053b9b82 100644
--- a/libsolidity/ast/ASTPrinter.cpp
+++ b/libsolidity/ast/ASTPrinter.cpp
@@ -164,6 +164,13 @@ bool ASTPrinter::visit(UserDefinedTypeName const& _node)
return goDeeper();
}
+bool ASTPrinter::visit(FunctionTypeName const& _node)
+{
+ writeLine("FunctionTypeName");
+ printSourcePart(_node);
+ return goDeeper();
+}
+
bool ASTPrinter::visit(Mapping const& _node)
{
writeLine("Mapping");
@@ -208,7 +215,7 @@ bool ASTPrinter::visit(IfStatement const& _node)
bool ASTPrinter::visit(WhileStatement const& _node)
{
- writeLine("WhileStatement");
+ writeLine(_node.isDoWhile() ? "DoWhileStatement" : "WhileStatement");
printSourcePart(_node);
return goDeeper();
}
@@ -442,6 +449,11 @@ void ASTPrinter::endVisit(UserDefinedTypeName const&)
m_indentation--;
}
+void ASTPrinter::endVisit(FunctionTypeName const&)
+{
+ m_indentation--;
+}
+
void ASTPrinter::endVisit(Mapping const&)
{
m_indentation--;
diff --git a/libsolidity/ast/ASTPrinter.h b/libsolidity/ast/ASTPrinter.h
index f0ab1098..9f88a1fd 100644
--- a/libsolidity/ast/ASTPrinter.h
+++ b/libsolidity/ast/ASTPrinter.h
@@ -63,6 +63,7 @@ public:
bool visit(TypeName const& _node) override;
bool visit(ElementaryTypeName const& _node) override;
bool visit(UserDefinedTypeName const& _node) override;
+ bool visit(FunctionTypeName const& _node) override;
bool visit(Mapping const& _node) override;
bool visit(ArrayTypeName const& _node) override;
bool visit(InlineAssembly const& _node) override;
@@ -106,6 +107,7 @@ public:
void endVisit(TypeName const&) override;
void endVisit(ElementaryTypeName const&) override;
void endVisit(UserDefinedTypeName const&) override;
+ void endVisit(FunctionTypeName const&) override;
void endVisit(Mapping const&) override;
void endVisit(ArrayTypeName const&) override;
void endVisit(InlineAssembly const&) override;
diff --git a/libsolidity/ast/ASTVisitor.h b/libsolidity/ast/ASTVisitor.h
index 3a1b55d3..e72afe69 100644
--- a/libsolidity/ast/ASTVisitor.h
+++ b/libsolidity/ast/ASTVisitor.h
@@ -61,6 +61,7 @@ public:
virtual bool visit(TypeName& _node) { return visitNode(_node); }
virtual bool visit(ElementaryTypeName& _node) { return visitNode(_node); }
virtual bool visit(UserDefinedTypeName& _node) { return visitNode(_node); }
+ virtual bool visit(FunctionTypeName& _node) { return visitNode(_node); }
virtual bool visit(Mapping& _node) { return visitNode(_node); }
virtual bool visit(ArrayTypeName& _node) { return visitNode(_node); }
virtual bool visit(InlineAssembly& _node) { return visitNode(_node); }
@@ -106,6 +107,7 @@ public:
virtual void endVisit(TypeName& _node) { endVisitNode(_node); }
virtual void endVisit(ElementaryTypeName& _node) { endVisitNode(_node); }
virtual void endVisit(UserDefinedTypeName& _node) { endVisitNode(_node); }
+ virtual void endVisit(FunctionTypeName& _node) { endVisitNode(_node); }
virtual void endVisit(Mapping& _node) { endVisitNode(_node); }
virtual void endVisit(ArrayTypeName& _node) { endVisitNode(_node); }
virtual void endVisit(InlineAssembly& _node) { endVisitNode(_node); }
@@ -163,6 +165,7 @@ public:
virtual bool visit(TypeName const& _node) { return visitNode(_node); }
virtual bool visit(ElementaryTypeName const& _node) { return visitNode(_node); }
virtual bool visit(UserDefinedTypeName const& _node) { return visitNode(_node); }
+ virtual bool visit(FunctionTypeName const& _node) { return visitNode(_node); }
virtual bool visit(Mapping const& _node) { return visitNode(_node); }
virtual bool visit(ArrayTypeName const& _node) { return visitNode(_node); }
virtual bool visit(Block const& _node) { return visitNode(_node); }
@@ -208,6 +211,7 @@ public:
virtual void endVisit(TypeName const& _node) { endVisitNode(_node); }
virtual void endVisit(ElementaryTypeName const& _node) { endVisitNode(_node); }
virtual void endVisit(UserDefinedTypeName const& _node) { endVisitNode(_node); }
+ virtual void endVisit(FunctionTypeName const& _node) { endVisitNode(_node); }
virtual void endVisit(Mapping const& _node) { endVisitNode(_node); }
virtual void endVisit(ArrayTypeName const& _node) { endVisitNode(_node); }
virtual void endVisit(Block const& _node) { endVisitNode(_node); }
diff --git a/libsolidity/ast/AST_accept.h b/libsolidity/ast/AST_accept.h
index b5a3806b..f521e092 100644
--- a/libsolidity/ast/AST_accept.h
+++ b/libsolidity/ast/AST_accept.h
@@ -327,6 +327,26 @@ void UserDefinedTypeName::accept(ASTConstVisitor& _visitor) const
_visitor.endVisit(*this);
}
+void FunctionTypeName::accept(ASTVisitor& _visitor)
+{
+ if (_visitor.visit(*this))
+ {
+ m_parameterTypes->accept(_visitor);
+ m_returnTypes->accept(_visitor);
+ }
+ _visitor.endVisit(*this);
+}
+
+void FunctionTypeName::accept(ASTConstVisitor& _visitor) const
+{
+ if (_visitor.visit(*this))
+ {
+ m_parameterTypes->accept(_visitor);
+ m_returnTypes->accept(_visitor);
+ }
+ _visitor.endVisit(*this);
+}
+
void Mapping::accept(ASTVisitor& _visitor)
{
if (_visitor.visit(*this))
diff --git a/libsolidity/ast/Types.cpp b/libsolidity/ast/Types.cpp
index 7fe97fa7..4488398f 100644
--- a/libsolidity/ast/Types.cpp
+++ b/libsolidity/ast/Types.cpp
@@ -200,10 +200,10 @@ TypePointer Type::commonType(TypePointer const& _a, TypePointer const& _b)
{
if (!_a || !_b)
return TypePointer();
- else if (_b->isImplicitlyConvertibleTo(*_a))
- return _a;
- else if (_a->isImplicitlyConvertibleTo(*_b))
- return _b;
+ else if (_b->isImplicitlyConvertibleTo(*_a->mobileType()))
+ return _a->mobileType();
+ else if (_a->isImplicitlyConvertibleTo(*_b->mobileType()))
+ return _b->mobileType();
else
return TypePointer();
}
@@ -1265,6 +1265,7 @@ TypePointer ArrayType::decodingType() const
TypePointer ArrayType::interfaceType(bool _inLibrary) const
{
+ // Note: This has to fulfill canBeUsedExternally(_inLibrary) == !!interfaceType(_inLibrary)
if (_inLibrary && location() == DataLocation::Storage)
return shared_from_this();
@@ -1282,6 +1283,21 @@ TypePointer ArrayType::interfaceType(bool _inLibrary) const
return make_shared<ArrayType>(DataLocation::Memory, baseExt, m_length);
}
+bool ArrayType::canBeUsedExternally(bool _inLibrary) const
+{
+ // Note: This has to fulfill canBeUsedExternally(_inLibrary) == !!interfaceType(_inLibrary)
+ if (_inLibrary && location() == DataLocation::Storage)
+ return true;
+ else if (m_arrayKind != ArrayKind::Ordinary)
+ return true;
+ else if (!m_baseType->canBeUsedExternally(_inLibrary))
+ return false;
+ else if (m_baseType->category() == Category::Array && m_baseType->isDynamicallySized())
+ return false;
+ else
+ return true;
+}
+
u256 ArrayType::memorySize() const
{
solAssert(!isDynamicallySized(), "");
@@ -1451,7 +1467,7 @@ u256 StructType::storageSize() const
string StructType::toString(bool _short) const
{
- string ret = "struct " + m_struct.name();
+ string ret = "struct " + m_struct.annotation().canonicalName;
if (!_short)
ret += " " + stringForReferencePart();
return ret;
@@ -1561,7 +1577,7 @@ bool EnumType::operator==(Type const& _other) const
unsigned EnumType::storageBytes() const
{
- size_t elements = m_enum.members().size();
+ size_t elements = numberOfMembers();
if (elements <= 1)
return 1;
else
@@ -1570,7 +1586,7 @@ unsigned EnumType::storageBytes() const
string EnumType::toString(bool) const
{
- return string("enum ") + m_enum.name();
+ return string("enum ") + m_enum.annotation().canonicalName;
}
string EnumType::canonicalName(bool) const
@@ -1578,9 +1594,14 @@ string EnumType::canonicalName(bool) const
return m_enum.annotation().canonicalName;
}
+size_t EnumType::numberOfMembers() const
+{
+ return m_enum.members().size();
+};
+
bool EnumType::isExplicitlyConvertibleTo(Type const& _convertTo) const
{
- return _convertTo.category() == category() || _convertTo.category() == Category::Integer;
+ return _convertTo == *this || _convertTo.category() == Category::Integer;
}
unsigned EnumType::memberValue(ASTString const& _member) const
@@ -1699,7 +1720,7 @@ TypePointer TupleType::closestTemporaryType(TypePointer const& _targetType) cons
FunctionType::FunctionType(FunctionDefinition const& _function, bool _isInternal):
m_location(_isInternal ? Location::Internal : Location::External),
m_isConstant(_function.isDeclaredConst()),
- m_isPayable(_function.isPayable()),
+ m_isPayable(_isInternal ? false : _function.isPayable()),
m_declaration(&_function)
{
TypePointers params;
@@ -1800,6 +1821,38 @@ FunctionType::FunctionType(EventDefinition const& _event):
swap(paramNames, m_parameterNames);
}
+FunctionType::FunctionType(FunctionTypeName const& _typeName):
+ m_location(_typeName.visibility() == VariableDeclaration::Visibility::External ? Location::External : Location::Internal),
+ m_isConstant(_typeName.isDeclaredConst()),
+ m_isPayable(_typeName.isPayable())
+{
+ if (_typeName.isPayable())
+ {
+ solAssert(m_location == Location::External, "Internal payable function type used.");
+ solAssert(!m_isConstant, "Payable constant function");
+ }
+ for (auto const& t: _typeName.parameterTypes())
+ {
+ solAssert(t->annotation().type, "Type not set for parameter.");
+ if (m_location == Location::External)
+ solAssert(
+ t->annotation().type->canBeUsedExternally(false),
+ "Internal type used as parameter for external function."
+ );
+ m_parameterTypes.push_back(t->annotation().type);
+ }
+ for (auto const& t: _typeName.returnParameterTypes())
+ {
+ solAssert(t->annotation().type, "Type not set for return parameter.");
+ if (m_location == Location::External)
+ solAssert(
+ t->annotation().type->canBeUsedExternally(false),
+ "Internal type used as return parameter for external function."
+ );
+ m_returnParameterTypes.push_back(t->annotation().type);
+ }
+}
+
FunctionTypePointer FunctionType::newExpressionType(ContractDefinition const& _contract)
{
FunctionDefinition const* constructor = _contract.constructor();
@@ -1875,22 +1928,69 @@ bool FunctionType::operator==(Type const& _other) const
return true;
}
+TypePointer FunctionType::unaryOperatorResult(Token::Value _operator) const
+{
+ if (_operator == Token::Value::Delete)
+ return make_shared<TupleType>();
+ return TypePointer();
+}
+
+string FunctionType::canonicalName(bool) const
+{
+ solAssert(m_location == Location::External, "");
+ return "function";
+}
+
string FunctionType::toString(bool _short) const
{
string name = "function (";
for (auto it = m_parameterTypes.begin(); it != m_parameterTypes.end(); ++it)
name += (*it)->toString(_short) + (it + 1 == m_parameterTypes.end() ? "" : ",");
- name += ") returns (";
- for (auto it = m_returnParameterTypes.begin(); it != m_returnParameterTypes.end(); ++it)
- name += (*it)->toString(_short) + (it + 1 == m_returnParameterTypes.end() ? "" : ",");
- return name + ")";
+ name += ")";
+ if (m_isConstant)
+ name += " constant";
+ if (m_isPayable)
+ name += " payable";
+ if (m_location == Location::External)
+ name += " external";
+ if (!m_returnParameterTypes.empty())
+ {
+ name += " returns (";
+ for (auto it = m_returnParameterTypes.begin(); it != m_returnParameterTypes.end(); ++it)
+ name += (*it)->toString(_short) + (it + 1 == m_returnParameterTypes.end() ? "" : ",");
+ name += ")";
+ }
+ return name;
+}
+
+unsigned FunctionType::calldataEncodedSize(bool _padded) const
+{
+ unsigned size = storageBytes();
+ if (_padded)
+ size = ((size + 31) / 32) * 32;
+ return size;
}
u256 FunctionType::storageSize() const
{
- BOOST_THROW_EXCEPTION(
- InternalCompilerError()
- << errinfo_comment("Storage size of non-storable function type requested."));
+ if (m_location == Location::External || m_location == Location::Internal)
+ return 1;
+ else
+ BOOST_THROW_EXCEPTION(
+ InternalCompilerError()
+ << errinfo_comment("Storage size of non-storable function type requested."));
+}
+
+unsigned FunctionType::storageBytes() const
+{
+ if (m_location == Location::External)
+ return 20 + 4;
+ else if (m_location == Location::Internal)
+ return 8; // it should really not be possible to create larger programs
+ else
+ BOOST_THROW_EXCEPTION(
+ InternalCompilerError()
+ << errinfo_comment("Storage size of non-storable function type requested."));
}
unsigned FunctionType::sizeOnStack() const
@@ -2013,6 +2113,23 @@ MemberList::MemberMap FunctionType::nativeMembers(ContractDefinition const*) con
}
}
+TypePointer FunctionType::encodingType() const
+{
+ // Only external functions can be encoded, internal functions cannot leave code boundaries.
+ if (m_location == Location::External)
+ return shared_from_this();
+ else
+ return TypePointer();
+}
+
+TypePointer FunctionType::interfaceType(bool /*_inLibrary*/) const
+{
+ if (m_location == Location::External)
+ return shared_from_this();
+ else
+ return TypePointer();
+}
+
bool FunctionType::canTakeArguments(TypePointers const& _argumentTypes, TypePointer const& _selfType) const
{
solAssert(!bound() || _selfType, "");
diff --git a/libsolidity/ast/Types.h b/libsolidity/ast/Types.h
index 3f94d11a..34fcfc82 100644
--- a/libsolidity/ast/Types.h
+++ b/libsolidity/ast/Types.h
@@ -254,6 +254,9 @@ public:
/// @param _inLibrary if set, returns types as used in a library, e.g. struct and contract types
/// are returned without modification.
virtual TypePointer interfaceType(bool /*_inLibrary*/) const { return TypePointer(); }
+ /// @returns true iff this type can be passed on via calls (to libraries if _inLibrary is true),
+ /// should be have identical to !!interfaceType(_inLibrary) but might do optimizations.
+ virtual bool canBeUsedExternally(bool _inLibrary) const { return !!interfaceType(_inLibrary); }
private:
/// @returns a member list containing all members added to this type by `using for` directives.
@@ -580,6 +583,7 @@ public:
virtual TypePointer encodingType() const override;
virtual TypePointer decodingType() const override;
virtual TypePointer interfaceType(bool _inLibrary) const override;
+ virtual bool canBeUsedExternally(bool _inLibrary) const override;
/// @returns true if this is a byte array or a string
bool isByteArray() const { return m_arrayKind != ArrayKind::Ordinary; }
@@ -738,6 +742,7 @@ public:
EnumDefinition const& enumDefinition() const { return m_enum; }
/// @returns the value that the string has in the Enum
unsigned int memberValue(ASTString const& _member) const;
+ size_t numberOfMembers() const;
private:
EnumDefinition const& m_enum;
@@ -820,6 +825,8 @@ public:
explicit FunctionType(VariableDeclaration const& _varDecl);
/// Creates the function type of an event.
explicit FunctionType(EventDefinition const& _event);
+ /// Creates the type of a function type name.
+ explicit FunctionType(FunctionTypeName const& _typeName);
/// Function type constructor to be used for a plain type (not derived from a declaration).
FunctionType(
strings const& _parameterTypes,
@@ -889,12 +896,19 @@ public:
TypePointer selfType() const;
virtual bool operator==(Type const& _other) const override;
+ virtual TypePointer unaryOperatorResult(Token::Value _operator) const override;
+ virtual std::string canonicalName(bool /*_addDataLocation*/) const override;
virtual std::string toString(bool _short) const override;
- virtual bool canBeStored() const override { return false; }
+ virtual unsigned calldataEncodedSize(bool _padded) const override;
+ virtual bool canBeStored() const override { return m_location == Location::Internal || m_location == Location::External; }
virtual u256 storageSize() const override;
- virtual bool canLiveOutsideStorage() const override { return false; }
+ virtual unsigned storageBytes() const override;
+ virtual bool isValueType() const override { return true; }
+ virtual bool canLiveOutsideStorage() const override { return m_location == Location::Internal || m_location == Location::External; }
virtual unsigned sizeOnStack() const override;
virtual MemberList::MemberMap nativeMembers(ContractDefinition const* _currentScope) const override;
+ virtual TypePointer encodingType() const override;
+ virtual TypePointer interfaceType(bool _inLibrary) const override;
/// @returns TypePointer of a new FunctionType object. All input/return parameters are an
/// appropriate external types (i.e. the interfaceType()s) of input/return parameters of