aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian <c@ethdev.com>2014-11-21 01:33:23 +0800
committerChristian <c@ethdev.com>2014-11-24 04:28:44 +0800
commitc50cd646ce3b8b6c20da747efee89f9420526cae (patch)
treea6ebf3a1fe6088d9b8c5e3d4f36caa09bfd3fdd7
parentfa987e0a206bba35cfe6e311f8bad1470d9b5d4f (diff)
downloaddexon-solidity-c50cd646ce3b8b6c20da747efee89f9420526cae.tar.gz
dexon-solidity-c50cd646ce3b8b6c20da747efee89f9420526cae.tar.zst
dexon-solidity-c50cd646ce3b8b6c20da747efee89f9420526cae.zip
Contracts as types and framework for special global variables.
-rw-r--r--AST.cpp36
-rw-r--r--AST.h20
-rw-r--r--CompilerStack.cpp5
-rw-r--r--CompilerStack.h9
-rw-r--r--ExpressionCompiler.cpp14
-rw-r--r--GlobalContext.cpp70
-rw-r--r--GlobalContext.h61
-rw-r--r--NameAndTypeResolver.cpp43
-rw-r--r--NameAndTypeResolver.h3
-rw-r--r--Scanner.cpp1
-rw-r--r--Token.h1
-rw-r--r--Types.cpp30
-rw-r--r--Types.h32
13 files changed, 259 insertions, 66 deletions
diff --git a/AST.cpp b/AST.cpp
index 9aecbded..22a658d4 100644
--- a/AST.cpp
+++ b/AST.cpp
@@ -51,6 +51,40 @@ void StructDefinition::accept(ASTVisitor& _visitor)
_visitor.endVisit(*this);
}
+void StructDefinition::checkValidityOfMembers()
+{
+ checkMemberTypes();
+ checkRecursion();
+}
+
+void StructDefinition::checkMemberTypes()
+{
+ for (ASTPointer<VariableDeclaration> const& member: getMembers())
+ if (!member->getType()->canBeStored())
+ BOOST_THROW_EXCEPTION(member->createTypeError("Type cannot be used in struct."));
+}
+
+void StructDefinition::checkRecursion()
+{
+ set<StructDefinition const*> definitionsSeen;
+ vector<StructDefinition const*> queue = {this};
+ while (!queue.empty())
+ {
+ StructDefinition const* def = queue.back();
+ queue.pop_back();
+ if (definitionsSeen.count(def))
+ BOOST_THROW_EXCEPTION(ParserError() << errinfo_sourceLocation(def->getLocation())
+ << errinfo_comment("Recursive struct definition."));
+ definitionsSeen.insert(def);
+ for (ASTPointer<VariableDeclaration> const& member: def->getMembers())
+ if (member->getType()->getCategory() == Type::Category::STRUCT)
+ {
+ UserDefinedTypeName const& typeName = dynamic_cast<UserDefinedTypeName&>(*member->getTypeName());
+ queue.push_back(&dynamic_cast<StructDefinition const&>(*typeName.getReferencedDeclaration()));
+ }
+ }
+}
+
void ParameterList::accept(ASTVisitor& _visitor)
{
if (_visitor.visit(*this))
@@ -258,7 +292,7 @@ void Literal::accept(ASTVisitor& _visitor)
_visitor.endVisit(*this);
}
-TypeError ASTNode::createTypeError(string const& _description)
+TypeError ASTNode::createTypeError(string const& _description) const
{
return TypeError() << errinfo_sourceLocation(getLocation()) << errinfo_comment(_description);
}
diff --git a/AST.h b/AST.h
index 80c7dd19..01e1b54f 100644
--- a/AST.h
+++ b/AST.h
@@ -66,7 +66,7 @@ public:
/// Creates a @ref TypeError exception and decorates it with the location of the node and
/// the given description
- TypeError createTypeError(std::string const& _description);
+ TypeError createTypeError(std::string const& _description) const;
///@{
///@name equality operators
@@ -139,7 +139,14 @@ public:
std::vector<ASTPointer<VariableDeclaration>> const& getMembers() const { return m_members; }
+ /// Checks that the members do not include any recursive structs and have valid types
+ /// (e.g. no functions).
+ void checkValidityOfMembers();
+
private:
+ void checkMemberTypes();
+ void checkRecursion();
+
std::vector<ASTPointer<VariableDeclaration>> m_members;
};
@@ -210,7 +217,6 @@ public:
Declaration(_location, _name), m_typeName(_type) {}
virtual void accept(ASTVisitor& _visitor) override;
- bool isTypeGivenExplicitly() const { return bool(m_typeName); }
TypeName* getTypeName() const { return m_typeName.get(); }
/// Returns the declared or inferred type. Can be an empty pointer if no type was explicitly
@@ -238,6 +244,7 @@ public:
/// Retrieve the element of the type hierarchy this node refers to. Can return an empty shared
/// pointer until the types have been resolved using the @ref NameAndTypeResolver.
+ /// If it returns an empty shared pointer after that, this indicates that the type was not found.
virtual std::shared_ptr<Type> toType() const = 0;
};
@@ -263,8 +270,7 @@ private:
};
/**
- * Name referring to a user-defined type (i.e. a struct).
- * @todo some changes are necessary if this is also used to refer to contract types later
+ * Name referring to a user-defined type (i.e. a struct, contract, etc.).
*/
class UserDefinedTypeName: public TypeName
{
@@ -275,13 +281,13 @@ public:
virtual std::shared_ptr<Type> toType() const override { return Type::fromUserDefinedTypeName(*this); }
ASTString const& getName() const { return *m_name; }
- void setReferencedStruct(StructDefinition& _referencedStruct) { m_referencedStruct = &_referencedStruct; }
- StructDefinition const* getReferencedStruct() const { return m_referencedStruct; }
+ void setReferencedDeclaration(Declaration& _referencedDeclaration) { m_referencedDeclaration = &_referencedDeclaration; }
+ Declaration const* getReferencedDeclaration() const { return m_referencedDeclaration; }
private:
ASTPointer<ASTString> m_name;
- StructDefinition* m_referencedStruct;
+ Declaration* m_referencedDeclaration;
};
/**
diff --git a/CompilerStack.cpp b/CompilerStack.cpp
index d87c2791..f051d58f 100644
--- a/CompilerStack.cpp
+++ b/CompilerStack.cpp
@@ -23,6 +23,7 @@
#include <libsolidity/AST.h>
#include <libsolidity/Scanner.h>
#include <libsolidity/Parser.h>
+#include <libsolidity/GlobalContext.h>
#include <libsolidity/NameAndTypeResolver.h>
#include <libsolidity/Compiler.h>
#include <libsolidity/CompilerStack.h>
@@ -45,7 +46,9 @@ void CompilerStack::parse()
if (!m_scanner)
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Source not available."));
m_contractASTNode = Parser().parse(m_scanner);
- NameAndTypeResolver().resolveNamesAndTypes(*m_contractASTNode);
+ m_globalContext = make_shared<GlobalContext>();
+ m_globalContext->setCurrentContract(*m_contractASTNode);
+ NameAndTypeResolver(m_globalContext->getDeclarations()).resolveNamesAndTypes(*m_contractASTNode);
m_parseSuccessful = true;
}
diff --git a/CompilerStack.h b/CompilerStack.h
index 2fb50589..6cae8660 100644
--- a/CompilerStack.h
+++ b/CompilerStack.h
@@ -30,9 +30,11 @@
namespace dev {
namespace solidity {
-class Scanner; // forward
-class ContractDefinition; // forward
-class Compiler; // forward
+// forward declarations
+class Scanner;
+class ContractDefinition;
+class Compiler;
+class GlobalContext;
/**
* Easy to use and self-contained Solidity compiler with as few header dependencies as possible.
@@ -71,6 +73,7 @@ public:
private:
std::shared_ptr<Scanner> m_scanner;
+ std::shared_ptr<GlobalContext> m_globalContext;
std::shared_ptr<ContractDefinition> m_contractASTNode;
bool m_parseSuccessful;
std::string m_interface;
diff --git a/ExpressionCompiler.cpp b/ExpressionCompiler.cpp
index 89eeb31f..4d175527 100644
--- a/ExpressionCompiler.cpp
+++ b/ExpressionCompiler.cpp
@@ -167,7 +167,15 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall)
BOOST_THROW_EXCEPTION(InternalCompilerError());
Expression& firstArgument = *_functionCall.getArguments().front();
firstArgument.accept(*this);
- appendTypeConversion(*firstArgument.getType(), *_functionCall.getType());
+ if (firstArgument.getType()->getCategory() == Type::Category::CONTRACT &&
+ _functionCall.getType()->getCategory() == Type::Category::INTEGER)
+ {
+ // explicit type conversion contract -> address, nothing to do.
+ }
+ else
+ {
+ appendTypeConversion(*firstArgument.getType(), *_functionCall.getType());
+ }
}
else
{
@@ -466,7 +474,7 @@ void ExpressionCompiler::LValue::storeValue(Expression const& _expression, bool
}
}
-void ExpressionCompiler::LValue::retrieveValueIfLValueNotRequested(const Expression& _expression)
+void ExpressionCompiler::LValue::retrieveValueIfLValueNotRequested(Expression const& _expression)
{
if (!_expression.lvalueRequested())
{
@@ -475,7 +483,7 @@ void ExpressionCompiler::LValue::retrieveValueIfLValueNotRequested(const Express
}
}
-void ExpressionCompiler::LValue::fromDeclaration( Expression const& _expression, Declaration const& _declaration)
+void ExpressionCompiler::LValue::fromDeclaration(Expression const& _expression, Declaration const& _declaration)
{
if (m_context->isLocalVariable(&_declaration))
{
diff --git a/GlobalContext.cpp b/GlobalContext.cpp
new file mode 100644
index 00000000..6179722b
--- /dev/null
+++ b/GlobalContext.cpp
@@ -0,0 +1,70 @@
+/*
+ This file is part of cpp-ethereum.
+
+ cpp-ethereum 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.
+
+ cpp-ethereum 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @author Christian <c@ethdev.com>
+ * @date 2014
+ * Container of the (implicit and explicit) global objects.
+ */
+
+#include <memory>
+#include <libsolidity/GlobalContext.h>
+#include <libsolidity/AST.h>
+#include <libsolidity/Types.h>
+
+using namespace std;
+
+namespace dev
+{
+namespace solidity
+{
+
+GlobalContext::GlobalContext()
+{
+ // CurrentContract this; // @todo type depends on context -> switch prior to entering contract
+ // Message msg;
+ // Transaction tx;
+ // Block block;
+
+ //@todo type will be a custom complex type, maybe the same type class for msg tx and block.
+ //addVariable("msg", );
+}
+
+void GlobalContext::setCurrentContract(ContractDefinition const& _contract)
+{
+ m_this = createVariable("this", make_shared<ContractType>(_contract));
+}
+
+vector<Declaration*> GlobalContext::getDeclarations() const
+{
+ vector<Declaration*> declarations;
+ declarations.reserve(m_objects.size() + 1);
+ for (ASTPointer<Declaration> const& declaration: m_objects)
+ declarations.push_back(declaration.get());
+ declarations.push_back(m_this.get());
+ return declarations;
+}
+
+ASTPointer<VariableDeclaration> GlobalContext::createVariable(const string& _name, shared_ptr<const Type> const& _type)
+{
+ ASTPointer<VariableDeclaration> variable = make_shared<VariableDeclaration>(Location(), ASTPointer<TypeName>(),
+ make_shared<ASTString>(_name));
+ variable->setType(_type);
+ return variable;
+}
+
+}
+}
diff --git a/GlobalContext.h b/GlobalContext.h
new file mode 100644
index 00000000..b6dea7d5
--- /dev/null
+++ b/GlobalContext.h
@@ -0,0 +1,61 @@
+/*
+ This file is part of cpp-ethereum.
+
+ cpp-ethereum 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.
+
+ cpp-ethereum 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 cpp-ethereum. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @author Christian <c@ethdev.com>
+ * @date 2014
+ * Container of the (implicit and explicit) global objects.
+ */
+
+#pragma once
+
+#include <string>
+#include <vector>
+#include <memory>
+#include <boost/noncopyable.hpp>
+#include <libsolidity/ASTForward.h>
+
+namespace dev
+{
+namespace solidity
+{
+
+class Type; // forward
+
+/**
+ * Container for all global objects which look like AST nodes, but are not part of the AST
+ * that is currently being compiled.
+ * @note must not be destroyed or moved during compilation as its objects can be referenced from
+ * other objects.
+ */
+class GlobalContext: private boost::noncopyable
+{
+public:
+ GlobalContext();
+ void setCurrentContract(ContractDefinition const& _contract);
+
+ std::vector<Declaration*> getDeclarations() const;
+
+private:
+ /// Creates a virtual variable declaration with the given name and type.
+ static ASTPointer<VariableDeclaration> createVariable(std::string const& _name, std::shared_ptr<Type const> const& _type);
+
+ std::vector<ASTPointer<Declaration>> m_objects;
+ ASTPointer<Declaration> m_this;
+};
+
+}
+}
diff --git a/NameAndTypeResolver.cpp b/NameAndTypeResolver.cpp
index aa772658..225f2a78 100644
--- a/NameAndTypeResolver.cpp
+++ b/NameAndTypeResolver.cpp
@@ -32,15 +32,20 @@ namespace solidity
{
+NameAndTypeResolver::NameAndTypeResolver(std::vector<Declaration*> const& _globals)
+{
+ for (Declaration* declaration: _globals)
+ m_scopes[nullptr].registerDeclaration(*declaration);
+}
+
void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
{
- reset();
DeclarationRegistrationHelper registrar(m_scopes, _contract);
m_currentScope = &m_scopes[&_contract];
for (ASTPointer<StructDefinition> const& structDef: _contract.getDefinedStructs())
ReferencesResolver resolver(*structDef, *this, nullptr);
for (ASTPointer<StructDefinition> const& structDef: _contract.getDefinedStructs())
- checkForRecursion(*structDef);
+ structDef->checkValidityOfMembers();
for (ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables())
ReferencesResolver resolver(*variable, *this, nullptr);
for (ASTPointer<FunctionDefinition> const& function: _contract.getDefinedFunctions())
@@ -73,30 +78,6 @@ Declaration* NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name
return m_currentScope->resolveName(_name, _recursive);
}
-void NameAndTypeResolver::checkForRecursion(StructDefinition const& _struct)
-{
- set<StructDefinition const*> definitionsSeen;
- vector<StructDefinition const*> queue = {&_struct};
- while (!queue.empty())
- {
- StructDefinition const* def = queue.back();
- queue.pop_back();
- if (definitionsSeen.count(def))
- BOOST_THROW_EXCEPTION(ParserError() << errinfo_sourceLocation(def->getLocation())
- << errinfo_comment("Recursive struct definition."));
- definitionsSeen.insert(def);
- for (ASTPointer<VariableDeclaration> const& member: def->getMembers())
- if (member->getType()->getCategory() == Type::Category::STRUCT)
- queue.push_back(dynamic_cast<UserDefinedTypeName&>(*member->getTypeName()).getReferencedStruct());
- }
-}
-
-void NameAndTypeResolver::reset()
-{
- m_scopes.clear();
- m_currentScope = nullptr;
-}
-
DeclarationRegistrationHelper::DeclarationRegistrationHelper(map<ASTNode const*, Scope>& _scopes,
ASTNode& _astRoot):
m_scopes(_scopes), m_currentScope(&m_scopes[nullptr])
@@ -195,7 +176,11 @@ void ReferencesResolver::endVisit(VariableDeclaration& _variable)
// endVisit because the internal type needs resolving if it is a user defined type
// or mapping
if (_variable.getTypeName())
+ {
_variable.setType(_variable.getTypeName()->toType());
+ if (!_variable.getType())
+ BOOST_THROW_EXCEPTION(_variable.getTypeName()->createTypeError("Invalid type name"));
+ }
else if (!m_allowLazyTypes)
BOOST_THROW_EXCEPTION(_variable.createTypeError("Explicit type needed."));
// otherwise we have a "var"-declaration whose type is resolved by the first assignment
@@ -221,11 +206,7 @@ bool ReferencesResolver::visit(UserDefinedTypeName& _typeName)
if (!declaration)
BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_typeName.getLocation())
<< errinfo_comment("Undeclared identifier."));
- StructDefinition* referencedStruct = dynamic_cast<StructDefinition*>(declaration);
- //@todo later, contracts are also valid types
- if (!referencedStruct)
- BOOST_THROW_EXCEPTION(_typeName.createTypeError("Identifier does not name a type name."));
- _typeName.setReferencedStruct(*referencedStruct);
+ _typeName.setReferencedDeclaration(*declaration);
return false;
}
diff --git a/NameAndTypeResolver.h b/NameAndTypeResolver.h
index d335807e..64f3c89d 100644
--- a/NameAndTypeResolver.h
+++ b/NameAndTypeResolver.h
@@ -41,8 +41,7 @@ namespace solidity
class NameAndTypeResolver: private boost::noncopyable
{
public:
- NameAndTypeResolver() {}
-
+ explicit NameAndTypeResolver(std::vector<Declaration*> const& _globals);
void resolveNamesAndTypes(ContractDefinition& _contract);
/// Resolves the given @a _name inside the scope @a _scope. If @a _scope is omitted,
diff --git a/Scanner.cpp b/Scanner.cpp
index 895b8ae7..dd18a320 100644
--- a/Scanner.cpp
+++ b/Scanner.cpp
@@ -683,7 +683,6 @@ Token::Value Scanner::scanNumber(char _charSeen)
KEYWORD("switch", Token::SWITCH) \
KEYWORD_GROUP('t') \
KEYWORD("text", Token::TEXT) \
- KEYWORD("this", Token::THIS) \
KEYWORD("true", Token::TRUE_LITERAL) \
KEYWORD_GROUP('u') \
KEYWORD("uint", Token::UINT) \
diff --git a/Token.h b/Token.h
index 52448752..8974ca1a 100644
--- a/Token.h
+++ b/Token.h
@@ -160,7 +160,6 @@ namespace solidity
K(RETURNS, "returns", 0) \
K(STRUCT, "struct", 0) \
K(SWITCH, "switch", 0) \
- K(THIS, "this", 0) \
K(VAR, "var", 0) \
K(WHILE, "while", 0) \
\
diff --git a/Types.cpp b/Types.cpp
index 897ca221..f9d3d90f 100644
--- a/Types.cpp
+++ b/Types.cpp
@@ -60,13 +60,24 @@ shared_ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken)
shared_ptr<Type> Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName)
{
- return make_shared<StructType>(*_typeName.getReferencedStruct());
+ Declaration const* declaration = _typeName.getReferencedDeclaration();
+ if (StructDefinition const* structDef = dynamic_cast<StructDefinition const*>(declaration))
+ return make_shared<StructType>(*structDef);
+ else if (FunctionDefinition const* function = dynamic_cast<FunctionDefinition const*>(declaration))
+ return make_shared<FunctionType>(*function);
+ else if (ContractDefinition const* contract = dynamic_cast<ContractDefinition const*>(declaration))
+ return make_shared<ContractType>(*contract);
+ return shared_ptr<Type>();
}
shared_ptr<Type> Type::fromMapping(Mapping const& _typeName)
{
shared_ptr<Type const> keyType = _typeName.getKeyType().toType();
+ if (!keyType)
+ BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Error resolving type name."));
shared_ptr<Type const> valueType = _typeName.getValueType().toType();
+ if (!valueType)
+ BOOST_THROW_EXCEPTION(_typeName.getValueType().createTypeError("Invalid type name"));
return make_shared<MappingType>(keyType, valueType);
}
@@ -201,6 +212,15 @@ u256 BoolType::literalValue(Literal const& _literal) const
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Bool type constructed from non-boolean literal."));
}
+bool ContractType::isExplicitlyConvertibleTo(Type const& _convertTo) const
+{
+ if (isImplicitlyConvertibleTo(_convertTo))
+ return true;
+ if (_convertTo.getCategory() == Category::INTEGER)
+ return dynamic_cast<IntegerType const&>(_convertTo).isAddress();
+ return false;
+}
+
bool ContractType::operator==(Type const& _other) const
{
if (_other.getCategory() != getCategory())
@@ -217,6 +237,11 @@ u256 ContractType::getStorageSize() const
return max<u256>(1, size);
}
+string ContractType::toString() const
+{
+ return "contract " + m_contract.getName();
+}
+
bool StructType::operator==(Type const& _other) const
{
if (_other.getCategory() != getCategory())
@@ -282,8 +307,7 @@ bool FunctionType::operator==(Type const& _other) const
string FunctionType::toString() const
{
- //@todo nice string for function types
- return "function(...)returns(...)";
+ return "function " + m_function.getName();
}
bool MappingType::operator==(Type const& _other) const
diff --git a/Types.h b/Types.h
index 2208a880..297284ba 100644
--- a/Types.h
+++ b/Types.h
@@ -106,6 +106,8 @@ public:
/// @returns number of bytes required to hold this value in storage.
/// For dynamically "allocated" types, it returns the size of the statically allocated head,
virtual u256 getStorageSize() const { return 1; }
+ /// Returns true if the type can be stored in storage.
+ virtual bool canBeStored() const { return true; }
/// Returns false if the type cannot live outside the storage, i.e. if it includes some mapping.
virtual bool canLiveOutsideStorage() const { return true; }
@@ -151,7 +153,7 @@ public:
virtual bool operator==(Type const& _other) const override;
- virtual unsigned getCalldataEncodedSize() const { return m_bits / 8; }
+ virtual unsigned getCalldataEncodedSize() const override { return m_bits / 8; }
virtual std::string toString() const override;
virtual u256 literalValue(Literal const& _literal) const override;
@@ -197,10 +199,11 @@ class ContractType: public Type
public:
virtual Category getCategory() const override { return Category::CONTRACT; }
ContractType(ContractDefinition const& _contract): m_contract(_contract) {}
-
+ /// Contracts can be converted to themselves and to addresses.
+ virtual bool isExplicitlyConvertibleTo(Type const& _convertTo) const override;
virtual bool operator==(Type const& _other) const override;
- virtual u256 getStorageSize() const;
- virtual std::string toString() const override { return "contract{...}"; }
+ virtual u256 getStorageSize() const override;
+ virtual std::string toString() const override;
private:
ContractDefinition const& m_contract;
@@ -220,8 +223,8 @@ public:
}
virtual bool operator==(Type const& _other) const override;
- virtual u256 getStorageSize() const;
- virtual bool canLiveOutsideStorage() const;
+ virtual u256 getStorageSize() const override;
+ virtual bool canLiveOutsideStorage() const override;
virtual std::string toString() const override;
virtual MemberList const& getMembers() const override;
@@ -247,8 +250,9 @@ public:
virtual bool operator==(Type const& _other) const override;
virtual std::string toString() const override;
- virtual u256 getStorageSize() const { BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Storage size of non-storable function type requested.")); }
- virtual bool canLiveOutsideStorage() const { return false; }
+ virtual bool canBeStored() const override { return false; }
+ virtual u256 getStorageSize() const override { BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Storage size of non-storable function type requested.")); }
+ virtual bool canLiveOutsideStorage() const override { return false; }
private:
FunctionDefinition const& m_function;
@@ -266,7 +270,7 @@ public:
virtual bool operator==(Type const& _other) const override;
virtual std::string toString() const override;
- virtual bool canLiveOutsideStorage() const { return false; }
+ virtual bool canLiveOutsideStorage() const override { return false; }
std::shared_ptr<Type const> getKeyType() const { return m_keyType; }
std::shared_ptr<Type const> getValueType() const { return m_valueType; }
@@ -287,8 +291,9 @@ public:
VoidType() {}
virtual std::string toString() const override { return "void"; }
- virtual u256 getStorageSize() const { BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Storage size of non-storable void type requested.")); }
- virtual bool canLiveOutsideStorage() const { return false; }
+ virtual bool canBeStored() const override { return false; }
+ virtual u256 getStorageSize() const override { BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Storage size of non-storable void type requested.")); }
+ virtual bool canLiveOutsideStorage() const override { return false; }
};
/**
@@ -304,8 +309,9 @@ public:
std::shared_ptr<Type const> const& getActualType() const { return m_actualType; }
virtual bool operator==(Type const& _other) const override;
- virtual u256 getStorageSize() const { BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Storage size of non-storable type type requested.")); }
- virtual bool canLiveOutsideStorage() const { return false; }
+ virtual bool canBeStored() const override { return false; }
+ virtual u256 getStorageSize() const override { BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Storage size of non-storable type type requested.")); }
+ virtual bool canLiveOutsideStorage() const override { return false; }
virtual std::string toString() const override { return "type(" + m_actualType->toString() + ")"; }
private: