mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Merge branch 'macox_fixes' into build_enhancement
Conflicts: test/solidityNatspecJSON.cpp
This commit is contained in:
commit
bea34ab073
269
AST.cpp
269
AST.cpp
@ -25,6 +25,7 @@
|
||||
#include <libsolidity/AST.h>
|
||||
#include <libsolidity/ASTVisitor.h>
|
||||
#include <libsolidity/Exceptions.h>
|
||||
#include <libsolidity/AST_accept.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -33,250 +34,6 @@ namespace dev
|
||||
namespace solidity
|
||||
{
|
||||
|
||||
void SourceUnit::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
listAccept(m_nodes, _visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ImportDirective::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ContractDefinition::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
listAccept(m_definedStructs, _visitor);
|
||||
listAccept(m_stateVariables, _visitor);
|
||||
listAccept(m_definedFunctions, _visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void StructDefinition::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
listAccept(m_members, _visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void StructDefinition::checkValidityOfMembers()
|
||||
{
|
||||
checkMemberTypes();
|
||||
checkRecursion();
|
||||
}
|
||||
|
||||
void ParameterList::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
listAccept(m_parameters, _visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void FunctionDefinition::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_parameters->accept(_visitor);
|
||||
if (m_returnParameters)
|
||||
m_returnParameters->accept(_visitor);
|
||||
m_body->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void VariableDeclaration::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
if (m_typeName)
|
||||
m_typeName->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void TypeName::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ElementaryTypeName::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void UserDefinedTypeName::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Mapping::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_keyType->accept(_visitor);
|
||||
m_valueType->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Statement::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Block::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
listAccept(m_statements, _visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void IfStatement::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_condition->accept(_visitor);
|
||||
m_trueBody->accept(_visitor);
|
||||
if (m_falseBody)
|
||||
m_falseBody->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void BreakableStatement::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void WhileStatement::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_condition->accept(_visitor);
|
||||
m_body->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Continue::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Break::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Return::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
if (m_expression)
|
||||
m_expression->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ExpressionStatement::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
if (m_expression)
|
||||
m_expression->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void VariableDefinition::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_variable->accept(_visitor);
|
||||
if (m_value)
|
||||
m_value->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Assignment::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_leftHandSide->accept(_visitor);
|
||||
m_rightHandSide->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void UnaryOperation::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
m_subExpression->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void BinaryOperation::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_left->accept(_visitor);
|
||||
m_right->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void FunctionCall::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_expression->accept(_visitor);
|
||||
listAccept(m_arguments, _visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void MemberAccess::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
m_expression->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void IndexAccess::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_base->accept(_visitor);
|
||||
m_index->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Identifier::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ElementaryTypeNameExpression::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Literal::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
TypeError ASTNode::createTypeError(string const& _description) const
|
||||
{
|
||||
return TypeError() << errinfo_sourceLocation(getLocation()) << errinfo_comment(_description);
|
||||
@ -297,14 +54,14 @@ vector<FunctionDefinition const*> ContractDefinition::getInterfaceFunctions() co
|
||||
return exportedFunctions;
|
||||
}
|
||||
|
||||
void StructDefinition::checkMemberTypes()
|
||||
void StructDefinition::checkMemberTypes() const
|
||||
{
|
||||
for (ASTPointer<VariableDeclaration> const& member: getMembers())
|
||||
if (!member->getType()->canBeStored())
|
||||
BOOST_THROW_EXCEPTION(member->createTypeError("Type cannot be used in struct."));
|
||||
}
|
||||
|
||||
void StructDefinition::checkRecursion()
|
||||
void StructDefinition::checkRecursion() const
|
||||
{
|
||||
set<StructDefinition const*> definitionsSeen;
|
||||
vector<StructDefinition const*> queue = {this};
|
||||
@ -319,7 +76,7 @@ void StructDefinition::checkRecursion()
|
||||
for (ASTPointer<VariableDeclaration> const& member: def->getMembers())
|
||||
if (member->getType()->getCategory() == Type::Category::STRUCT)
|
||||
{
|
||||
UserDefinedTypeName const& typeName = dynamic_cast<UserDefinedTypeName&>(*member->getTypeName());
|
||||
UserDefinedTypeName const& typeName = dynamic_cast<UserDefinedTypeName const&>(*member->getTypeName());
|
||||
queue.push_back(&dynamic_cast<StructDefinition const&>(*typeName.getReferencedDeclaration()));
|
||||
}
|
||||
}
|
||||
@ -532,7 +289,7 @@ void Identifier::checkTypeRequirements()
|
||||
if (asserts(m_referencedDeclaration))
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier not resolved."));
|
||||
|
||||
VariableDeclaration* variable = dynamic_cast<VariableDeclaration*>(m_referencedDeclaration);
|
||||
VariableDeclaration const* variable = dynamic_cast<VariableDeclaration const*>(m_referencedDeclaration);
|
||||
if (variable)
|
||||
{
|
||||
if (!variable->getType())
|
||||
@ -542,29 +299,29 @@ void Identifier::checkTypeRequirements()
|
||||
return;
|
||||
}
|
||||
//@todo can we unify these with TypeName::toType()?
|
||||
StructDefinition* structDef = dynamic_cast<StructDefinition*>(m_referencedDeclaration);
|
||||
StructDefinition const* structDef = dynamic_cast<StructDefinition const*>(m_referencedDeclaration);
|
||||
if (structDef)
|
||||
{
|
||||
// note that we do not have a struct type here
|
||||
m_type = make_shared<TypeType>(make_shared<StructType>(*structDef));
|
||||
m_type = make_shared<TypeType const>(make_shared<StructType const>(*structDef));
|
||||
return;
|
||||
}
|
||||
FunctionDefinition* functionDef = dynamic_cast<FunctionDefinition*>(m_referencedDeclaration);
|
||||
FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(m_referencedDeclaration);
|
||||
if (functionDef)
|
||||
{
|
||||
// a function reference is not a TypeType, because calling a TypeType converts to the type.
|
||||
// Calling a function (e.g. function(12), otherContract.function(34)) does not do a type
|
||||
// conversion.
|
||||
m_type = make_shared<FunctionType>(*functionDef);
|
||||
m_type = make_shared<FunctionType const>(*functionDef);
|
||||
return;
|
||||
}
|
||||
ContractDefinition* contractDef = dynamic_cast<ContractDefinition*>(m_referencedDeclaration);
|
||||
ContractDefinition const* contractDef = dynamic_cast<ContractDefinition const*>(m_referencedDeclaration);
|
||||
if (contractDef)
|
||||
{
|
||||
m_type = make_shared<TypeType>(make_shared<ContractType>(*contractDef));
|
||||
m_type = make_shared<TypeType const>(make_shared<ContractType>(*contractDef));
|
||||
return;
|
||||
}
|
||||
MagicVariableDeclaration* magicVariable = dynamic_cast<MagicVariableDeclaration*>(m_referencedDeclaration);
|
||||
MagicVariableDeclaration const* magicVariable = dynamic_cast<MagicVariableDeclaration const*>(m_referencedDeclaration);
|
||||
if (magicVariable)
|
||||
{
|
||||
m_type = magicVariable->getType();
|
||||
@ -575,7 +332,7 @@ void Identifier::checkTypeRequirements()
|
||||
|
||||
void ElementaryTypeNameExpression::checkTypeRequirements()
|
||||
{
|
||||
m_type = make_shared<TypeType>(Type::fromElementaryTypeName(m_typeToken));
|
||||
m_type = make_shared<TypeType const>(Type::fromElementaryTypeName(m_typeToken));
|
||||
}
|
||||
|
||||
void Literal::checkTypeRequirements()
|
||||
|
133
AST.h
133
AST.h
@ -39,6 +39,7 @@ namespace solidity
|
||||
{
|
||||
|
||||
class ASTVisitor;
|
||||
class ASTConstVisitor;
|
||||
|
||||
|
||||
/**
|
||||
@ -54,12 +55,19 @@ public:
|
||||
virtual ~ASTNode() {}
|
||||
|
||||
virtual void accept(ASTVisitor& _visitor) = 0;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const = 0;
|
||||
template <class T>
|
||||
static void listAccept(std::vector<ASTPointer<T>>& _list, ASTVisitor& _visitor)
|
||||
{
|
||||
for (ASTPointer<T>& element: _list)
|
||||
element->accept(_visitor);
|
||||
}
|
||||
template <class T>
|
||||
static void listAccept(std::vector<ASTPointer<T>> const& _list, ASTConstVisitor& _visitor)
|
||||
{
|
||||
for (ASTPointer<T> const& element: _list)
|
||||
element->accept(_visitor);
|
||||
}
|
||||
|
||||
/// Returns the source code location of this node.
|
||||
Location const& getLocation() const { return m_location; }
|
||||
@ -89,6 +97,7 @@ public:
|
||||
ASTNode(_location), m_nodes(_nodes) {}
|
||||
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
std::vector<ASTPointer<ASTNode>> getNodes() const { return m_nodes; }
|
||||
|
||||
@ -108,6 +117,7 @@ public:
|
||||
ASTNode(_location), m_identifier(_identifier) {}
|
||||
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
ASTString const& getIdentifier() const { return *m_identifier; }
|
||||
|
||||
@ -122,18 +132,18 @@ class Declaration: public ASTNode
|
||||
{
|
||||
public:
|
||||
Declaration(Location const& _location, ASTPointer<ASTString> const& _name):
|
||||
ASTNode(_location), m_name(_name) {}
|
||||
ASTNode(_location), m_name(_name), m_scope(nullptr) {}
|
||||
|
||||
/// @returns the declared name.
|
||||
ASTString const& getName() const { return *m_name; }
|
||||
/// @returns the scope this declaration resides in. Can be nullptr if it is the global scope.
|
||||
/// Available only after name and type resolution step.
|
||||
Declaration* getScope() const { return m_scope; }
|
||||
void setScope(Declaration* const& _scope) { m_scope = _scope; }
|
||||
Declaration const* getScope() const { return m_scope; }
|
||||
void setScope(Declaration const* _scope) { m_scope = _scope; }
|
||||
|
||||
private:
|
||||
ASTPointer<ASTString> m_name;
|
||||
Declaration* m_scope;
|
||||
Declaration const* m_scope;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -146,21 +156,28 @@ class ContractDefinition: public Declaration
|
||||
public:
|
||||
ContractDefinition(Location const& _location,
|
||||
ASTPointer<ASTString> const& _name,
|
||||
ASTPointer<ASTString> const& _documentation,
|
||||
std::vector<ASTPointer<StructDefinition>> const& _definedStructs,
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& _stateVariables,
|
||||
std::vector<ASTPointer<FunctionDefinition>> const& _definedFunctions):
|
||||
Declaration(_location, _name),
|
||||
m_definedStructs(_definedStructs),
|
||||
m_stateVariables(_stateVariables),
|
||||
m_definedFunctions(_definedFunctions)
|
||||
m_definedFunctions(_definedFunctions),
|
||||
m_documentation(_documentation)
|
||||
{}
|
||||
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
std::vector<ASTPointer<StructDefinition>> const& getDefinedStructs() const { return m_definedStructs; }
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& getStateVariables() const { return m_stateVariables; }
|
||||
std::vector<ASTPointer<FunctionDefinition>> const& getDefinedFunctions() const { return m_definedFunctions; }
|
||||
|
||||
/// @return A shared pointer of an ASTString.
|
||||
/// Can contain a nullptr in which case indicates absence of documentation
|
||||
ASTPointer<ASTString> const& getDocumentation() const { return m_documentation; }
|
||||
|
||||
/// Returns the functions that make up the calling interface in the intended order.
|
||||
std::vector<FunctionDefinition const*> getInterfaceFunctions() const;
|
||||
|
||||
@ -168,6 +185,7 @@ private:
|
||||
std::vector<ASTPointer<StructDefinition>> m_definedStructs;
|
||||
std::vector<ASTPointer<VariableDeclaration>> m_stateVariables;
|
||||
std::vector<ASTPointer<FunctionDefinition>> m_definedFunctions;
|
||||
ASTPointer<ASTString> m_documentation;
|
||||
};
|
||||
|
||||
class StructDefinition: public Declaration
|
||||
@ -178,16 +196,17 @@ public:
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& _members):
|
||||
Declaration(_location, _name), m_members(_members) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
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();
|
||||
void checkValidityOfMembers() const;
|
||||
|
||||
private:
|
||||
void checkMemberTypes();
|
||||
void checkRecursion();
|
||||
void checkMemberTypes() const;
|
||||
void checkRecursion() const;
|
||||
|
||||
std::vector<ASTPointer<VariableDeclaration>> m_members;
|
||||
};
|
||||
@ -204,6 +223,7 @@ public:
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& _parameters):
|
||||
ASTNode(_location), m_parameters(_parameters) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& getParameters() const { return m_parameters; }
|
||||
|
||||
@ -230,14 +250,15 @@ public:
|
||||
{}
|
||||
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
bool isPublic() const { return m_isPublic; }
|
||||
bool isDeclaredConst() const { return m_isDeclaredConst; }
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& getParameters() const { return m_parameters->getParameters(); }
|
||||
ParameterList& getParameterList() { return *m_parameters; }
|
||||
ParameterList const& getParameterList() const { return *m_parameters; }
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& getReturnParameters() const { return m_returnParameters->getParameters(); }
|
||||
ASTPointer<ParameterList> const& getReturnParameterList() const { return m_returnParameters; }
|
||||
Block& getBody() { return *m_body; }
|
||||
Block const& getBody() const { return *m_body; }
|
||||
/// @return A shared pointer of an ASTString.
|
||||
/// Can contain a nullptr in which case indicates absence of documentation
|
||||
ASTPointer<ASTString> const& getDocumentation() const { return m_documentation; }
|
||||
@ -270,15 +291,16 @@ public:
|
||||
ASTPointer<ASTString> const& _name):
|
||||
Declaration(_location, _name), m_typeName(_type) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
TypeName* getTypeName() const { return m_typeName.get(); }
|
||||
TypeName const* getTypeName() const { return m_typeName.get(); }
|
||||
|
||||
/// Returns the declared or inferred type. Can be an empty pointer if no type was explicitly
|
||||
/// declared and there is no assignment to the variable that fixes the type.
|
||||
std::shared_ptr<Type const> const& getType() const { return m_type; }
|
||||
void setType(std::shared_ptr<Type const> const& _type) { m_type = _type; }
|
||||
|
||||
bool isLocalVariable() const { return !!dynamic_cast<FunctionDefinition*>(getScope()); }
|
||||
bool isLocalVariable() const { return !!dynamic_cast<FunctionDefinition const*>(getScope()); }
|
||||
|
||||
private:
|
||||
ASTPointer<TypeName> m_typeName; ///< can be empty ("var")
|
||||
@ -297,6 +319,8 @@ public:
|
||||
Declaration(Location(), std::make_shared<ASTString>(_name)), m_type(_type) {}
|
||||
virtual void accept(ASTVisitor&) override { BOOST_THROW_EXCEPTION(InternalCompilerError()
|
||||
<< errinfo_comment("MagicVariableDeclaration used inside real AST.")); }
|
||||
virtual void accept(ASTConstVisitor&) const override { BOOST_THROW_EXCEPTION(InternalCompilerError()
|
||||
<< errinfo_comment("MagicVariableDeclaration used inside real AST.")); }
|
||||
|
||||
std::shared_ptr<Type const> const& getType() const { return m_type; }
|
||||
|
||||
@ -315,11 +339,12 @@ class TypeName: public ASTNode
|
||||
public:
|
||||
explicit TypeName(Location const& _location): ASTNode(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
/// 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;
|
||||
virtual std::shared_ptr<Type const> toType() const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -335,7 +360,8 @@ public:
|
||||
if (asserts(Token::isElementaryTypeName(_type))) BOOST_THROW_EXCEPTION(InternalCompilerError());
|
||||
}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual std::shared_ptr<Type> toType() const override { return Type::fromElementaryTypeName(m_type); }
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual std::shared_ptr<Type const> toType() const override { return Type::fromElementaryTypeName(m_type); }
|
||||
|
||||
Token::Value getTypeName() const { return m_type; }
|
||||
|
||||
@ -350,18 +376,19 @@ class UserDefinedTypeName: public TypeName
|
||||
{
|
||||
public:
|
||||
UserDefinedTypeName(Location const& _location, ASTPointer<ASTString> const& _name):
|
||||
TypeName(_location), m_name(_name) {}
|
||||
TypeName(_location), m_name(_name), m_referencedDeclaration(nullptr) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual std::shared_ptr<Type> toType() const override { return Type::fromUserDefinedTypeName(*this); }
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual std::shared_ptr<Type const> toType() const override { return Type::fromUserDefinedTypeName(*this); }
|
||||
|
||||
ASTString const& getName() const { return *m_name; }
|
||||
void setReferencedDeclaration(Declaration& _referencedDeclaration) { m_referencedDeclaration = &_referencedDeclaration; }
|
||||
void setReferencedDeclaration(Declaration const& _referencedDeclaration) { m_referencedDeclaration = &_referencedDeclaration; }
|
||||
Declaration const* getReferencedDeclaration() const { return m_referencedDeclaration; }
|
||||
|
||||
private:
|
||||
ASTPointer<ASTString> m_name;
|
||||
|
||||
Declaration* m_referencedDeclaration;
|
||||
Declaration const* m_referencedDeclaration;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -374,7 +401,8 @@ public:
|
||||
ASTPointer<TypeName> const& _valueType):
|
||||
TypeName(_location), m_keyType(_keyType), m_valueType(_valueType) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual std::shared_ptr<Type> toType() const override { return Type::fromMapping(*this); }
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual std::shared_ptr<Type const> toType() const override { return Type::fromMapping(*this); }
|
||||
|
||||
ElementaryTypeName const& getKeyType() const { return *m_keyType; }
|
||||
TypeName const& getValueType() const { return *m_valueType; }
|
||||
@ -397,7 +425,6 @@ class Statement: public ASTNode
|
||||
{
|
||||
public:
|
||||
explicit Statement(Location const& _location): ASTNode(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
/// Check all type requirements, throws exception if some requirement is not met.
|
||||
/// This includes checking that operators are applicable to their arguments but also that
|
||||
@ -414,6 +441,7 @@ public:
|
||||
Block(Location const& _location, std::vector<ASTPointer<Statement>> const& _statements):
|
||||
Statement(_location), m_statements(_statements) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
@ -433,12 +461,13 @@ public:
|
||||
Statement(_location),
|
||||
m_condition(_condition), m_trueBody(_trueBody), m_falseBody(_falseBody) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Expression& getCondition() const { return *m_condition; }
|
||||
Statement& getTrueStatement() const { return *m_trueBody; }
|
||||
Expression const& getCondition() const { return *m_condition; }
|
||||
Statement const& getTrueStatement() const { return *m_trueBody; }
|
||||
/// @returns the "else" part of the if statement or nullptr if there is no "else" part.
|
||||
Statement* getFalseStatement() const { return m_falseBody.get(); }
|
||||
Statement const* getFalseStatement() const { return m_falseBody.get(); }
|
||||
|
||||
private:
|
||||
ASTPointer<Expression> m_condition;
|
||||
@ -447,13 +476,12 @@ private:
|
||||
};
|
||||
|
||||
/**
|
||||
* Statement in which a break statement is legal.
|
||||
* Statement in which a break statement is legal (abstract class).
|
||||
*/
|
||||
class BreakableStatement: public Statement
|
||||
{
|
||||
public:
|
||||
BreakableStatement(Location const& _location): Statement(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
};
|
||||
|
||||
class WhileStatement: public BreakableStatement
|
||||
@ -463,10 +491,11 @@ public:
|
||||
ASTPointer<Statement> const& _body):
|
||||
BreakableStatement(_location), m_condition(_condition), m_body(_body) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Expression& getCondition() const { return *m_condition; }
|
||||
Statement& getBody() const { return *m_body; }
|
||||
Expression const& getCondition() const { return *m_condition; }
|
||||
Statement const& getBody() const { return *m_body; }
|
||||
|
||||
private:
|
||||
ASTPointer<Expression> m_condition;
|
||||
@ -478,6 +507,7 @@ class Continue: public Statement
|
||||
public:
|
||||
Continue(Location const& _location): Statement(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override {}
|
||||
};
|
||||
|
||||
@ -486,6 +516,7 @@ class Break: public Statement
|
||||
public:
|
||||
Break(Location const& _location): Statement(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override {}
|
||||
};
|
||||
|
||||
@ -493,8 +524,9 @@ class Return: public Statement
|
||||
{
|
||||
public:
|
||||
Return(Location const& _location, ASTPointer<Expression> _expression):
|
||||
Statement(_location), m_expression(_expression) {}
|
||||
Statement(_location), m_expression(_expression), m_returnParameters(nullptr) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
void setFunctionReturnParameters(ParameterList& _parameters) { m_returnParameters = &_parameters; }
|
||||
@ -504,7 +536,7 @@ public:
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError());
|
||||
return *m_returnParameters;
|
||||
}
|
||||
Expression* getExpression() const { return m_expression.get(); }
|
||||
Expression const* getExpression() const { return m_expression.get(); }
|
||||
|
||||
private:
|
||||
ASTPointer<Expression> m_expression; ///< value to return, optional
|
||||
@ -525,10 +557,11 @@ public:
|
||||
ASTPointer<Expression> _value):
|
||||
Statement(_location), m_variable(_variable), m_value(_value) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
VariableDeclaration const& getDeclaration() const { return *m_variable; }
|
||||
Expression* getExpression() const { return m_value.get(); }
|
||||
Expression const* getExpression() const { return m_value.get(); }
|
||||
|
||||
private:
|
||||
ASTPointer<VariableDeclaration> m_variable;
|
||||
@ -544,9 +577,10 @@ public:
|
||||
ExpressionStatement(Location const& _location, ASTPointer<Expression> _expression):
|
||||
Statement(_location), m_expression(_expression) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Expression& getExpression() const { return *m_expression; }
|
||||
Expression const& getExpression() const { return *m_expression; }
|
||||
|
||||
private:
|
||||
ASTPointer<Expression> m_expression;
|
||||
@ -608,11 +642,12 @@ public:
|
||||
if (asserts(Token::isAssignmentOp(_assignmentOperator))) BOOST_THROW_EXCEPTION(InternalCompilerError());
|
||||
}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Expression& getLeftHandSide() const { return *m_leftHandSide; }
|
||||
Expression const& getLeftHandSide() const { return *m_leftHandSide; }
|
||||
Token::Value getAssignmentOperator() const { return m_assigmentOperator; }
|
||||
Expression& getRightHandSide() const { return *m_rightHandSide; }
|
||||
Expression const& getRightHandSide() const { return *m_rightHandSide; }
|
||||
|
||||
private:
|
||||
ASTPointer<Expression> m_leftHandSide;
|
||||
@ -635,11 +670,12 @@ public:
|
||||
if (asserts(Token::isUnaryOp(_operator))) BOOST_THROW_EXCEPTION(InternalCompilerError());
|
||||
}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Token::Value getOperator() const { return m_operator; }
|
||||
bool isPrefixOperation() const { return m_isPrefix; }
|
||||
Expression& getSubExpression() const { return *m_subExpression; }
|
||||
Expression const& getSubExpression() const { return *m_subExpression; }
|
||||
|
||||
private:
|
||||
Token::Value m_operator;
|
||||
@ -661,10 +697,11 @@ public:
|
||||
if (asserts(Token::isBinaryOp(_operator) || Token::isCompareOp(_operator))) BOOST_THROW_EXCEPTION(InternalCompilerError());
|
||||
}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Expression& getLeftExpression() const { return *m_left; }
|
||||
Expression& getRightExpression() const { return *m_right; }
|
||||
Expression const& getLeftExpression() const { return *m_left; }
|
||||
Expression const& getRightExpression() const { return *m_right; }
|
||||
Token::Value getOperator() const { return m_operator; }
|
||||
Type const& getCommonType() const { return *m_commonType; }
|
||||
|
||||
@ -688,10 +725,11 @@ public:
|
||||
std::vector<ASTPointer<Expression>> const& _arguments):
|
||||
Expression(_location), m_expression(_expression), m_arguments(_arguments) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Expression& getExpression() const { return *m_expression; }
|
||||
std::vector<ASTPointer<Expression>> const& getArguments() const { return m_arguments; }
|
||||
Expression const& getExpression() const { return *m_expression; }
|
||||
std::vector<ASTPointer<Expression const>> getArguments() const { return {m_arguments.begin(), m_arguments.end()}; }
|
||||
|
||||
/// Returns true if this is not an actual function call, but an explicit type conversion
|
||||
/// or constructor call.
|
||||
@ -712,7 +750,8 @@ public:
|
||||
ASTPointer<ASTString> const& _memberName):
|
||||
Expression(_location), m_expression(_expression), m_memberName(_memberName) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
Expression& getExpression() const { return *m_expression; }
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
Expression const& getExpression() const { return *m_expression; }
|
||||
ASTString const& getMemberName() const { return *m_memberName; }
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
@ -731,10 +770,11 @@ public:
|
||||
ASTPointer<Expression> const& _index):
|
||||
Expression(_location), m_base(_base), m_index(_index) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Expression& getBaseExpression() const { return *m_base; }
|
||||
Expression& getIndexExpression() const { return *m_index; }
|
||||
Expression const& getBaseExpression() const { return *m_base; }
|
||||
Expression const& getIndexExpression() const { return *m_index; }
|
||||
|
||||
private:
|
||||
ASTPointer<Expression> m_base;
|
||||
@ -758,20 +798,21 @@ class Identifier: public PrimaryExpression
|
||||
{
|
||||
public:
|
||||
Identifier(Location const& _location, ASTPointer<ASTString> const& _name):
|
||||
PrimaryExpression(_location), m_name(_name) {}
|
||||
PrimaryExpression(_location), m_name(_name), m_referencedDeclaration(nullptr) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
ASTString const& getName() const { return *m_name; }
|
||||
|
||||
void setReferencedDeclaration(Declaration& _referencedDeclaration) { m_referencedDeclaration = &_referencedDeclaration; }
|
||||
Declaration* getReferencedDeclaration() { return m_referencedDeclaration; }
|
||||
void setReferencedDeclaration(Declaration const& _referencedDeclaration) { m_referencedDeclaration = &_referencedDeclaration; }
|
||||
Declaration const* getReferencedDeclaration() const { return m_referencedDeclaration; }
|
||||
|
||||
private:
|
||||
ASTPointer<ASTString> m_name;
|
||||
|
||||
/// Declaration the name refers to.
|
||||
Declaration* m_referencedDeclaration;
|
||||
Declaration const* m_referencedDeclaration;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -788,6 +829,7 @@ public:
|
||||
if (asserts(Token::isElementaryTypeName(_typeToken))) BOOST_THROW_EXCEPTION(InternalCompilerError());
|
||||
}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Token::Value getTypeToken() const { return m_typeToken; }
|
||||
@ -805,6 +847,7 @@ public:
|
||||
Literal(Location const& _location, Token::Value _token, ASTPointer<ASTString> const& _value):
|
||||
PrimaryExpression(_location), m_token(_token), m_value(_value) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Token::Value getToken() const { return m_token; }
|
||||
|
126
ASTPrinter.cpp
126
ASTPrinter.cpp
@ -30,7 +30,7 @@ namespace dev
|
||||
namespace solidity
|
||||
{
|
||||
|
||||
ASTPrinter::ASTPrinter(ASTNode& _ast, string const& _source):
|
||||
ASTPrinter::ASTPrinter(ASTNode const& _ast, string const& _source):
|
||||
m_indentation(0), m_source(_source), m_ast(&_ast)
|
||||
{
|
||||
}
|
||||
@ -43,35 +43,35 @@ void ASTPrinter::print(ostream& _stream)
|
||||
}
|
||||
|
||||
|
||||
bool ASTPrinter::visit(ImportDirective& _node)
|
||||
bool ASTPrinter::visit(ImportDirective const& _node)
|
||||
{
|
||||
writeLine("ImportDirective \"" + _node.getIdentifier() + "\"");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(ContractDefinition& _node)
|
||||
bool ASTPrinter::visit(ContractDefinition const& _node)
|
||||
{
|
||||
writeLine("ContractDefinition \"" + _node.getName() + "\"");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(StructDefinition& _node)
|
||||
bool ASTPrinter::visit(StructDefinition const& _node)
|
||||
{
|
||||
writeLine("StructDefinition \"" + _node.getName() + "\"");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(ParameterList& _node)
|
||||
bool ASTPrinter::visit(ParameterList const& _node)
|
||||
{
|
||||
writeLine("ParameterList");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(FunctionDefinition& _node)
|
||||
bool ASTPrinter::visit(FunctionDefinition const& _node)
|
||||
{
|
||||
writeLine("FunctionDefinition \"" + _node.getName() + "\"" +
|
||||
(_node.isPublic() ? " - public" : "") +
|
||||
@ -80,112 +80,112 @@ bool ASTPrinter::visit(FunctionDefinition& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(VariableDeclaration& _node)
|
||||
bool ASTPrinter::visit(VariableDeclaration const& _node)
|
||||
{
|
||||
writeLine("VariableDeclaration \"" + _node.getName() + "\"");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(TypeName& _node)
|
||||
bool ASTPrinter::visit(TypeName const& _node)
|
||||
{
|
||||
writeLine("TypeName");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(ElementaryTypeName& _node)
|
||||
bool ASTPrinter::visit(ElementaryTypeName const& _node)
|
||||
{
|
||||
writeLine(string("ElementaryTypeName ") + Token::toString(_node.getTypeName()));
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(UserDefinedTypeName& _node)
|
||||
bool ASTPrinter::visit(UserDefinedTypeName const& _node)
|
||||
{
|
||||
writeLine("UserDefinedTypeName \"" + _node.getName() + "\"");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Mapping& _node)
|
||||
bool ASTPrinter::visit(Mapping const& _node)
|
||||
{
|
||||
writeLine("Mapping");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Statement& _node)
|
||||
bool ASTPrinter::visit(Statement const& _node)
|
||||
{
|
||||
writeLine("Statement");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Block& _node)
|
||||
bool ASTPrinter::visit(Block const& _node)
|
||||
{
|
||||
writeLine("Block");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(IfStatement& _node)
|
||||
bool ASTPrinter::visit(IfStatement const& _node)
|
||||
{
|
||||
writeLine("IfStatement");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(BreakableStatement& _node)
|
||||
bool ASTPrinter::visit(BreakableStatement const& _node)
|
||||
{
|
||||
writeLine("BreakableStatement");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(WhileStatement& _node)
|
||||
bool ASTPrinter::visit(WhileStatement const& _node)
|
||||
{
|
||||
writeLine("WhileStatement");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Continue& _node)
|
||||
bool ASTPrinter::visit(Continue const& _node)
|
||||
{
|
||||
writeLine("Continue");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Break& _node)
|
||||
bool ASTPrinter::visit(Break const& _node)
|
||||
{
|
||||
writeLine("Break");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Return& _node)
|
||||
bool ASTPrinter::visit(Return const& _node)
|
||||
{
|
||||
writeLine("Return");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(VariableDefinition& _node)
|
||||
bool ASTPrinter::visit(VariableDefinition const& _node)
|
||||
{
|
||||
writeLine("VariableDefinition");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(ExpressionStatement& _node)
|
||||
bool ASTPrinter::visit(ExpressionStatement const& _node)
|
||||
{
|
||||
writeLine("ExpressionStatement");
|
||||
printSourcePart(_node);
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Expression& _node)
|
||||
bool ASTPrinter::visit(Expression const& _node)
|
||||
{
|
||||
writeLine("Expression");
|
||||
printType(_node);
|
||||
@ -193,7 +193,7 @@ bool ASTPrinter::visit(Expression& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Assignment& _node)
|
||||
bool ASTPrinter::visit(Assignment const& _node)
|
||||
{
|
||||
writeLine(string("Assignment using operator ") + Token::toString(_node.getAssignmentOperator()));
|
||||
printType(_node);
|
||||
@ -201,7 +201,7 @@ bool ASTPrinter::visit(Assignment& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(UnaryOperation& _node)
|
||||
bool ASTPrinter::visit(UnaryOperation const& _node)
|
||||
{
|
||||
writeLine(string("UnaryOperation (") + (_node.isPrefixOperation() ? "prefix" : "postfix") +
|
||||
") " + Token::toString(_node.getOperator()));
|
||||
@ -210,7 +210,7 @@ bool ASTPrinter::visit(UnaryOperation& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(BinaryOperation& _node)
|
||||
bool ASTPrinter::visit(BinaryOperation const& _node)
|
||||
{
|
||||
writeLine(string("BinaryOperation using operator ") + Token::toString(_node.getOperator()));
|
||||
printType(_node);
|
||||
@ -218,7 +218,7 @@ bool ASTPrinter::visit(BinaryOperation& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(FunctionCall& _node)
|
||||
bool ASTPrinter::visit(FunctionCall const& _node)
|
||||
{
|
||||
writeLine("FunctionCall");
|
||||
printType(_node);
|
||||
@ -226,7 +226,7 @@ bool ASTPrinter::visit(FunctionCall& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(MemberAccess& _node)
|
||||
bool ASTPrinter::visit(MemberAccess const& _node)
|
||||
{
|
||||
writeLine("MemberAccess to member " + _node.getMemberName());
|
||||
printType(_node);
|
||||
@ -234,7 +234,7 @@ bool ASTPrinter::visit(MemberAccess& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(IndexAccess& _node)
|
||||
bool ASTPrinter::visit(IndexAccess const& _node)
|
||||
{
|
||||
writeLine("IndexAccess");
|
||||
printType(_node);
|
||||
@ -242,7 +242,7 @@ bool ASTPrinter::visit(IndexAccess& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(PrimaryExpression& _node)
|
||||
bool ASTPrinter::visit(PrimaryExpression const& _node)
|
||||
{
|
||||
writeLine("PrimaryExpression");
|
||||
printType(_node);
|
||||
@ -250,7 +250,7 @@ bool ASTPrinter::visit(PrimaryExpression& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Identifier& _node)
|
||||
bool ASTPrinter::visit(Identifier const& _node)
|
||||
{
|
||||
writeLine(string("Identifier ") + _node.getName());
|
||||
printType(_node);
|
||||
@ -258,7 +258,7 @@ bool ASTPrinter::visit(Identifier& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(ElementaryTypeNameExpression& _node)
|
||||
bool ASTPrinter::visit(ElementaryTypeNameExpression const& _node)
|
||||
{
|
||||
writeLine(string("ElementaryTypeNameExpression ") + Token::toString(_node.getTypeToken()));
|
||||
printType(_node);
|
||||
@ -266,7 +266,7 @@ bool ASTPrinter::visit(ElementaryTypeNameExpression& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
bool ASTPrinter::visit(Literal& _node)
|
||||
bool ASTPrinter::visit(Literal const& _node)
|
||||
{
|
||||
char const* tokenString = Token::toString(_node.getToken());
|
||||
if (!tokenString)
|
||||
@ -277,157 +277,157 @@ bool ASTPrinter::visit(Literal& _node)
|
||||
return goDeeper();
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(ImportDirective&)
|
||||
void ASTPrinter::endVisit(ImportDirective const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(ContractDefinition&)
|
||||
void ASTPrinter::endVisit(ContractDefinition const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(StructDefinition&)
|
||||
void ASTPrinter::endVisit(StructDefinition const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(ParameterList&)
|
||||
void ASTPrinter::endVisit(ParameterList const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(FunctionDefinition&)
|
||||
void ASTPrinter::endVisit(FunctionDefinition const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(VariableDeclaration&)
|
||||
void ASTPrinter::endVisit(VariableDeclaration const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(TypeName&)
|
||||
void ASTPrinter::endVisit(TypeName const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(ElementaryTypeName&)
|
||||
void ASTPrinter::endVisit(ElementaryTypeName const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(UserDefinedTypeName&)
|
||||
void ASTPrinter::endVisit(UserDefinedTypeName const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Mapping&)
|
||||
void ASTPrinter::endVisit(Mapping const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Statement&)
|
||||
void ASTPrinter::endVisit(Statement const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Block&)
|
||||
void ASTPrinter::endVisit(Block const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(IfStatement&)
|
||||
void ASTPrinter::endVisit(IfStatement const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(BreakableStatement&)
|
||||
void ASTPrinter::endVisit(BreakableStatement const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(WhileStatement&)
|
||||
void ASTPrinter::endVisit(WhileStatement const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Continue&)
|
||||
void ASTPrinter::endVisit(Continue const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Break&)
|
||||
void ASTPrinter::endVisit(Break const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Return&)
|
||||
void ASTPrinter::endVisit(Return const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(VariableDefinition&)
|
||||
void ASTPrinter::endVisit(VariableDefinition const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(ExpressionStatement&)
|
||||
void ASTPrinter::endVisit(ExpressionStatement const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Expression&)
|
||||
void ASTPrinter::endVisit(Expression const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Assignment&)
|
||||
void ASTPrinter::endVisit(Assignment const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(UnaryOperation&)
|
||||
void ASTPrinter::endVisit(UnaryOperation const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(BinaryOperation&)
|
||||
void ASTPrinter::endVisit(BinaryOperation const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(FunctionCall&)
|
||||
void ASTPrinter::endVisit(FunctionCall const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(MemberAccess&)
|
||||
void ASTPrinter::endVisit(MemberAccess const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(IndexAccess&)
|
||||
void ASTPrinter::endVisit(IndexAccess const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(PrimaryExpression&)
|
||||
void ASTPrinter::endVisit(PrimaryExpression const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Identifier&)
|
||||
void ASTPrinter::endVisit(Identifier const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(ElementaryTypeNameExpression&)
|
||||
void ASTPrinter::endVisit(ElementaryTypeNameExpression const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
||||
void ASTPrinter::endVisit(Literal&)
|
||||
void ASTPrinter::endVisit(Literal const&)
|
||||
{
|
||||
m_indentation--;
|
||||
}
|
||||
|
130
ASTPrinter.h
130
ASTPrinter.h
@ -33,78 +33,78 @@ namespace solidity
|
||||
/**
|
||||
* Pretty-printer for the abstract syntax tree (the "pretty" is arguable) for debugging purposes.
|
||||
*/
|
||||
class ASTPrinter: public ASTVisitor
|
||||
class ASTPrinter: public ASTConstVisitor
|
||||
{
|
||||
public:
|
||||
/// Create a printer for the given abstract syntax tree. If the source is specified,
|
||||
/// the corresponding parts of the source are printed with each node.
|
||||
ASTPrinter(ASTNode& _ast, std::string const& _source = std::string());
|
||||
ASTPrinter(ASTNode const& _ast, std::string const& _source = std::string());
|
||||
/// Output the string representation of the AST to _stream.
|
||||
void print(std::ostream& _stream);
|
||||
|
||||
bool visit(ImportDirective& _node) override;
|
||||
bool visit(ContractDefinition& _node) override;
|
||||
bool visit(StructDefinition& _node) override;
|
||||
bool visit(ParameterList& _node) override;
|
||||
bool visit(FunctionDefinition& _node) override;
|
||||
bool visit(VariableDeclaration& _node) override;
|
||||
bool visit(TypeName& _node) override;
|
||||
bool visit(ElementaryTypeName& _node) override;
|
||||
bool visit(UserDefinedTypeName& _node) override;
|
||||
bool visit(Mapping& _node) override;
|
||||
bool visit(Statement& _node) override;
|
||||
bool visit(Block& _node) override;
|
||||
bool visit(IfStatement& _node) override;
|
||||
bool visit(BreakableStatement& _node) override;
|
||||
bool visit(WhileStatement& _node) override;
|
||||
bool visit(Continue& _node) override;
|
||||
bool visit(Break& _node) override;
|
||||
bool visit(Return& _node) override;
|
||||
bool visit(VariableDefinition& _node) override;
|
||||
bool visit(ExpressionStatement& _node) override;
|
||||
bool visit(Expression& _node) override;
|
||||
bool visit(Assignment& _node) override;
|
||||
bool visit(UnaryOperation& _node) override;
|
||||
bool visit(BinaryOperation& _node) override;
|
||||
bool visit(FunctionCall& _node) override;
|
||||
bool visit(MemberAccess& _node) override;
|
||||
bool visit(IndexAccess& _node) override;
|
||||
bool visit(PrimaryExpression& _node) override;
|
||||
bool visit(Identifier& _node) override;
|
||||
bool visit(ElementaryTypeNameExpression& _node) override;
|
||||
bool visit(Literal& _node) override;
|
||||
bool visit(ImportDirective const& _node) override;
|
||||
bool visit(ContractDefinition const& _node) override;
|
||||
bool visit(StructDefinition const& _node) override;
|
||||
bool visit(ParameterList const& _node) override;
|
||||
bool visit(FunctionDefinition const& _node) override;
|
||||
bool visit(VariableDeclaration const& _node) override;
|
||||
bool visit(TypeName const& _node) override;
|
||||
bool visit(ElementaryTypeName const& _node) override;
|
||||
bool visit(UserDefinedTypeName const& _node) override;
|
||||
bool visit(Mapping const& _node) override;
|
||||
bool visit(Statement const& _node) override;
|
||||
bool visit(Block const& _node) override;
|
||||
bool visit(IfStatement const& _node) override;
|
||||
bool visit(BreakableStatement const& _node) override;
|
||||
bool visit(WhileStatement const& _node) override;
|
||||
bool visit(Continue const& _node) override;
|
||||
bool visit(Break const& _node) override;
|
||||
bool visit(Return const& _node) override;
|
||||
bool visit(VariableDefinition const& _node) override;
|
||||
bool visit(ExpressionStatement const& _node) override;
|
||||
bool visit(Expression const& _node) override;
|
||||
bool visit(Assignment const& _node) override;
|
||||
bool visit(UnaryOperation const& _node) override;
|
||||
bool visit(BinaryOperation const& _node) override;
|
||||
bool visit(FunctionCall const& _node) override;
|
||||
bool visit(MemberAccess const& _node) override;
|
||||
bool visit(IndexAccess const& _node) override;
|
||||
bool visit(PrimaryExpression const& _node) override;
|
||||
bool visit(Identifier const& _node) override;
|
||||
bool visit(ElementaryTypeNameExpression const& _node) override;
|
||||
bool visit(Literal const& _node) override;
|
||||
|
||||
void endVisit(ImportDirective&) override;
|
||||
void endVisit(ContractDefinition&) override;
|
||||
void endVisit(StructDefinition&) override;
|
||||
void endVisit(ParameterList&) override;
|
||||
void endVisit(FunctionDefinition&) override;
|
||||
void endVisit(VariableDeclaration&) override;
|
||||
void endVisit(TypeName&) override;
|
||||
void endVisit(ElementaryTypeName&) override;
|
||||
void endVisit(UserDefinedTypeName&) override;
|
||||
void endVisit(Mapping&) override;
|
||||
void endVisit(Statement&) override;
|
||||
void endVisit(Block&) override;
|
||||
void endVisit(IfStatement&) override;
|
||||
void endVisit(BreakableStatement&) override;
|
||||
void endVisit(WhileStatement&) override;
|
||||
void endVisit(Continue&) override;
|
||||
void endVisit(Break&) override;
|
||||
void endVisit(Return&) override;
|
||||
void endVisit(VariableDefinition&) override;
|
||||
void endVisit(ExpressionStatement&) override;
|
||||
void endVisit(Expression&) override;
|
||||
void endVisit(Assignment&) override;
|
||||
void endVisit(UnaryOperation&) override;
|
||||
void endVisit(BinaryOperation&) override;
|
||||
void endVisit(FunctionCall&) override;
|
||||
void endVisit(MemberAccess&) override;
|
||||
void endVisit(IndexAccess&) override;
|
||||
void endVisit(PrimaryExpression&) override;
|
||||
void endVisit(Identifier&) override;
|
||||
void endVisit(ElementaryTypeNameExpression&) override;
|
||||
void endVisit(Literal&) override;
|
||||
void endVisit(ImportDirective const&) override;
|
||||
void endVisit(ContractDefinition const&) override;
|
||||
void endVisit(StructDefinition const&) override;
|
||||
void endVisit(ParameterList const&) override;
|
||||
void endVisit(FunctionDefinition const&) override;
|
||||
void endVisit(VariableDeclaration const&) override;
|
||||
void endVisit(TypeName const&) override;
|
||||
void endVisit(ElementaryTypeName const&) override;
|
||||
void endVisit(UserDefinedTypeName const&) override;
|
||||
void endVisit(Mapping const&) override;
|
||||
void endVisit(Statement const&) override;
|
||||
void endVisit(Block const&) override;
|
||||
void endVisit(IfStatement const&) override;
|
||||
void endVisit(BreakableStatement const&) override;
|
||||
void endVisit(WhileStatement const&) override;
|
||||
void endVisit(Continue const&) override;
|
||||
void endVisit(Break const&) override;
|
||||
void endVisit(Return const&) override;
|
||||
void endVisit(VariableDefinition const&) override;
|
||||
void endVisit(ExpressionStatement const&) override;
|
||||
void endVisit(Expression const&) override;
|
||||
void endVisit(Assignment const&) override;
|
||||
void endVisit(UnaryOperation const&) override;
|
||||
void endVisit(BinaryOperation const&) override;
|
||||
void endVisit(FunctionCall const&) override;
|
||||
void endVisit(MemberAccess const&) override;
|
||||
void endVisit(IndexAccess const&) override;
|
||||
void endVisit(PrimaryExpression const&) override;
|
||||
void endVisit(Identifier const&) override;
|
||||
void endVisit(ElementaryTypeNameExpression const&) override;
|
||||
void endVisit(Literal const&) override;
|
||||
|
||||
private:
|
||||
void printSourcePart(ASTNode const& _node);
|
||||
@ -115,7 +115,7 @@ private:
|
||||
|
||||
int m_indentation;
|
||||
std::string m_source;
|
||||
ASTNode* m_ast;
|
||||
ASTNode const* m_ast;
|
||||
std::ostream* m_ostream;
|
||||
};
|
||||
|
||||
|
72
ASTVisitor.h
72
ASTVisitor.h
@ -110,5 +110,77 @@ public:
|
||||
virtual void endVisit(Literal&) { }
|
||||
};
|
||||
|
||||
class ASTConstVisitor
|
||||
{
|
||||
public:
|
||||
virtual bool visit(ASTNode const&) { return true; }
|
||||
virtual bool visit(SourceUnit const&) { return true; }
|
||||
virtual bool visit(ImportDirective const&) { return true; }
|
||||
virtual bool visit(ContractDefinition const&) { return true; }
|
||||
virtual bool visit(StructDefinition const&) { return true; }
|
||||
virtual bool visit(ParameterList const&) { return true; }
|
||||
virtual bool visit(FunctionDefinition const&) { return true; }
|
||||
virtual bool visit(VariableDeclaration const&) { return true; }
|
||||
virtual bool visit(TypeName const&) { return true; }
|
||||
virtual bool visit(ElementaryTypeName const&) { return true; }
|
||||
virtual bool visit(UserDefinedTypeName const&) { return true; }
|
||||
virtual bool visit(Mapping const&) { return true; }
|
||||
virtual bool visit(Statement const&) { return true; }
|
||||
virtual bool visit(Block const&) { return true; }
|
||||
virtual bool visit(IfStatement const&) { return true; }
|
||||
virtual bool visit(BreakableStatement const&) { return true; }
|
||||
virtual bool visit(WhileStatement const&) { return true; }
|
||||
virtual bool visit(Continue const&) { return true; }
|
||||
virtual bool visit(Break const&) { return true; }
|
||||
virtual bool visit(Return const&) { return true; }
|
||||
virtual bool visit(VariableDefinition const&) { return true; }
|
||||
virtual bool visit(ExpressionStatement const&) { return true; }
|
||||
virtual bool visit(Expression const&) { return true; }
|
||||
virtual bool visit(Assignment const&) { return true; }
|
||||
virtual bool visit(UnaryOperation const&) { return true; }
|
||||
virtual bool visit(BinaryOperation const&) { return true; }
|
||||
virtual bool visit(FunctionCall const&) { return true; }
|
||||
virtual bool visit(MemberAccess const&) { return true; }
|
||||
virtual bool visit(IndexAccess const&) { return true; }
|
||||
virtual bool visit(PrimaryExpression const&) { return true; }
|
||||
virtual bool visit(Identifier const&) { return true; }
|
||||
virtual bool visit(ElementaryTypeNameExpression const&) { return true; }
|
||||
virtual bool visit(Literal const&) { return true; }
|
||||
|
||||
virtual void endVisit(ASTNode const&) { }
|
||||
virtual void endVisit(SourceUnit const&) { }
|
||||
virtual void endVisit(ImportDirective const&) { }
|
||||
virtual void endVisit(ContractDefinition const&) { }
|
||||
virtual void endVisit(StructDefinition const&) { }
|
||||
virtual void endVisit(ParameterList const&) { }
|
||||
virtual void endVisit(FunctionDefinition const&) { }
|
||||
virtual void endVisit(VariableDeclaration const&) { }
|
||||
virtual void endVisit(TypeName const&) { }
|
||||
virtual void endVisit(ElementaryTypeName const&) { }
|
||||
virtual void endVisit(UserDefinedTypeName const&) { }
|
||||
virtual void endVisit(Mapping const&) { }
|
||||
virtual void endVisit(Statement const&) { }
|
||||
virtual void endVisit(Block const&) { }
|
||||
virtual void endVisit(IfStatement const&) { }
|
||||
virtual void endVisit(BreakableStatement const&) { }
|
||||
virtual void endVisit(WhileStatement const&) { }
|
||||
virtual void endVisit(Continue const&) { }
|
||||
virtual void endVisit(Break const&) { }
|
||||
virtual void endVisit(Return const&) { }
|
||||
virtual void endVisit(VariableDefinition const&) { }
|
||||
virtual void endVisit(ExpressionStatement const&) { }
|
||||
virtual void endVisit(Expression const&) { }
|
||||
virtual void endVisit(Assignment const&) { }
|
||||
virtual void endVisit(UnaryOperation const&) { }
|
||||
virtual void endVisit(BinaryOperation const&) { }
|
||||
virtual void endVisit(FunctionCall const&) { }
|
||||
virtual void endVisit(MemberAccess const&) { }
|
||||
virtual void endVisit(IndexAccess const&) { }
|
||||
virtual void endVisit(PrimaryExpression const&) { }
|
||||
virtual void endVisit(Identifier const&) { }
|
||||
virtual void endVisit(ElementaryTypeNameExpression const&) { }
|
||||
virtual void endVisit(Literal const&) { }
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
493
AST_accept.h
Normal file
493
AST_accept.h
Normal file
@ -0,0 +1,493 @@
|
||||
/*
|
||||
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
|
||||
* Implementation of the accept functions of AST nodes, included by AST.cpp to not clutter that
|
||||
* file with these mechanical implementations.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <libsolidity/AST.h>
|
||||
#include <libsolidity/ASTVisitor.h>
|
||||
|
||||
namespace dev
|
||||
{
|
||||
namespace solidity
|
||||
{
|
||||
|
||||
void SourceUnit::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
listAccept(m_nodes, _visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void SourceUnit::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
listAccept(m_nodes, _visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ImportDirective::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ImportDirective::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ContractDefinition::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
listAccept(m_definedStructs, _visitor);
|
||||
listAccept(m_stateVariables, _visitor);
|
||||
listAccept(m_definedFunctions, _visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ContractDefinition::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
listAccept(m_definedStructs, _visitor);
|
||||
listAccept(m_stateVariables, _visitor);
|
||||
listAccept(m_definedFunctions, _visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void StructDefinition::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
listAccept(m_members, _visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void StructDefinition::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
listAccept(m_members, _visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void StructDefinition::checkValidityOfMembers() const
|
||||
{
|
||||
checkMemberTypes();
|
||||
checkRecursion();
|
||||
}
|
||||
|
||||
void ParameterList::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
listAccept(m_parameters, _visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ParameterList::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
listAccept(m_parameters, _visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void FunctionDefinition::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_parameters->accept(_visitor);
|
||||
if (m_returnParameters)
|
||||
m_returnParameters->accept(_visitor);
|
||||
m_body->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void FunctionDefinition::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_parameters->accept(_visitor);
|
||||
if (m_returnParameters)
|
||||
m_returnParameters->accept(_visitor);
|
||||
m_body->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void VariableDeclaration::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
if (m_typeName)
|
||||
m_typeName->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void VariableDeclaration::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
if (m_typeName)
|
||||
m_typeName->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void TypeName::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void TypeName::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ElementaryTypeName::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ElementaryTypeName::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void UserDefinedTypeName::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void UserDefinedTypeName::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Mapping::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_keyType->accept(_visitor);
|
||||
m_valueType->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Mapping::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_keyType->accept(_visitor);
|
||||
m_valueType->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Block::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
listAccept(m_statements, _visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Block::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
listAccept(m_statements, _visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void IfStatement::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_condition->accept(_visitor);
|
||||
m_trueBody->accept(_visitor);
|
||||
if (m_falseBody)
|
||||
m_falseBody->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void IfStatement::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_condition->accept(_visitor);
|
||||
m_trueBody->accept(_visitor);
|
||||
if (m_falseBody)
|
||||
m_falseBody->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void WhileStatement::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_condition->accept(_visitor);
|
||||
m_body->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void WhileStatement::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_condition->accept(_visitor);
|
||||
m_body->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Continue::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Continue::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Break::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Break::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Return::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
if (m_expression)
|
||||
m_expression->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Return::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
if (m_expression)
|
||||
m_expression->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ExpressionStatement::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
if (m_expression)
|
||||
m_expression->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ExpressionStatement::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
if (m_expression)
|
||||
m_expression->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void VariableDefinition::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_variable->accept(_visitor);
|
||||
if (m_value)
|
||||
m_value->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void VariableDefinition::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_variable->accept(_visitor);
|
||||
if (m_value)
|
||||
m_value->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Assignment::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_leftHandSide->accept(_visitor);
|
||||
m_rightHandSide->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Assignment::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_leftHandSide->accept(_visitor);
|
||||
m_rightHandSide->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void UnaryOperation::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
m_subExpression->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void UnaryOperation::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
m_subExpression->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void BinaryOperation::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_left->accept(_visitor);
|
||||
m_right->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void BinaryOperation::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_left->accept(_visitor);
|
||||
m_right->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void FunctionCall::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_expression->accept(_visitor);
|
||||
listAccept(m_arguments, _visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void FunctionCall::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_expression->accept(_visitor);
|
||||
listAccept(m_arguments, _visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void MemberAccess::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
m_expression->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void MemberAccess::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
m_expression->accept(_visitor);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void IndexAccess::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_base->accept(_visitor);
|
||||
m_index->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void IndexAccess::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
if (_visitor.visit(*this))
|
||||
{
|
||||
m_base->accept(_visitor);
|
||||
m_index->accept(_visitor);
|
||||
}
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Identifier::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Identifier::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ElementaryTypeNameExpression::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void ElementaryTypeNameExpression::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Literal::accept(ASTVisitor& _visitor)
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
void Literal::accept(ASTConstVisitor& _visitor) const
|
||||
{
|
||||
_visitor.visit(*this);
|
||||
_visitor.endVisit(*this);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
24
Compiler.cpp
24
Compiler.cpp
@ -33,7 +33,7 @@ using namespace std;
|
||||
namespace dev {
|
||||
namespace solidity {
|
||||
|
||||
void Compiler::compileContract(ContractDefinition& _contract, vector<MagicVariableDeclaration const*> const& _magicGlobals)
|
||||
void Compiler::compileContract(ContractDefinition const& _contract, vector<MagicVariableDeclaration const*> const& _magicGlobals)
|
||||
{
|
||||
m_context = CompilerContext(); // clear it just in case
|
||||
|
||||
@ -182,7 +182,7 @@ void Compiler::registerStateVariables(ContractDefinition const& _contract)
|
||||
m_context.addStateVariable(*variable);
|
||||
}
|
||||
|
||||
bool Compiler::visit(FunctionDefinition& _function)
|
||||
bool Compiler::visit(FunctionDefinition const& _function)
|
||||
{
|
||||
//@todo to simplify this, the calling convention could by changed such that
|
||||
// caller puts: [retarg0] ... [retargm] [return address] [arg0] ... [argn]
|
||||
@ -244,7 +244,7 @@ bool Compiler::visit(FunctionDefinition& _function)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::visit(IfStatement& _ifStatement)
|
||||
bool Compiler::visit(IfStatement const& _ifStatement)
|
||||
{
|
||||
ExpressionCompiler::compileExpression(m_context, _ifStatement.getCondition());
|
||||
eth::AssemblyItem trueTag = m_context.appendConditionalJump();
|
||||
@ -257,7 +257,7 @@ bool Compiler::visit(IfStatement& _ifStatement)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::visit(WhileStatement& _whileStatement)
|
||||
bool Compiler::visit(WhileStatement const& _whileStatement)
|
||||
{
|
||||
eth::AssemblyItem loopStart = m_context.newTag();
|
||||
eth::AssemblyItem loopEnd = m_context.newTag();
|
||||
@ -279,24 +279,24 @@ bool Compiler::visit(WhileStatement& _whileStatement)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::visit(Continue&)
|
||||
bool Compiler::visit(Continue const&)
|
||||
{
|
||||
if (!m_continueTags.empty())
|
||||
m_context.appendJumpTo(m_continueTags.back());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::visit(Break&)
|
||||
bool Compiler::visit(Break const&)
|
||||
{
|
||||
if (!m_breakTags.empty())
|
||||
m_context.appendJumpTo(m_breakTags.back());
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::visit(Return& _return)
|
||||
bool Compiler::visit(Return const& _return)
|
||||
{
|
||||
//@todo modifications are needed to make this work with functions returning multiple values
|
||||
if (Expression* expression = _return.getExpression())
|
||||
if (Expression const* expression = _return.getExpression())
|
||||
{
|
||||
ExpressionCompiler::compileExpression(m_context, *expression);
|
||||
VariableDeclaration const& firstVariable = *_return.getFunctionReturnParameters().getParameters().front();
|
||||
@ -308,9 +308,9 @@ bool Compiler::visit(Return& _return)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::visit(VariableDefinition& _variableDefinition)
|
||||
bool Compiler::visit(VariableDefinition const& _variableDefinition)
|
||||
{
|
||||
if (Expression* expression = _variableDefinition.getExpression())
|
||||
if (Expression const* expression = _variableDefinition.getExpression())
|
||||
{
|
||||
ExpressionCompiler::compileExpression(m_context, *expression);
|
||||
ExpressionCompiler::appendTypeConversion(m_context,
|
||||
@ -321,9 +321,9 @@ bool Compiler::visit(VariableDefinition& _variableDefinition)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Compiler::visit(ExpressionStatement& _expressionStatement)
|
||||
bool Compiler::visit(ExpressionStatement const& _expressionStatement)
|
||||
{
|
||||
Expression& expression = _expressionStatement.getExpression();
|
||||
Expression const& expression = _expressionStatement.getExpression();
|
||||
ExpressionCompiler::compileExpression(m_context, expression);
|
||||
CompilerUtils(m_context).popStackElement(*expression.getType());
|
||||
return false;
|
||||
|
20
Compiler.h
20
Compiler.h
@ -27,12 +27,12 @@
|
||||
namespace dev {
|
||||
namespace solidity {
|
||||
|
||||
class Compiler: private ASTVisitor
|
||||
class Compiler: private ASTConstVisitor
|
||||
{
|
||||
public:
|
||||
Compiler(): m_returnTag(m_context.newTag()) {}
|
||||
|
||||
void compileContract(ContractDefinition& _contract, std::vector<MagicVariableDeclaration const*> const& _magicGlobals);
|
||||
void compileContract(ContractDefinition const& _contract, std::vector<MagicVariableDeclaration const*> const& _magicGlobals);
|
||||
bytes getAssembledBytecode(bool _optimize = false) { return m_context.getAssembledBytecode(_optimize); }
|
||||
void streamAssembly(std::ostream& _stream) const { m_context.streamAssembly(_stream); }
|
||||
|
||||
@ -48,14 +48,14 @@ private:
|
||||
|
||||
void registerStateVariables(ContractDefinition const& _contract);
|
||||
|
||||
virtual bool visit(FunctionDefinition& _function) override;
|
||||
virtual bool visit(IfStatement& _ifStatement) override;
|
||||
virtual bool visit(WhileStatement& _whileStatement) override;
|
||||
virtual bool visit(Continue& _continue) override;
|
||||
virtual bool visit(Break& _break) override;
|
||||
virtual bool visit(Return& _return) override;
|
||||
virtual bool visit(VariableDefinition& _variableDefinition) override;
|
||||
virtual bool visit(ExpressionStatement& _expressionStatement) override;
|
||||
virtual bool visit(FunctionDefinition const& _function) override;
|
||||
virtual bool visit(IfStatement const& _ifStatement) override;
|
||||
virtual bool visit(WhileStatement const& _whileStatement) override;
|
||||
virtual bool visit(Continue const& _continue) override;
|
||||
virtual bool visit(Break const& _break) override;
|
||||
virtual bool visit(Return const& _return) override;
|
||||
virtual bool visit(VariableDefinition const& _variableDefinition) override;
|
||||
virtual bool visit(ExpressionStatement const& _expressionStatement) override;
|
||||
|
||||
|
||||
CompilerContext m_context;
|
||||
|
@ -82,7 +82,7 @@ void CompilerStack::parse(string const& _sourceCode)
|
||||
parse();
|
||||
}
|
||||
|
||||
vector<string> CompilerStack::getContractNames()
|
||||
vector<string> CompilerStack::getContractNames() const
|
||||
{
|
||||
if (!m_parseSuccessful)
|
||||
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
|
||||
@ -116,29 +116,29 @@ bytes const& CompilerStack::compile(string const& _sourceCode, bool _optimize)
|
||||
return getBytecode();
|
||||
}
|
||||
|
||||
bytes const& CompilerStack::getBytecode(string const& _contractName)
|
||||
bytes const& CompilerStack::getBytecode(string const& _contractName) const
|
||||
{
|
||||
return getContract(_contractName).bytecode;
|
||||
}
|
||||
|
||||
void CompilerStack::streamAssembly(ostream& _outStream, string const& _contractName)
|
||||
void CompilerStack::streamAssembly(ostream& _outStream, string const& _contractName) const
|
||||
{
|
||||
getContract(_contractName).compiler->streamAssembly(_outStream);
|
||||
}
|
||||
|
||||
string const& CompilerStack::getInterface(std::string const& _contractName)
|
||||
string const& CompilerStack::getInterface(string const& _contractName) const
|
||||
{
|
||||
return getJsonDocumentation(_contractName, DocumentationType::ABI_INTERFACE);
|
||||
}
|
||||
|
||||
std::string const& CompilerStack::getJsonDocumentation(std::string const& _contractName, DocumentationType _type)
|
||||
string const& CompilerStack::getJsonDocumentation(string const& _contractName, DocumentationType _type) const
|
||||
{
|
||||
if (!m_parseSuccessful)
|
||||
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("Parsing was not successful."));
|
||||
|
||||
Contract& contract = getContract(_contractName);
|
||||
Contract const& contract = getContract(_contractName);
|
||||
|
||||
std::unique_ptr<string>* doc;
|
||||
std::unique_ptr<string const>* doc;
|
||||
switch (_type)
|
||||
{
|
||||
case DocumentationType::NATSPEC_USER:
|
||||
@ -158,12 +158,12 @@ std::string const& CompilerStack::getJsonDocumentation(std::string const& _contr
|
||||
return *(*doc);
|
||||
}
|
||||
|
||||
Scanner const& CompilerStack::getScanner(string const& _sourceName)
|
||||
Scanner const& CompilerStack::getScanner(string const& _sourceName) const
|
||||
{
|
||||
return *getSource(_sourceName).scanner;
|
||||
}
|
||||
|
||||
SourceUnit& CompilerStack::getAST(string const& _sourceName)
|
||||
SourceUnit const& CompilerStack::getAST(string const& _sourceName) const
|
||||
{
|
||||
return *getSource(_sourceName).ast;
|
||||
}
|
||||
@ -217,7 +217,7 @@ void CompilerStack::resolveImports()
|
||||
swap(m_sourceOrder, sourceOrder);
|
||||
}
|
||||
|
||||
CompilerStack::Contract& CompilerStack::getContract(string const& _contractName)
|
||||
CompilerStack::Contract const& CompilerStack::getContract(string const& _contractName) const
|
||||
{
|
||||
if (m_contracts.empty())
|
||||
BOOST_THROW_EXCEPTION(CompilerError() << errinfo_comment("No compiled contracts found."));
|
||||
@ -229,7 +229,7 @@ CompilerStack::Contract& CompilerStack::getContract(string const& _contractName)
|
||||
return it->second;
|
||||
}
|
||||
|
||||
CompilerStack::Source& CompilerStack::getSource(string const& _sourceName)
|
||||
CompilerStack::Source const& CompilerStack::getSource(string const& _sourceName) const
|
||||
{
|
||||
auto it = m_sources.find(_sourceName);
|
||||
if (it == m_sources.end())
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
/// Sets the given source code as the only source unit and parses it.
|
||||
void parse(std::string const& _sourceCode);
|
||||
/// Returns a list of the contract names in the sources.
|
||||
std::vector<std::string> getContractNames();
|
||||
std::vector<std::string> getContractNames() const;
|
||||
|
||||
/// Compiles the source units that were previously added and parsed.
|
||||
void compile(bool _optimize = false);
|
||||
@ -72,23 +72,23 @@ public:
|
||||
/// @returns the compiled bytecode
|
||||
bytes const& compile(std::string const& _sourceCode, bool _optimize = false);
|
||||
|
||||
bytes const& getBytecode(std::string const& _contractName = "");
|
||||
bytes const& getBytecode(std::string const& _contractName = "") const;
|
||||
/// Streams a verbose version of the assembly to @a _outStream.
|
||||
/// Prerequisite: Successful compilation.
|
||||
void streamAssembly(std::ostream& _outStream, std::string const& _contractName = "");
|
||||
void streamAssembly(std::ostream& _outStream, std::string const& _contractName = "") const;
|
||||
|
||||
/// Returns a string representing the contract interface in JSON.
|
||||
/// Prerequisite: Successful call to parse or compile.
|
||||
std::string const& getInterface(std::string const& _contractName = "");
|
||||
std::string const& getInterface(std::string const& _contractName = "") const;
|
||||
/// Returns a string representing the contract's documentation in JSON.
|
||||
/// Prerequisite: Successful call to parse or compile.
|
||||
/// @param type The type of the documentation to get.
|
||||
/// Can be one of 3 types defined at @c DocumentationType
|
||||
std::string const& getJsonDocumentation(std::string const& _contractName, DocumentationType _type);
|
||||
std::string const& getJsonDocumentation(std::string const& _contractName, DocumentationType _type) const;
|
||||
|
||||
/// Returns the previously used scanner, useful for counting lines during error reporting.
|
||||
Scanner const& getScanner(std::string const& _sourceName = "");
|
||||
SourceUnit& getAST(std::string const& _sourceName = "");
|
||||
Scanner const& getScanner(std::string const& _sourceName = "") const;
|
||||
SourceUnit const& getAST(std::string const& _sourceName = "") const;
|
||||
|
||||
/// Compile the given @a _sourceCode to bytecode. If a scanner is provided, it is used for
|
||||
/// scanning the source code - this is useful for printing exception information.
|
||||
@ -112,9 +112,9 @@ private:
|
||||
std::shared_ptr<Compiler> compiler;
|
||||
bytes bytecode;
|
||||
std::shared_ptr<InterfaceHandler> interfaceHandler;
|
||||
std::unique_ptr<std::string> interface;
|
||||
std::unique_ptr<std::string> userDocumentation;
|
||||
std::unique_ptr<std::string> devDocumentation;
|
||||
mutable std::unique_ptr<std::string const> interface;
|
||||
mutable std::unique_ptr<std::string const> userDocumentation;
|
||||
mutable std::unique_ptr<std::string const> devDocumentation;
|
||||
|
||||
Contract();
|
||||
};
|
||||
@ -122,14 +122,14 @@ private:
|
||||
void reset(bool _keepSources = false);
|
||||
void resolveImports();
|
||||
|
||||
Contract& getContract(std::string const& _contractName = "");
|
||||
Source& getSource(std::string const& _sourceName = "");
|
||||
Contract const& getContract(std::string const& _contractName = "") const;
|
||||
Source const& getSource(std::string const& _sourceName = "") const;
|
||||
|
||||
bool m_parseSuccessful;
|
||||
std::map<std::string, Source> m_sources;
|
||||
std::map<std::string const, Source> m_sources;
|
||||
std::shared_ptr<GlobalContext> m_globalContext;
|
||||
std::vector<Source const*> m_sourceOrder;
|
||||
std::map<std::string, Contract> m_contracts;
|
||||
std::map<std::string const, Contract> m_contracts;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace dev
|
||||
namespace solidity
|
||||
{
|
||||
|
||||
bool DeclarationContainer::registerDeclaration(Declaration& _declaration, bool _update)
|
||||
bool DeclarationContainer::registerDeclaration(Declaration const& _declaration, bool _update)
|
||||
{
|
||||
if (!_update && m_declarations.find(_declaration.getName()) != m_declarations.end())
|
||||
return false;
|
||||
@ -36,7 +36,7 @@ bool DeclarationContainer::registerDeclaration(Declaration& _declaration, bool _
|
||||
return true;
|
||||
}
|
||||
|
||||
Declaration* DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const
|
||||
Declaration const* DeclarationContainer::resolveName(ASTString const& _name, bool _recursive) const
|
||||
{
|
||||
auto result = m_declarations.find(_name);
|
||||
if (result != m_declarations.end())
|
||||
|
@ -39,18 +39,19 @@ namespace solidity
|
||||
class DeclarationContainer
|
||||
{
|
||||
public:
|
||||
explicit DeclarationContainer(Declaration* _enclosingDeclaration = nullptr, DeclarationContainer* _enclosingContainer = nullptr):
|
||||
explicit DeclarationContainer(Declaration const* _enclosingDeclaration = nullptr,
|
||||
DeclarationContainer const* _enclosingContainer = nullptr):
|
||||
m_enclosingDeclaration(_enclosingDeclaration), m_enclosingContainer(_enclosingContainer) {}
|
||||
/// Registers the declaration in the scope unless its name is already declared. Returns true iff
|
||||
/// it was not yet declared.
|
||||
bool registerDeclaration(Declaration& _declaration, bool _update = false);
|
||||
Declaration* resolveName(ASTString const& _name, bool _recursive = false) const;
|
||||
Declaration* getEnclosingDeclaration() const { return m_enclosingDeclaration; }
|
||||
bool registerDeclaration(Declaration const& _declaration, bool _update = false);
|
||||
Declaration const* resolveName(ASTString const& _name, bool _recursive = false) const;
|
||||
Declaration const* getEnclosingDeclaration() const { return m_enclosingDeclaration; }
|
||||
|
||||
private:
|
||||
Declaration* m_enclosingDeclaration;
|
||||
DeclarationContainer* m_enclosingContainer;
|
||||
std::map<ASTString, Declaration*> m_declarations;
|
||||
Declaration const* m_enclosingDeclaration;
|
||||
DeclarationContainer const* m_enclosingContainer;
|
||||
std::map<ASTString, Declaration const*> m_declarations;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ using namespace std;
|
||||
namespace dev {
|
||||
namespace solidity {
|
||||
|
||||
void ExpressionCompiler::compileExpression(CompilerContext& _context, Expression& _expression)
|
||||
void ExpressionCompiler::compileExpression(CompilerContext& _context, Expression const& _expression)
|
||||
{
|
||||
ExpressionCompiler compiler(_context);
|
||||
_expression.accept(compiler);
|
||||
@ -46,7 +46,7 @@ void ExpressionCompiler::appendTypeConversion(CompilerContext& _context,
|
||||
compiler.appendTypeConversion(_typeOnStack, _targetType);
|
||||
}
|
||||
|
||||
bool ExpressionCompiler::visit(Assignment& _assignment)
|
||||
bool ExpressionCompiler::visit(Assignment const& _assignment)
|
||||
{
|
||||
_assignment.getRightHandSide().accept(*this);
|
||||
appendTypeConversion(*_assignment.getRightHandSide().getType(), *_assignment.getType());
|
||||
@ -68,7 +68,7 @@ bool ExpressionCompiler::visit(Assignment& _assignment)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ExpressionCompiler::endVisit(UnaryOperation& _unaryOperation)
|
||||
void ExpressionCompiler::endVisit(UnaryOperation const& _unaryOperation)
|
||||
{
|
||||
//@todo type checking and creating code for an operator should be in the same place:
|
||||
// the operator should know how to convert itself and to which types it applies, so
|
||||
@ -129,10 +129,10 @@ void ExpressionCompiler::endVisit(UnaryOperation& _unaryOperation)
|
||||
}
|
||||
}
|
||||
|
||||
bool ExpressionCompiler::visit(BinaryOperation& _binaryOperation)
|
||||
bool ExpressionCompiler::visit(BinaryOperation const& _binaryOperation)
|
||||
{
|
||||
Expression& leftExpression = _binaryOperation.getLeftExpression();
|
||||
Expression& rightExpression = _binaryOperation.getRightExpression();
|
||||
Expression const& leftExpression = _binaryOperation.getLeftExpression();
|
||||
Expression const& rightExpression = _binaryOperation.getRightExpression();
|
||||
Type const& commonType = _binaryOperation.getCommonType();
|
||||
Token::Value const op = _binaryOperation.getOperator();
|
||||
|
||||
@ -159,7 +159,7 @@ bool ExpressionCompiler::visit(BinaryOperation& _binaryOperation)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ExpressionCompiler::visit(FunctionCall& _functionCall)
|
||||
bool ExpressionCompiler::visit(FunctionCall const& _functionCall)
|
||||
{
|
||||
using Location = FunctionType::Location;
|
||||
if (_functionCall.isTypeConversion())
|
||||
@ -167,7 +167,7 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall)
|
||||
//@todo struct construction
|
||||
if (asserts(_functionCall.getArguments().size() == 1))
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError());
|
||||
Expression& firstArgument = *_functionCall.getArguments().front();
|
||||
Expression const& firstArgument = *_functionCall.getArguments().front();
|
||||
firstArgument.accept(*this);
|
||||
if (firstArgument.getType()->getCategory() == Type::Category::CONTRACT &&
|
||||
_functionCall.getType()->getCategory() == Type::Category::INTEGER)
|
||||
@ -180,7 +180,7 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall)
|
||||
else
|
||||
{
|
||||
FunctionType const& function = dynamic_cast<FunctionType const&>(*_functionCall.getExpression().getType());
|
||||
std::vector<ASTPointer<Expression>> const& arguments = _functionCall.getArguments();
|
||||
std::vector<ASTPointer<Expression const>> arguments = _functionCall.getArguments();
|
||||
if (asserts(arguments.size() == function.getParameterTypes().size()))
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError());
|
||||
|
||||
@ -299,7 +299,7 @@ bool ExpressionCompiler::visit(FunctionCall& _functionCall)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ExpressionCompiler::endVisit(MemberAccess& _memberAccess)
|
||||
void ExpressionCompiler::endVisit(MemberAccess const& _memberAccess)
|
||||
{
|
||||
ASTString const& member = _memberAccess.getMemberName();
|
||||
switch (_memberAccess.getExpression().getType()->getCategory())
|
||||
@ -365,7 +365,7 @@ void ExpressionCompiler::endVisit(MemberAccess& _memberAccess)
|
||||
}
|
||||
}
|
||||
|
||||
bool ExpressionCompiler::visit(IndexAccess& _indexAccess)
|
||||
bool ExpressionCompiler::visit(IndexAccess const& _indexAccess)
|
||||
{
|
||||
_indexAccess.getBaseExpression().accept(*this);
|
||||
_indexAccess.getIndexExpression().accept(*this);
|
||||
@ -382,30 +382,30 @@ bool ExpressionCompiler::visit(IndexAccess& _indexAccess)
|
||||
return false;
|
||||
}
|
||||
|
||||
void ExpressionCompiler::endVisit(Identifier& _identifier)
|
||||
void ExpressionCompiler::endVisit(Identifier const& _identifier)
|
||||
{
|
||||
Declaration* declaration = _identifier.getReferencedDeclaration();
|
||||
if (MagicVariableDeclaration* magicVar = dynamic_cast<MagicVariableDeclaration*>(declaration))
|
||||
Declaration const* declaration = _identifier.getReferencedDeclaration();
|
||||
if (MagicVariableDeclaration const* magicVar = dynamic_cast<MagicVariableDeclaration const*>(declaration))
|
||||
{
|
||||
if (magicVar->getType()->getCategory() == Type::Category::CONTRACT) // must be "this"
|
||||
m_context << eth::Instruction::ADDRESS;
|
||||
return;
|
||||
}
|
||||
if (FunctionDefinition* functionDef = dynamic_cast<FunctionDefinition*>(declaration))
|
||||
if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration))
|
||||
{
|
||||
m_context << m_context.getFunctionEntryLabel(*functionDef).pushTag();
|
||||
return;
|
||||
}
|
||||
if (/*VariableDeclaration* varDef = */dynamic_cast<VariableDeclaration*>(declaration))
|
||||
if (dynamic_cast<VariableDeclaration const*>(declaration))
|
||||
{
|
||||
m_currentLValue.fromIdentifier(_identifier, *_identifier.getReferencedDeclaration());
|
||||
m_currentLValue.fromIdentifier(_identifier, *declaration);
|
||||
m_currentLValue.retrieveValueIfLValueNotRequested(_identifier);
|
||||
return;
|
||||
}
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Identifier type not expected in expression context."));
|
||||
}
|
||||
|
||||
void ExpressionCompiler::endVisit(Literal& _literal)
|
||||
void ExpressionCompiler::endVisit(Literal const& _literal)
|
||||
{
|
||||
switch (_literal.getType()->getCategory())
|
||||
{
|
||||
@ -418,7 +418,7 @@ void ExpressionCompiler::endVisit(Literal& _literal)
|
||||
}
|
||||
}
|
||||
|
||||
void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation& _binaryOperation)
|
||||
void ExpressionCompiler::appendAndOrOperatorCode(BinaryOperation const& _binaryOperation)
|
||||
{
|
||||
Token::Value const op = _binaryOperation.getOperator();
|
||||
if (asserts(op == Token::OR || op == Token::AND))
|
||||
|
@ -41,11 +41,11 @@ class IntegerType;
|
||||
* of EVM instructions. It needs a compiler context that is the same for the whole compilation
|
||||
* unit.
|
||||
*/
|
||||
class ExpressionCompiler: private ASTVisitor
|
||||
class ExpressionCompiler: private ASTConstVisitor
|
||||
{
|
||||
public:
|
||||
/// Compile the given @a _expression into the @a _context.
|
||||
static void compileExpression(CompilerContext& _context, Expression& _expression);
|
||||
static void compileExpression(CompilerContext& _context, Expression const& _expression);
|
||||
|
||||
/// Appends code to remove dirty higher order bits in case of an implicit promotion to a wider type.
|
||||
static void appendTypeConversion(CompilerContext& _context, Type const& _typeOnStack, Type const& _targetType);
|
||||
@ -54,18 +54,18 @@ private:
|
||||
ExpressionCompiler(CompilerContext& _compilerContext):
|
||||
m_context(_compilerContext), m_currentLValue(m_context) {}
|
||||
|
||||
virtual bool visit(Assignment& _assignment) override;
|
||||
virtual void endVisit(UnaryOperation& _unaryOperation) override;
|
||||
virtual bool visit(BinaryOperation& _binaryOperation) override;
|
||||
virtual bool visit(FunctionCall& _functionCall) override;
|
||||
virtual void endVisit(MemberAccess& _memberAccess) override;
|
||||
virtual bool visit(IndexAccess& _indexAccess) override;
|
||||
virtual void endVisit(Identifier& _identifier) override;
|
||||
virtual void endVisit(Literal& _literal) override;
|
||||
virtual bool visit(Assignment const& _assignment) override;
|
||||
virtual void endVisit(UnaryOperation const& _unaryOperation) override;
|
||||
virtual bool visit(BinaryOperation const& _binaryOperation) override;
|
||||
virtual bool visit(FunctionCall const& _functionCall) override;
|
||||
virtual void endVisit(MemberAccess const& _memberAccess) override;
|
||||
virtual bool visit(IndexAccess const& _indexAccess) override;
|
||||
virtual void endVisit(Identifier const& _identifier) override;
|
||||
virtual void endVisit(Literal const& _literal) override;
|
||||
|
||||
///@{
|
||||
///@name Append code for various operator types
|
||||
void appendAndOrOperatorCode(BinaryOperation& _binaryOperation);
|
||||
void appendAndOrOperatorCode(BinaryOperation const& _binaryOperation);
|
||||
void appendCompareOperatorCode(Token::Value _operator, Type const& _type);
|
||||
void appendOrdinaryBinaryOperatorCode(Token::Value _operator, Type const& _type);
|
||||
|
||||
@ -134,10 +134,6 @@ private:
|
||||
|
||||
CompilerContext& m_context;
|
||||
LValue m_currentLValue;
|
||||
/// If a "virtual" function (i.e. a bulit-in function without jump tag) is encountered, the
|
||||
/// actual function is stored here. @todo prevent assignment or store it with assignment
|
||||
enum class SpecialFunction { NONE, SEND, SHA3, SUICIDE, ECRECOVER, SHA256, RIPEMD160 };
|
||||
SpecialFunction m_currentSpecialFunction;
|
||||
};
|
||||
|
||||
|
||||
|
@ -33,7 +33,7 @@ namespace solidity
|
||||
{
|
||||
|
||||
GlobalContext::GlobalContext():
|
||||
m_magicVariables(vector<shared_ptr<MagicVariableDeclaration>>{make_shared<MagicVariableDeclaration>("block", make_shared<MagicType>(MagicType::Kind::BLOCK)),
|
||||
m_magicVariables(vector<shared_ptr<MagicVariableDeclaration const>>{make_shared<MagicVariableDeclaration>("block", make_shared<MagicType>(MagicType::Kind::BLOCK)),
|
||||
make_shared<MagicVariableDeclaration>("msg", make_shared<MagicType>(MagicType::Kind::MSG)),
|
||||
make_shared<MagicVariableDeclaration>("tx", make_shared<MagicType>(MagicType::Kind::TX)),
|
||||
make_shared<MagicVariableDeclaration>("suicide",
|
||||
@ -68,16 +68,16 @@ void GlobalContext::setCurrentContract(ContractDefinition const& _contract)
|
||||
m_currentContract = &_contract;
|
||||
}
|
||||
|
||||
vector<Declaration*> GlobalContext::getDeclarations() const
|
||||
vector<Declaration const*> GlobalContext::getDeclarations() const
|
||||
{
|
||||
vector<Declaration*> declarations;
|
||||
vector<Declaration const*> declarations;
|
||||
declarations.reserve(m_magicVariables.size() + 1);
|
||||
for (ASTPointer<Declaration> const& variable: m_magicVariables)
|
||||
for (ASTPointer<Declaration const> const& variable: m_magicVariables)
|
||||
declarations.push_back(variable.get());
|
||||
return declarations;
|
||||
}
|
||||
|
||||
MagicVariableDeclaration* GlobalContext::getCurrentThis() const
|
||||
MagicVariableDeclaration const* GlobalContext::getCurrentThis() const
|
||||
{
|
||||
if (!m_thisPointer[m_currentContract])
|
||||
m_thisPointer[m_currentContract] = make_shared<MagicVariableDeclaration>(
|
||||
|
@ -47,17 +47,17 @@ class GlobalContext: private boost::noncopyable
|
||||
public:
|
||||
GlobalContext();
|
||||
void setCurrentContract(ContractDefinition const& _contract);
|
||||
MagicVariableDeclaration* getCurrentThis() const;
|
||||
MagicVariableDeclaration const* getCurrentThis() const;
|
||||
|
||||
/// @returns all magic variables.
|
||||
std::vector<MagicVariableDeclaration const*> getMagicVariables() const;
|
||||
/// @returns a vector of all implicit global declarations excluding "this".
|
||||
std::vector<Declaration*> getDeclarations() const;
|
||||
std::vector<Declaration const*> getDeclarations() const;
|
||||
|
||||
private:
|
||||
std::vector<std::shared_ptr<MagicVariableDeclaration>> m_magicVariables;
|
||||
std::vector<std::shared_ptr<MagicVariableDeclaration const>> m_magicVariables;
|
||||
ContractDefinition const* m_currentContract;
|
||||
std::map<ContractDefinition const*, std::shared_ptr<MagicVariableDeclaration>> mutable m_thisPointer;
|
||||
std::map<ContractDefinition const*, std::shared_ptr<MagicVariableDeclaration const>> mutable m_thisPointer;
|
||||
};
|
||||
|
||||
}
|
||||
|
@ -75,7 +75,7 @@ std::unique_ptr<std::string> InterfaceHandler::getUserDocumentation(ContractDefi
|
||||
if (strPtr)
|
||||
{
|
||||
resetUser();
|
||||
parseDocString(*strPtr);
|
||||
parseDocString(*strPtr, CommentOwner::FUNCTION);
|
||||
if (!m_notice.empty())
|
||||
{// since @notice is the only user tag if missing function should not appear
|
||||
user["notice"] = Json::Value(m_notice);
|
||||
@ -95,6 +95,20 @@ std::unique_ptr<std::string> InterfaceHandler::getDevDocumentation(ContractDefin
|
||||
Json::Value doc;
|
||||
Json::Value methods(Json::objectValue);
|
||||
|
||||
auto contractDoc = _contractDef.getDocumentation();
|
||||
if (contractDoc)
|
||||
{
|
||||
m_contractAuthor.clear();
|
||||
m_title.clear();
|
||||
parseDocString(*contractDoc, CommentOwner::CONTRACT);
|
||||
|
||||
if (!m_contractAuthor.empty())
|
||||
doc["author"] = m_contractAuthor;
|
||||
|
||||
if (!m_title.empty())
|
||||
doc["title"] = m_title;
|
||||
}
|
||||
|
||||
for (FunctionDefinition const* f: _contractDef.getInterfaceFunctions())
|
||||
{
|
||||
Json::Value method;
|
||||
@ -102,16 +116,21 @@ std::unique_ptr<std::string> InterfaceHandler::getDevDocumentation(ContractDefin
|
||||
if (strPtr)
|
||||
{
|
||||
resetDev();
|
||||
parseDocString(*strPtr);
|
||||
parseDocString(*strPtr, CommentOwner::FUNCTION);
|
||||
|
||||
if (!m_dev.empty())
|
||||
method["details"] = Json::Value(m_dev);
|
||||
|
||||
if (!m_author.empty())
|
||||
method["author"] = m_author;
|
||||
|
||||
Json::Value params(Json::objectValue);
|
||||
for (auto const& pair: m_params)
|
||||
params[pair.first] = pair.second;
|
||||
|
||||
if (!m_params.empty())
|
||||
method["params"] = params;
|
||||
|
||||
if (!m_return.empty())
|
||||
method["return"] = m_return;
|
||||
|
||||
@ -133,6 +152,7 @@ void InterfaceHandler::resetUser()
|
||||
void InterfaceHandler::resetDev()
|
||||
{
|
||||
m_dev.clear();
|
||||
m_author.clear();
|
||||
m_return.clear();
|
||||
m_params.clear();
|
||||
}
|
||||
@ -193,10 +213,12 @@ std::string::const_iterator InterfaceHandler::appendDocTagParam(std::string::con
|
||||
|
||||
std::string::const_iterator InterfaceHandler::parseDocTag(std::string::const_iterator _pos,
|
||||
std::string::const_iterator _end,
|
||||
std::string const& _tag)
|
||||
std::string const& _tag,
|
||||
CommentOwner _owner)
|
||||
{
|
||||
// LTODO: need to check for @(start of a tag) between here and the end of line
|
||||
// for all cases
|
||||
// for all cases. Also somehow automate list of acceptable tags for each
|
||||
// language construct since current way does not scale well.
|
||||
if (m_lastTag == DocTagType::NONE || _tag != "")
|
||||
{
|
||||
if (_tag == "dev")
|
||||
@ -205,37 +227,77 @@ std::string::const_iterator InterfaceHandler::parseDocTag(std::string::const_ite
|
||||
return parseDocTagLine(_pos, _end, m_notice, DocTagType::NOTICE);
|
||||
else if (_tag == "return")
|
||||
return parseDocTagLine(_pos, _end, m_return, DocTagType::RETURN);
|
||||
else if (_tag == "author")
|
||||
{
|
||||
if (_owner == CommentOwner::CONTRACT)
|
||||
return parseDocTagLine(_pos, _end, m_contractAuthor, DocTagType::AUTHOR);
|
||||
else if (_owner == CommentOwner::FUNCTION)
|
||||
return parseDocTagLine(_pos, _end, m_author, DocTagType::AUTHOR);
|
||||
else
|
||||
// LTODO: for now this else makes no sense but later comments will go to more language constructs
|
||||
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@author tag is legal only for contracts"));
|
||||
}
|
||||
else if (_tag == "title")
|
||||
{
|
||||
if (_owner == CommentOwner::CONTRACT)
|
||||
return parseDocTagLine(_pos, _end, m_title, DocTagType::TITLE);
|
||||
else
|
||||
// LTODO: Unknown tag, throw some form of warning and not just an exception
|
||||
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@title tag is legal only for contracts"));
|
||||
}
|
||||
else if (_tag == "param")
|
||||
return parseDocTagParam(_pos, _end);
|
||||
else
|
||||
{
|
||||
// LTODO: Unknown tag, throw some form of warning and not just an exception
|
||||
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("Unknown tag " + _tag + " encountered"));
|
||||
}
|
||||
}
|
||||
else
|
||||
return appendDocTag(_pos, _end);
|
||||
return appendDocTag(_pos, _end, _owner);
|
||||
}
|
||||
|
||||
std::string::const_iterator InterfaceHandler::appendDocTag(std::string::const_iterator _pos,
|
||||
std::string::const_iterator _end)
|
||||
std::string::const_iterator _end,
|
||||
CommentOwner _owner)
|
||||
{
|
||||
switch (m_lastTag)
|
||||
{
|
||||
case DocTagType::DEV:
|
||||
m_dev += " ";
|
||||
return parseDocTagLine(_pos, _end, m_dev, DocTagType::DEV);
|
||||
case DocTagType::NOTICE:
|
||||
m_notice += " ";
|
||||
return parseDocTagLine(_pos, _end, m_notice, DocTagType::NOTICE);
|
||||
case DocTagType::RETURN:
|
||||
m_return += " ";
|
||||
return parseDocTagLine(_pos, _end, m_return, DocTagType::RETURN);
|
||||
case DocTagType::PARAM:
|
||||
return appendDocTagParam(_pos, _end);
|
||||
default:
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Internal: Illegal documentation tag type"));
|
||||
break;
|
||||
case DocTagType::DEV:
|
||||
m_dev += " ";
|
||||
return parseDocTagLine(_pos, _end, m_dev, DocTagType::DEV);
|
||||
case DocTagType::NOTICE:
|
||||
m_notice += " ";
|
||||
return parseDocTagLine(_pos, _end, m_notice, DocTagType::NOTICE);
|
||||
case DocTagType::RETURN:
|
||||
m_return += " ";
|
||||
return parseDocTagLine(_pos, _end, m_return, DocTagType::RETURN);
|
||||
case DocTagType::AUTHOR:
|
||||
if (_owner == CommentOwner::CONTRACT)
|
||||
{
|
||||
m_contractAuthor += " ";
|
||||
return parseDocTagLine(_pos, _end, m_contractAuthor, DocTagType::AUTHOR);
|
||||
}
|
||||
else if (_owner == CommentOwner::FUNCTION)
|
||||
{
|
||||
m_author += " ";
|
||||
return parseDocTagLine(_pos, _end, m_author, DocTagType::AUTHOR);
|
||||
}
|
||||
else
|
||||
// LTODO: Unknown tag, throw some form of warning and not just an exception
|
||||
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@author tag in illegal comment"));
|
||||
case DocTagType::TITLE:
|
||||
if (_owner == CommentOwner::CONTRACT)
|
||||
{
|
||||
m_title += " ";
|
||||
return parseDocTagLine(_pos, _end, m_title, DocTagType::TITLE);
|
||||
}
|
||||
else
|
||||
// LTODO: Unknown tag, throw some form of warning and not just an exception
|
||||
BOOST_THROW_EXCEPTION(DocstringParsingError() << errinfo_comment("@title tag in illegal comment"));
|
||||
case DocTagType::PARAM:
|
||||
return appendDocTagParam(_pos, _end);
|
||||
default:
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Internal: Illegal documentation tag type"));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -247,7 +309,7 @@ static inline std::string::const_iterator getFirstSpaceOrNl(std::string::const_i
|
||||
return (spacePos < nlPos) ? spacePos : nlPos;
|
||||
}
|
||||
|
||||
void InterfaceHandler::parseDocString(std::string const& _string)
|
||||
void InterfaceHandler::parseDocString(std::string const& _string, CommentOwner _owner)
|
||||
{
|
||||
auto currPos = _string.begin();
|
||||
auto end = _string.end();
|
||||
@ -265,10 +327,10 @@ void InterfaceHandler::parseDocString(std::string const& _string)
|
||||
BOOST_THROW_EXCEPTION(DocstringParsingError() <<
|
||||
errinfo_comment("End of tag " + std::string(tagPos, tagNameEndPos) + "not found"));
|
||||
|
||||
currPos = parseDocTag(tagNameEndPos + 1, end, std::string(tagPos + 1, tagNameEndPos));
|
||||
currPos = parseDocTag(tagNameEndPos + 1, end, std::string(tagPos + 1, tagNameEndPos), _owner);
|
||||
}
|
||||
else if (m_lastTag != DocTagType::NONE) // continuation of the previous tag
|
||||
currPos = appendDocTag(currPos + 1, end);
|
||||
currPos = appendDocTag(currPos + 1, end, _owner);
|
||||
else if (currPos != end) // skip the line if a newline was found
|
||||
currPos = nlPos + 1;
|
||||
}
|
||||
|
@ -45,7 +45,15 @@ enum class DocTagType: uint8_t
|
||||
DEV,
|
||||
NOTICE,
|
||||
PARAM,
|
||||
RETURN
|
||||
RETURN,
|
||||
AUTHOR,
|
||||
TITLE
|
||||
};
|
||||
|
||||
enum class CommentOwner
|
||||
{
|
||||
CONTRACT,
|
||||
FUNCTION
|
||||
};
|
||||
|
||||
class InterfaceHandler
|
||||
@ -89,12 +97,14 @@ private:
|
||||
std::string::const_iterator _end);
|
||||
std::string::const_iterator appendDocTagParam(std::string::const_iterator _pos,
|
||||
std::string::const_iterator _end);
|
||||
void parseDocString(std::string const& _string);
|
||||
void parseDocString(std::string const& _string, CommentOwner _owner);
|
||||
std::string::const_iterator appendDocTag(std::string::const_iterator _pos,
|
||||
std::string::const_iterator _end);
|
||||
std::string::const_iterator _end,
|
||||
CommentOwner _owner);
|
||||
std::string::const_iterator parseDocTag(std::string::const_iterator _pos,
|
||||
std::string::const_iterator _end,
|
||||
std::string const& _tag);
|
||||
std::string const& _tag,
|
||||
CommentOwner _owner);
|
||||
|
||||
Json::StyledWriter m_writer;
|
||||
|
||||
@ -103,6 +113,9 @@ private:
|
||||
std::string m_notice;
|
||||
std::string m_dev;
|
||||
std::string m_return;
|
||||
std::string m_contractAuthor;
|
||||
std::string m_author;
|
||||
std::string m_title;
|
||||
std::vector<std::pair<std::string, std::string>> m_params;
|
||||
};
|
||||
|
||||
|
@ -32,9 +32,9 @@ namespace solidity
|
||||
{
|
||||
|
||||
|
||||
NameAndTypeResolver::NameAndTypeResolver(std::vector<Declaration*> const& _globals)
|
||||
NameAndTypeResolver::NameAndTypeResolver(std::vector<Declaration const*> const& _globals)
|
||||
{
|
||||
for (Declaration* declaration: _globals)
|
||||
for (Declaration const* declaration: _globals)
|
||||
m_scopes[nullptr].registerDeclaration(*declaration);
|
||||
}
|
||||
|
||||
@ -70,13 +70,14 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
|
||||
m_currentScope = &m_scopes[nullptr];
|
||||
}
|
||||
|
||||
void NameAndTypeResolver::updateDeclaration(Declaration& _declaration)
|
||||
void NameAndTypeResolver::updateDeclaration(Declaration const& _declaration)
|
||||
{
|
||||
m_scopes[nullptr].registerDeclaration(_declaration, true);
|
||||
_declaration.setScope(nullptr);
|
||||
if (asserts(_declaration.getScope() == nullptr))
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Updated declaration outside global scope."));
|
||||
}
|
||||
|
||||
Declaration* NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const
|
||||
Declaration const* NameAndTypeResolver::resolveName(ASTString const& _name, Declaration const* _scope) const
|
||||
{
|
||||
auto iterator = m_scopes.find(_scope);
|
||||
if (iterator == end(m_scopes))
|
||||
@ -84,7 +85,7 @@ Declaration* NameAndTypeResolver::resolveName(ASTString const& _name, Declaratio
|
||||
return iterator->second.resolveName(_name, false);
|
||||
}
|
||||
|
||||
Declaration* NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name, bool _recursive)
|
||||
Declaration const* NameAndTypeResolver::getNameFromCurrentScope(ASTString const& _name, bool _recursive)
|
||||
{
|
||||
return m_currentScope->resolveName(_name, _recursive);
|
||||
}
|
||||
@ -146,7 +147,7 @@ bool DeclarationRegistrationHelper::visit(VariableDeclaration& _declaration)
|
||||
return true;
|
||||
}
|
||||
|
||||
void DeclarationRegistrationHelper::enterNewSubScope(Declaration& _declaration)
|
||||
void DeclarationRegistrationHelper::enterNewSubScope(Declaration const& _declaration)
|
||||
{
|
||||
map<ASTNode const*, DeclarationContainer>::iterator iter;
|
||||
bool newlyAdded;
|
||||
@ -204,15 +205,14 @@ bool ReferencesResolver::visit(Return& _return)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReferencesResolver::visit(Mapping& _mapping)
|
||||
bool ReferencesResolver::visit(Mapping&)
|
||||
{
|
||||
(void)_mapping;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ReferencesResolver::visit(UserDefinedTypeName& _typeName)
|
||||
{
|
||||
Declaration* declaration = m_resolver.getNameFromCurrentScope(_typeName.getName());
|
||||
Declaration const* declaration = m_resolver.getNameFromCurrentScope(_typeName.getName());
|
||||
if (!declaration)
|
||||
BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_typeName.getLocation())
|
||||
<< errinfo_comment("Undeclared identifier."));
|
||||
@ -222,7 +222,7 @@ bool ReferencesResolver::visit(UserDefinedTypeName& _typeName)
|
||||
|
||||
bool ReferencesResolver::visit(Identifier& _identifier)
|
||||
{
|
||||
Declaration* declaration = m_resolver.getNameFromCurrentScope(_identifier.getName());
|
||||
Declaration const* declaration = m_resolver.getNameFromCurrentScope(_identifier.getName());
|
||||
if (!declaration)
|
||||
BOOST_THROW_EXCEPTION(DeclarationError() << errinfo_sourceLocation(_identifier.getLocation())
|
||||
<< errinfo_comment("Undeclared identifier."));
|
||||
|
@ -41,27 +41,25 @@ namespace solidity
|
||||
class NameAndTypeResolver: private boost::noncopyable
|
||||
{
|
||||
public:
|
||||
explicit NameAndTypeResolver(std::vector<Declaration*> const& _globals);
|
||||
explicit NameAndTypeResolver(std::vector<Declaration const*> const& _globals);
|
||||
/// Registers all declarations found in the source unit.
|
||||
void registerDeclarations(SourceUnit& _sourceUnit);
|
||||
/// Resolves all names and types referenced from the given contract.
|
||||
void resolveNamesAndTypes(ContractDefinition& _contract);
|
||||
/// Updates the given global declaration (used for "this"). Not to be used with declarations
|
||||
/// that create their own scope.
|
||||
void updateDeclaration(Declaration& _declaration);
|
||||
void updateDeclaration(Declaration const& _declaration);
|
||||
|
||||
/// Resolves the given @a _name inside the scope @a _scope. If @a _scope is omitted,
|
||||
/// the global scope is used (i.e. the one containing only the contract).
|
||||
/// @returns a pointer to the declaration on success or nullptr on failure.
|
||||
Declaration* resolveName(ASTString const& _name, Declaration const* _scope = nullptr) const;
|
||||
Declaration const* resolveName(ASTString const& _name, Declaration const* _scope = nullptr) const;
|
||||
|
||||
/// Resolves a name in the "current" scope. Should only be called during the initial
|
||||
/// resolving phase.
|
||||
Declaration* getNameFromCurrentScope(ASTString const& _name, bool _recursive = true);
|
||||
Declaration const* getNameFromCurrentScope(ASTString const& _name, bool _recursive = true);
|
||||
|
||||
private:
|
||||
/// Throws if @a _struct contains a recursive loop. Note that recursion via mappings is fine.
|
||||
void checkForRecursion(StructDefinition const& _struct);
|
||||
void reset();
|
||||
|
||||
/// Maps nodes declaring a scope to scopes, i.e. ContractDefinition and FunctionDeclaration,
|
||||
@ -91,12 +89,12 @@ private:
|
||||
void endVisit(VariableDefinition& _variableDefinition);
|
||||
bool visit(VariableDeclaration& _declaration);
|
||||
|
||||
void enterNewSubScope(Declaration& _declaration);
|
||||
void enterNewSubScope(Declaration const& _declaration);
|
||||
void closeCurrentScope();
|
||||
void registerDeclaration(Declaration& _declaration, bool _opensScope);
|
||||
|
||||
std::map<ASTNode const*, DeclarationContainer>& m_scopes;
|
||||
Declaration* m_currentScope;
|
||||
Declaration const* m_currentScope;
|
||||
FunctionDefinition* m_currentFunction;
|
||||
};
|
||||
|
||||
|
@ -112,6 +112,9 @@ ASTPointer<ImportDirective> Parser::parseImportDirective()
|
||||
ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
ASTPointer<ASTString> docstring;
|
||||
if (m_scanner->getCurrentCommentLiteral() != "")
|
||||
docstring = make_shared<ASTString>(m_scanner->getCurrentCommentLiteral());
|
||||
expectToken(Token::CONTRACT);
|
||||
ASTPointer<ASTString> name = expectIdentifierToken();
|
||||
expectToken(Token::LBRACE);
|
||||
@ -146,7 +149,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
||||
}
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RBRACE);
|
||||
return nodeFactory.createNode<ContractDefinition>(name, structs, stateVariables, functions);
|
||||
return nodeFactory.createNode<ContractDefinition>(name, docstring, structs, stateVariables, functions);
|
||||
}
|
||||
|
||||
ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
|
||||
|
@ -61,7 +61,7 @@ void SourceReferenceFormatter::printSourceLocation(ostream& _stream,
|
||||
void SourceReferenceFormatter::printExceptionInformation(ostream& _stream,
|
||||
Exception const& _exception,
|
||||
string const& _name,
|
||||
CompilerStack& _compiler)
|
||||
CompilerStack const& _compiler)
|
||||
{
|
||||
Location const* location = boost::get_error_info<errinfo_sourceLocation>(_exception);
|
||||
Scanner const* scanner;
|
||||
|
@ -41,7 +41,7 @@ struct SourceReferenceFormatter
|
||||
public:
|
||||
static void printSourceLocation(std::ostream& _stream, Location const& _location, Scanner const& _scanner);
|
||||
static void printExceptionInformation(std::ostream& _stream, Exception const& _exception,
|
||||
std::string const& _name, CompilerStack& _compiler);
|
||||
std::string const& _name, CompilerStack const& _compiler);
|
||||
};
|
||||
|
||||
}
|
||||
|
36
Types.cpp
36
Types.cpp
@ -32,7 +32,7 @@ namespace dev
|
||||
namespace solidity
|
||||
{
|
||||
|
||||
shared_ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken)
|
||||
shared_ptr<Type const> Type::fromElementaryTypeName(Token::Value _typeToken)
|
||||
{
|
||||
if (asserts(Token::isElementaryTypeName(_typeToken)))
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError());
|
||||
@ -44,33 +44,33 @@ shared_ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken)
|
||||
if (bytes == 0)
|
||||
bytes = 32;
|
||||
int modifier = offset / 33;
|
||||
return make_shared<IntegerType>(bytes * 8,
|
||||
return make_shared<IntegerType const>(bytes * 8,
|
||||
modifier == 0 ? IntegerType::Modifier::SIGNED :
|
||||
modifier == 1 ? IntegerType::Modifier::UNSIGNED :
|
||||
IntegerType::Modifier::HASH);
|
||||
}
|
||||
else if (_typeToken == Token::ADDRESS)
|
||||
return make_shared<IntegerType>(0, IntegerType::Modifier::ADDRESS);
|
||||
return make_shared<IntegerType const>(0, IntegerType::Modifier::ADDRESS);
|
||||
else if (_typeToken == Token::BOOL)
|
||||
return make_shared<BoolType>();
|
||||
return shared_ptr<BoolType const>();
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(InternalCompilerError() << errinfo_comment("Unable to convert elementary typename " +
|
||||
std::string(Token::toString(_typeToken)) + " to type."));
|
||||
}
|
||||
|
||||
shared_ptr<Type> Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName)
|
||||
shared_ptr<Type const> Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName)
|
||||
{
|
||||
Declaration const* declaration = _typeName.getReferencedDeclaration();
|
||||
if (StructDefinition const* structDef = dynamic_cast<StructDefinition const*>(declaration))
|
||||
return make_shared<StructType>(*structDef);
|
||||
return make_shared<StructType const>(*structDef);
|
||||
else if (FunctionDefinition const* function = dynamic_cast<FunctionDefinition const*>(declaration))
|
||||
return make_shared<FunctionType>(*function);
|
||||
return make_shared<FunctionType const>(*function);
|
||||
else if (ContractDefinition const* contract = dynamic_cast<ContractDefinition const*>(declaration))
|
||||
return make_shared<ContractType>(*contract);
|
||||
return shared_ptr<Type>();
|
||||
return make_shared<ContractType const>(*contract);
|
||||
return shared_ptr<Type const>();
|
||||
}
|
||||
|
||||
shared_ptr<Type> Type::fromMapping(Mapping const& _typeName)
|
||||
shared_ptr<Type const> Type::fromMapping(Mapping const& _typeName)
|
||||
{
|
||||
shared_ptr<Type const> keyType = _typeName.getKeyType().toType();
|
||||
if (!keyType)
|
||||
@ -78,28 +78,28 @@ shared_ptr<Type> Type::fromMapping(Mapping const& _typeName)
|
||||
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);
|
||||
return make_shared<MappingType const>(keyType, valueType);
|
||||
}
|
||||
|
||||
shared_ptr<Type> Type::forLiteral(Literal const& _literal)
|
||||
shared_ptr<Type const> Type::forLiteral(Literal const& _literal)
|
||||
{
|
||||
switch (_literal.getToken())
|
||||
{
|
||||
case Token::TRUE_LITERAL:
|
||||
case Token::FALSE_LITERAL:
|
||||
return make_shared<BoolType>();
|
||||
return shared_ptr<BoolType const>();
|
||||
case Token::NUMBER:
|
||||
return IntegerType::smallestTypeForLiteral(_literal.getValue());
|
||||
case Token::STRING_LITERAL:
|
||||
return shared_ptr<Type>(); // @todo add string literals
|
||||
return shared_ptr<Type const>(); // @todo add string literals
|
||||
default:
|
||||
return shared_ptr<Type>();
|
||||
return shared_ptr<Type const>();
|
||||
}
|
||||
}
|
||||
|
||||
const MemberList Type::EmptyMemberList = MemberList();
|
||||
|
||||
shared_ptr<IntegerType> IntegerType::smallestTypeForLiteral(string const& _literal)
|
||||
shared_ptr<IntegerType const> IntegerType::smallestTypeForLiteral(string const& _literal)
|
||||
{
|
||||
bigint value(_literal);
|
||||
bool isSigned = value < 0 || (!_literal.empty() && _literal.front() == '-');
|
||||
@ -108,8 +108,8 @@ shared_ptr<IntegerType> IntegerType::smallestTypeForLiteral(string const& _liter
|
||||
value = ((-value) - 1) << 1;
|
||||
unsigned bytes = max(bytesRequired(value), 1u);
|
||||
if (bytes > 32)
|
||||
return shared_ptr<IntegerType>();
|
||||
return make_shared<IntegerType>(bytes * 8, isSigned ? Modifier::SIGNED : Modifier::UNSIGNED);
|
||||
return shared_ptr<IntegerType const>();
|
||||
return make_shared<IntegerType const>(bytes * 8, isSigned ? Modifier::SIGNED : Modifier::UNSIGNED);
|
||||
}
|
||||
|
||||
IntegerType::IntegerType(int _bits, IntegerType::Modifier _modifier):
|
||||
|
14
Types.h
14
Types.h
@ -80,15 +80,15 @@ public:
|
||||
///@{
|
||||
///@name Factory functions
|
||||
/// Factory functions that convert an AST @ref TypeName to a Type.
|
||||
static std::shared_ptr<Type> fromElementaryTypeName(Token::Value _typeToken);
|
||||
static std::shared_ptr<Type> fromUserDefinedTypeName(UserDefinedTypeName const& _typeName);
|
||||
static std::shared_ptr<Type> fromMapping(Mapping const& _typeName);
|
||||
static std::shared_ptr<Type> fromFunction(FunctionDefinition const& _function);
|
||||
static std::shared_ptr<Type const> fromElementaryTypeName(Token::Value _typeToken);
|
||||
static std::shared_ptr<Type const> fromUserDefinedTypeName(UserDefinedTypeName const& _typeName);
|
||||
static std::shared_ptr<Type const> fromMapping(Mapping const& _typeName);
|
||||
static std::shared_ptr<Type const> fromFunction(FunctionDefinition const& _function);
|
||||
/// @}
|
||||
|
||||
/// Auto-detect the proper type for a literal. @returns an empty pointer if the literal does
|
||||
/// not fit any type.
|
||||
static std::shared_ptr<Type> forLiteral(Literal const& _literal);
|
||||
static std::shared_ptr<Type const> forLiteral(Literal const& _literal);
|
||||
|
||||
virtual Category getCategory() const = 0;
|
||||
virtual bool isImplicitlyConvertibleTo(Type const& _other) const { return *this == _other; }
|
||||
@ -148,7 +148,7 @@ public:
|
||||
|
||||
/// @returns the smallest integer type for the given literal or an empty pointer
|
||||
/// if no type fits.
|
||||
static std::shared_ptr<IntegerType> smallestTypeForLiteral(std::string const& _literal);
|
||||
static std::shared_ptr<IntegerType const> smallestTypeForLiteral(std::string const& _literal);
|
||||
|
||||
explicit IntegerType(int _bits, Modifier _modifier = Modifier::UNSIGNED);
|
||||
|
||||
@ -286,7 +286,7 @@ public:
|
||||
virtual bool canLiveOutsideStorage() const override { return false; }
|
||||
virtual unsigned getSizeOnStack() const override;
|
||||
|
||||
Location getLocation() const { return m_location; }
|
||||
Location const& getLocation() const { return m_location; }
|
||||
|
||||
private:
|
||||
TypePointers m_parameterTypes;
|
||||
|
Loading…
Reference in New Issue
Block a user