mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
Pointer type cleanup: Use ASTPointer only for AST nodes and shared_ptr for type
pointer.
This commit is contained in:
parent
f0c334670d
commit
be885dc3cf
86
AST.cpp
86
AST.cpp
@ -250,46 +250,42 @@ void Literal::accept(ASTVisitor& _visitor)
|
||||
|
||||
void Statement::expectType(Expression& _expression, const Type& _expectedType)
|
||||
{
|
||||
if (!_expression.checkTypeRequirements()->isImplicitlyConvertibleTo(_expectedType))
|
||||
_expression.checkTypeRequirements();
|
||||
if (!_expression.getType()->isImplicitlyConvertibleTo(_expectedType))
|
||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Type not implicitly convertible "
|
||||
"to expected type."));
|
||||
//@todo provide more information to the exception
|
||||
}
|
||||
|
||||
ptr<Type> Block::checkTypeRequirements()
|
||||
void Block::checkTypeRequirements()
|
||||
{
|
||||
for (ptr<Statement> const& statement: m_statements)
|
||||
for (std::shared_ptr<Statement> const& statement: m_statements)
|
||||
statement->checkTypeRequirements();
|
||||
return ptr<Type>();
|
||||
}
|
||||
|
||||
ptr<Type> IfStatement::checkTypeRequirements()
|
||||
void IfStatement::checkTypeRequirements()
|
||||
{
|
||||
expectType(*m_condition, BoolType());
|
||||
m_trueBody->checkTypeRequirements();
|
||||
if (m_falseBody)
|
||||
m_falseBody->checkTypeRequirements();
|
||||
return ptr<Type>();
|
||||
}
|
||||
|
||||
ptr<Type> WhileStatement::checkTypeRequirements()
|
||||
void WhileStatement::checkTypeRequirements()
|
||||
{
|
||||
expectType(*m_condition, BoolType());
|
||||
m_body->checkTypeRequirements();
|
||||
return ptr<Type>();
|
||||
}
|
||||
|
||||
ptr<Type> Continue::checkTypeRequirements()
|
||||
void Continue::checkTypeRequirements()
|
||||
{
|
||||
return ptr<Type>();
|
||||
}
|
||||
|
||||
ptr<Type> Break::checkTypeRequirements()
|
||||
void Break::checkTypeRequirements()
|
||||
{
|
||||
return ptr<Type>();
|
||||
}
|
||||
|
||||
ptr<Type> Return::checkTypeRequirements()
|
||||
void Return::checkTypeRequirements()
|
||||
{
|
||||
BOOST_ASSERT(m_returnParameters != nullptr);
|
||||
if (m_returnParameters->getParameters().size() != 1)
|
||||
@ -299,10 +295,9 @@ ptr<Type> Return::checkTypeRequirements()
|
||||
// this could later be changed such that the paramaters type is an anonymous struct type,
|
||||
// but for now, we only allow one return parameter
|
||||
expectType(*m_expression, *m_returnParameters->getParameters().front()->getType());
|
||||
return ptr<Type>();
|
||||
}
|
||||
|
||||
ptr<Type> VariableDefinition::checkTypeRequirements()
|
||||
void VariableDefinition::checkTypeRequirements()
|
||||
{
|
||||
// Variables can be declared without type (with "var"), in which case the first assignment
|
||||
// setsthe type.
|
||||
@ -313,17 +308,20 @@ ptr<Type> VariableDefinition::checkTypeRequirements()
|
||||
if (m_variable->getType())
|
||||
expectType(*m_value, *m_variable->getType());
|
||||
else
|
||||
{
|
||||
// no type declared and no previous assignment, infer the type
|
||||
m_variable->setType(m_value->checkTypeRequirements());
|
||||
m_value->checkTypeRequirements();
|
||||
m_variable->setType(m_value->getType());
|
||||
}
|
||||
}
|
||||
return ptr<Type>();
|
||||
}
|
||||
|
||||
ptr<Type> Assignment::checkTypeRequirements()
|
||||
void Assignment::checkTypeRequirements()
|
||||
{
|
||||
//@todo lefthandside actually has to be assignable
|
||||
// add a feature to the type system to check that
|
||||
expectType(*m_rightHandSide, *m_leftHandSide->checkTypeRequirements());
|
||||
m_leftHandSide->checkTypeRequirements();
|
||||
expectType(*m_rightHandSide, *m_leftHandSide->getType());
|
||||
m_type = m_leftHandSide->getType();
|
||||
if (m_assigmentOperator != Token::ASSIGN)
|
||||
{
|
||||
@ -331,19 +329,18 @@ ptr<Type> Assignment::checkTypeRequirements()
|
||||
if (!m_type->acceptsBinaryOperator(Token::AssignmentToBinaryOp(m_assigmentOperator)))
|
||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Operator not compatible with type."));
|
||||
}
|
||||
return m_type;
|
||||
}
|
||||
|
||||
ptr<Type> UnaryOperation::checkTypeRequirements()
|
||||
void UnaryOperation::checkTypeRequirements()
|
||||
{
|
||||
// INC, DEC, NOT, BIT_NOT, DELETE
|
||||
m_type = m_subExpression->checkTypeRequirements();
|
||||
m_subExpression->checkTypeRequirements();
|
||||
m_type = m_subExpression->getType();
|
||||
if (m_type->acceptsUnaryOperator(m_operator))
|
||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Unary operator not compatible with type."));
|
||||
return m_type;
|
||||
}
|
||||
|
||||
ptr<Type> BinaryOperation::checkTypeRequirements()
|
||||
void BinaryOperation::checkTypeRequirements()
|
||||
{
|
||||
m_right->checkTypeRequirements();
|
||||
m_left->checkTypeRequirements();
|
||||
@ -362,19 +359,18 @@ ptr<Type> BinaryOperation::checkTypeRequirements()
|
||||
if (!m_commonType->acceptsBinaryOperator(m_operator))
|
||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Operator not compatible with type."));
|
||||
}
|
||||
return m_type;
|
||||
}
|
||||
|
||||
ptr<Type> FunctionCall::checkTypeRequirements()
|
||||
void FunctionCall::checkTypeRequirements()
|
||||
{
|
||||
m_expression->checkTypeRequirements();
|
||||
for (ptr<Expression> const& argument: m_arguments)
|
||||
for (ASTPointer<Expression> const& argument: m_arguments)
|
||||
argument->checkTypeRequirements();
|
||||
ptr<Type> expressionType = m_expression->getType();
|
||||
Type::Category const category = expressionType->getCategory();
|
||||
Type const& expressionType = *m_expression->getType();
|
||||
Type::Category const category = expressionType.getCategory();
|
||||
if (category == Type::Category::TYPE)
|
||||
{
|
||||
TypeType* type = dynamic_cast<TypeType*>(expressionType.get());
|
||||
TypeType const* type = dynamic_cast<TypeType const*>(&expressionType);
|
||||
BOOST_ASSERT(type != nullptr);
|
||||
//@todo for structs, we have to check the number of arguments to be equal to the
|
||||
// number of non-mapping members
|
||||
@ -391,10 +387,10 @@ ptr<Type> FunctionCall::checkTypeRequirements()
|
||||
//@todo would be nice to create a struct type from the arguments
|
||||
// and then ask if that is implicitly convertible to the struct represented by the
|
||||
// function parameters
|
||||
FunctionType* function = dynamic_cast<FunctionType*>(expressionType.get());
|
||||
FunctionType const* function = dynamic_cast<FunctionType const*>(&expressionType);
|
||||
BOOST_ASSERT(function != nullptr);
|
||||
FunctionDefinition const& fun = function->getFunction();
|
||||
std::vector<ptr<VariableDeclaration>> const& parameters = fun.getParameters();
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& parameters = fun.getParameters();
|
||||
if (parameters.size() != m_arguments.size())
|
||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Wrong argument count for "
|
||||
"function call."));
|
||||
@ -413,24 +409,21 @@ ptr<Type> FunctionCall::checkTypeRequirements()
|
||||
{
|
||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Type does not support invocation."));
|
||||
}
|
||||
return m_type;
|
||||
}
|
||||
|
||||
ptr<Type> MemberAccess::checkTypeRequirements()
|
||||
void MemberAccess::checkTypeRequirements()
|
||||
{
|
||||
BOOST_ASSERT(false); // not yet implemented
|
||||
// m_type = ;
|
||||
return m_type;
|
||||
}
|
||||
|
||||
ptr<Type> IndexAccess::checkTypeRequirements()
|
||||
void IndexAccess::checkTypeRequirements()
|
||||
{
|
||||
BOOST_ASSERT(false); // not yet implemented
|
||||
// m_type = ;
|
||||
return m_type;
|
||||
}
|
||||
|
||||
ptr<Type> Identifier::checkTypeRequirements()
|
||||
void Identifier::checkTypeRequirements()
|
||||
{
|
||||
BOOST_ASSERT(m_referencedDeclaration != nullptr);
|
||||
//@todo these dynamic casts here are not really nice...
|
||||
@ -444,11 +437,11 @@ ptr<Type> Identifier::checkTypeRequirements()
|
||||
VariableDeclaration* variable = dynamic_cast<VariableDeclaration*>(m_referencedDeclaration);
|
||||
if (variable != nullptr)
|
||||
{
|
||||
if (variable->getType().get() == nullptr)
|
||||
if (!variable->getType())
|
||||
BOOST_THROW_EXCEPTION(TypeError() << errinfo_comment("Variable referenced before type "
|
||||
"could be determined."));
|
||||
m_type = variable->getType();
|
||||
return m_type;
|
||||
return;
|
||||
}
|
||||
//@todo can we unify these with TypeName::toType()?
|
||||
StructDefinition* structDef = dynamic_cast<StructDefinition*>(m_referencedDeclaration);
|
||||
@ -456,7 +449,7 @@ ptr<Type> Identifier::checkTypeRequirements()
|
||||
{
|
||||
// note that we do not have a struct type here
|
||||
m_type = std::make_shared<TypeType>(std::make_shared<StructType>(*structDef));
|
||||
return m_type;
|
||||
return;
|
||||
}
|
||||
FunctionDefinition* functionDef = dynamic_cast<FunctionDefinition*>(m_referencedDeclaration);
|
||||
if (functionDef != nullptr)
|
||||
@ -465,28 +458,25 @@ ptr<Type> Identifier::checkTypeRequirements()
|
||||
// Calling a function (e.g. function(12), otherContract.function(34)) does not do a type
|
||||
// conversion.
|
||||
m_type = std::make_shared<FunctionType>(*functionDef);
|
||||
return m_type;
|
||||
return;
|
||||
}
|
||||
ContractDefinition* contractDef = dynamic_cast<ContractDefinition*>(m_referencedDeclaration);
|
||||
if (contractDef != nullptr)
|
||||
{
|
||||
m_type = std::make_shared<TypeType>(std::make_shared<ContractType>(*contractDef));
|
||||
return m_type;
|
||||
return;
|
||||
}
|
||||
BOOST_ASSERT(false); // declaration reference of unknown/forbidden type
|
||||
return m_type;
|
||||
}
|
||||
|
||||
ptr<Type> ElementaryTypeNameExpression::checkTypeRequirements()
|
||||
void ElementaryTypeNameExpression::checkTypeRequirements()
|
||||
{
|
||||
m_type = std::make_shared<TypeType>(Type::fromElementaryTypeName(m_typeToken));
|
||||
return m_type;
|
||||
}
|
||||
|
||||
ptr<Type> Literal::checkTypeRequirements()
|
||||
void Literal::checkTypeRequirements()
|
||||
{
|
||||
m_type = Type::forLiteral(*this);
|
||||
return m_type;
|
||||
}
|
||||
|
||||
}
|
||||
|
217
AST.h
217
AST.h
@ -51,9 +51,9 @@ public:
|
||||
|
||||
virtual void accept(ASTVisitor& _visitor) = 0;
|
||||
template <class T>
|
||||
static void listAccept(std::vector<ptr<T>>& _list, ASTVisitor& _visitor)
|
||||
static void listAccept(std::vector<ASTPointer<T>>& _list, ASTVisitor& _visitor)
|
||||
{
|
||||
for (ptr<T>& element: _list)
|
||||
for (ASTPointer<T>& element: _list)
|
||||
element->accept(_visitor);
|
||||
}
|
||||
|
||||
@ -65,22 +65,22 @@ private:
|
||||
class Declaration: public ASTNode
|
||||
{
|
||||
public:
|
||||
Declaration(Location const& _location, ptr<ASTString> const& _name)
|
||||
Declaration(Location const& _location, ASTPointer<ASTString> const& _name)
|
||||
: ASTNode(_location), m_name(_name) {}
|
||||
|
||||
const ASTString& getName() const { return *m_name; }
|
||||
private:
|
||||
ptr<ASTString> m_name;
|
||||
ASTPointer<ASTString> m_name;
|
||||
};
|
||||
|
||||
class ContractDefinition: public Declaration
|
||||
{
|
||||
public:
|
||||
ContractDefinition(Location const& _location,
|
||||
ptr<ASTString> const& _name,
|
||||
std::vector<ptr<StructDefinition>> const& _definedStructs,
|
||||
std::vector<ptr<VariableDeclaration>> const& _stateVariables,
|
||||
std::vector<ptr<FunctionDefinition>> const& _definedFunctions)
|
||||
ASTPointer<ASTString> const& _name,
|
||||
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),
|
||||
@ -89,26 +89,26 @@ public:
|
||||
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
std::vector<ptr<StructDefinition>> const& getDefinedStructs() { return m_definedStructs; }
|
||||
std::vector<ptr<VariableDeclaration>> const& getStateVariables() { return m_stateVariables; }
|
||||
std::vector<ptr<FunctionDefinition>> const& getDefinedFunctions() { return m_definedFunctions; }
|
||||
std::vector<ASTPointer<StructDefinition>> const& getDefinedStructs() { return m_definedStructs; }
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& getStateVariables() { return m_stateVariables; }
|
||||
std::vector<ASTPointer<FunctionDefinition>> const& getDefinedFunctions() { return m_definedFunctions; }
|
||||
private:
|
||||
std::vector<ptr<StructDefinition>> m_definedStructs;
|
||||
std::vector<ptr<VariableDeclaration>> m_stateVariables;
|
||||
std::vector<ptr<FunctionDefinition>> m_definedFunctions;
|
||||
std::vector<ASTPointer<StructDefinition>> m_definedStructs;
|
||||
std::vector<ASTPointer<VariableDeclaration>> m_stateVariables;
|
||||
std::vector<ASTPointer<FunctionDefinition>> m_definedFunctions;
|
||||
};
|
||||
|
||||
class StructDefinition: public Declaration
|
||||
{
|
||||
public:
|
||||
StructDefinition(Location const& _location,
|
||||
ptr<ASTString> const& _name,
|
||||
std::vector<ptr<VariableDeclaration>> const& _members)
|
||||
ASTPointer<ASTString> const& _name,
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& _members)
|
||||
: Declaration(_location, _name), m_members(_members) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
private:
|
||||
std::vector<ptr<VariableDeclaration>> m_members;
|
||||
std::vector<ASTPointer<VariableDeclaration>> m_members;
|
||||
};
|
||||
|
||||
/// Used as function parameter list and return list
|
||||
@ -117,23 +117,23 @@ private:
|
||||
class ParameterList: public ASTNode
|
||||
{
|
||||
public:
|
||||
ParameterList(Location const& _location, std::vector<ptr<VariableDeclaration>> const& _parameters)
|
||||
ParameterList(Location const& _location, std::vector<ASTPointer<VariableDeclaration>> const& _parameters)
|
||||
: ASTNode(_location), m_parameters(_parameters) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
std::vector<ptr<VariableDeclaration>> const& getParameters() { return m_parameters; }
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& getParameters() { return m_parameters; }
|
||||
private:
|
||||
std::vector<ptr<VariableDeclaration>> m_parameters;
|
||||
std::vector<ASTPointer<VariableDeclaration>> m_parameters;
|
||||
};
|
||||
|
||||
class FunctionDefinition: public Declaration
|
||||
{
|
||||
public:
|
||||
FunctionDefinition(Location const& _location, ptr<ASTString> const& _name, bool _isPublic,
|
||||
ptr<ParameterList> const& _parameters,
|
||||
FunctionDefinition(Location const& _location, ASTPointer<ASTString> const& _name, bool _isPublic,
|
||||
ASTPointer<ParameterList> const& _parameters,
|
||||
bool _isDeclaredConst,
|
||||
ptr<ParameterList> const& _returnParameters,
|
||||
ptr<Block> const& _body)
|
||||
ASTPointer<ParameterList> const& _returnParameters,
|
||||
ASTPointer<Block> const& _body)
|
||||
: Declaration(_location, _name), m_isPublic(_isPublic), m_parameters(_parameters),
|
||||
m_isDeclaredConst(_isDeclaredConst), m_returnParameters(_returnParameters),
|
||||
m_body(_body) {}
|
||||
@ -141,23 +141,23 @@ public:
|
||||
|
||||
bool isPublic() const { return m_isPublic; }
|
||||
bool isDeclaredConst() const { return m_isDeclaredConst; }
|
||||
std::vector<ptr<VariableDeclaration>> const& getParameters() const { return m_parameters->getParameters(); }
|
||||
std::vector<ASTPointer<VariableDeclaration>> const& getParameters() const { return m_parameters->getParameters(); }
|
||||
ParameterList& getParameterList() { return *m_parameters; }
|
||||
ptr<ParameterList> const& getReturnParameterList() const { return m_returnParameters; }
|
||||
ASTPointer<ParameterList> const& getReturnParameterList() const { return m_returnParameters; }
|
||||
Block& getBody() { return *m_body; }
|
||||
private:
|
||||
bool m_isPublic;
|
||||
ptr<ParameterList> m_parameters;
|
||||
ASTPointer<ParameterList> m_parameters;
|
||||
bool m_isDeclaredConst;
|
||||
ptr<ParameterList> m_returnParameters;
|
||||
ptr<Block> m_body;
|
||||
ASTPointer<ParameterList> m_returnParameters;
|
||||
ASTPointer<Block> m_body;
|
||||
};
|
||||
|
||||
class VariableDeclaration: public Declaration
|
||||
{
|
||||
public:
|
||||
VariableDeclaration(Location const& _location, ptr<TypeName> const& _type,
|
||||
ptr<ASTString> const& _name)
|
||||
VariableDeclaration(Location const& _location, ASTPointer<TypeName> const& _type,
|
||||
ASTPointer<ASTString> const& _name)
|
||||
: Declaration(_location, _name), m_typeName(_type) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
@ -166,12 +166,12 @@ public:
|
||||
|
||||
//! 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.
|
||||
ptr<Type> const& getType() const { return m_type; }
|
||||
void setType(ptr<Type> const& _type) { m_type = _type; }
|
||||
std::shared_ptr<Type const> const& getType() const { return m_type; }
|
||||
void setType(std::shared_ptr<Type const> const& _type) { m_type = _type; }
|
||||
private:
|
||||
ptr<TypeName> m_typeName; ///< can be empty ("var")
|
||||
ASTPointer<TypeName> m_typeName; ///< can be empty ("var")
|
||||
|
||||
ptr<Type> m_type;
|
||||
std::shared_ptr<Type const> m_type;
|
||||
};
|
||||
|
||||
/// types
|
||||
@ -183,7 +183,7 @@ public:
|
||||
explicit TypeName(Location const& _location): ASTNode(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
virtual ptr<Type> toType() = 0;
|
||||
virtual std::shared_ptr<Type> toType() = 0;
|
||||
};
|
||||
|
||||
/// any pre-defined type that is not a mapping
|
||||
@ -193,7 +193,7 @@ public:
|
||||
explicit ElementaryTypeName(Location const& _location, Token::Value _type)
|
||||
: TypeName(_location), m_type(_type) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> toType() override { return Type::fromElementaryTypeName(m_type); }
|
||||
virtual std::shared_ptr<Type> toType() override { return Type::fromElementaryTypeName(m_type); }
|
||||
|
||||
Token::Value getType() const { return m_type; }
|
||||
private:
|
||||
@ -203,16 +203,16 @@ private:
|
||||
class UserDefinedTypeName: public TypeName
|
||||
{
|
||||
public:
|
||||
UserDefinedTypeName(Location const& _location, ptr<ASTString> const& _name)
|
||||
UserDefinedTypeName(Location const& _location, ASTPointer<ASTString> const& _name)
|
||||
: TypeName(_location), m_name(_name) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> toType() override { return Type::fromUserDefinedTypeName(*this); }
|
||||
virtual std::shared_ptr<Type> toType() override { return Type::fromUserDefinedTypeName(*this); }
|
||||
|
||||
const ASTString& getName() const { return *m_name; }
|
||||
void setReferencedStruct(StructDefinition& _referencedStruct) { m_referencedStruct = &_referencedStruct; }
|
||||
StructDefinition const* getReferencedStruct() const { return m_referencedStruct; }
|
||||
private:
|
||||
ptr<ASTString> m_name;
|
||||
ASTPointer<ASTString> m_name;
|
||||
|
||||
StructDefinition* m_referencedStruct;
|
||||
};
|
||||
@ -220,14 +220,14 @@ private:
|
||||
class Mapping: public TypeName
|
||||
{
|
||||
public:
|
||||
Mapping(Location const& _location, ptr<ElementaryTypeName> const& _keyType,
|
||||
ptr<TypeName> const& _valueType)
|
||||
Mapping(Location const& _location, ASTPointer<ElementaryTypeName> const& _keyType,
|
||||
ASTPointer<TypeName> const& _valueType)
|
||||
: TypeName(_location), m_keyType(_keyType), m_valueType(_valueType) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> toType() override { return Type::fromMapping(*this); }
|
||||
virtual std::shared_ptr<Type> toType() override { return Type::fromMapping(*this); }
|
||||
private:
|
||||
ptr<ElementaryTypeName> m_keyType;
|
||||
ptr<TypeName> m_valueType;
|
||||
ASTPointer<ElementaryTypeName> m_keyType;
|
||||
ASTPointer<TypeName> m_valueType;
|
||||
};
|
||||
|
||||
/// @}
|
||||
@ -244,7 +244,7 @@ public:
|
||||
//! Check all type requirements, throws exception if some requirement is not met.
|
||||
//! For expressions, this also returns the inferred type of the expression. For other
|
||||
//! statements, returns the empty pointer.
|
||||
virtual ptr<Type> checkTypeRequirements() = 0;
|
||||
virtual void checkTypeRequirements() = 0;
|
||||
protected:
|
||||
//! Check that the inferred type for _expression is _expectedType or at least implicitly
|
||||
//! convertible to _expectedType. If not, throw exception.
|
||||
@ -254,28 +254,28 @@ protected:
|
||||
class Block: public Statement
|
||||
{
|
||||
public:
|
||||
Block(Location const& _location, std::vector<ptr<Statement>> const& _statements)
|
||||
Block(Location const& _location, std::vector<ASTPointer<Statement>> const& _statements)
|
||||
: Statement(_location), m_statements(_statements) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
private:
|
||||
std::vector<ptr<Statement>> m_statements;
|
||||
std::vector<ASTPointer<Statement>> m_statements;
|
||||
};
|
||||
|
||||
class IfStatement: public Statement
|
||||
{
|
||||
public:
|
||||
IfStatement(Location const& _location, ptr<Expression> const& _condition,
|
||||
ptr<Statement> const& _trueBody, ptr<Statement> const& _falseBody)
|
||||
IfStatement(Location const& _location, ASTPointer<Expression> const& _condition,
|
||||
ASTPointer<Statement> const& _trueBody, ASTPointer<Statement> const& _falseBody)
|
||||
: Statement(_location), m_condition(_condition),
|
||||
m_trueBody(_trueBody), m_falseBody(_falseBody) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
private:
|
||||
ptr<Expression> m_condition;
|
||||
ptr<Statement> m_trueBody;
|
||||
ptr<Statement> m_falseBody; //< "else" part, optional
|
||||
ASTPointer<Expression> m_condition;
|
||||
ASTPointer<Statement> m_trueBody;
|
||||
ASTPointer<Statement> m_falseBody; //< "else" part, optional
|
||||
};
|
||||
|
||||
class BreakableStatement: public Statement
|
||||
@ -288,14 +288,14 @@ public:
|
||||
class WhileStatement: public BreakableStatement
|
||||
{
|
||||
public:
|
||||
WhileStatement(Location const& _location, ptr<Expression> const& _condition,
|
||||
ptr<Statement> const& _body)
|
||||
WhileStatement(Location const& _location, ASTPointer<Expression> const& _condition,
|
||||
ASTPointer<Statement> const& _body)
|
||||
: BreakableStatement(_location), m_condition(_condition), m_body(_body) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
private:
|
||||
ptr<Expression> m_condition;
|
||||
ptr<Statement> m_body;
|
||||
ASTPointer<Expression> m_condition;
|
||||
ASTPointer<Statement> m_body;
|
||||
};
|
||||
|
||||
class Continue: public Statement
|
||||
@ -303,7 +303,7 @@ class Continue: public Statement
|
||||
public:
|
||||
Continue(Location const& _location): Statement(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
};
|
||||
|
||||
class Break: public Statement
|
||||
@ -311,20 +311,20 @@ class Break: public Statement
|
||||
public:
|
||||
Break(Location const& _location): Statement(_location) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
};
|
||||
|
||||
class Return: public Statement
|
||||
{
|
||||
public:
|
||||
Return(Location const& _location, ptr<Expression> _expression)
|
||||
Return(Location const& _location, ASTPointer<Expression> _expression)
|
||||
: Statement(_location), m_expression(_expression) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
void setFunctionReturnParameters(ParameterList& _parameters) { m_returnParameters = &_parameters; }
|
||||
private:
|
||||
ptr<Expression> m_expression; //< value to return, optional
|
||||
ASTPointer<Expression> m_expression; //< value to return, optional
|
||||
|
||||
ParameterList* m_returnParameters; //< extracted from the function declaration
|
||||
};
|
||||
@ -332,24 +332,25 @@ private:
|
||||
class VariableDefinition: public Statement
|
||||
{
|
||||
public:
|
||||
VariableDefinition(Location const& _location, ptr<VariableDeclaration> _variable,
|
||||
ptr<Expression> _value)
|
||||
VariableDefinition(Location const& _location, ASTPointer<VariableDeclaration> _variable,
|
||||
ASTPointer<Expression> _value)
|
||||
: Statement(_location), m_variable(_variable), m_value(_value) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
private:
|
||||
ptr<VariableDeclaration> m_variable;
|
||||
ptr<Expression> m_value; ///< can be missing
|
||||
ASTPointer<VariableDeclaration> m_variable;
|
||||
ASTPointer<Expression> m_value; ///< can be missing
|
||||
};
|
||||
|
||||
class Expression: public Statement
|
||||
{
|
||||
public:
|
||||
Expression(Location const& _location): Statement(_location) {}
|
||||
ptr<Type> const& getType() { return m_type; }
|
||||
std::shared_ptr<Type const> const& getType() const { return m_type; }
|
||||
protected:
|
||||
ptr<Type> m_type;
|
||||
//! Inferred type of the expression, only filled after a call to checkTypeRequirements().
|
||||
std::shared_ptr<Type const> m_type;
|
||||
};
|
||||
|
||||
/// @}
|
||||
@ -360,95 +361,95 @@ protected:
|
||||
class Assignment: public Expression
|
||||
{
|
||||
public:
|
||||
Assignment(Location const& _location, ptr<Expression> const& _leftHandSide,
|
||||
Token::Value _assignmentOperator, ptr<Expression> const& _rightHandSide)
|
||||
Assignment(Location const& _location, ASTPointer<Expression> const& _leftHandSide,
|
||||
Token::Value _assignmentOperator, ASTPointer<Expression> const& _rightHandSide)
|
||||
: Expression(_location), m_leftHandSide(_leftHandSide),
|
||||
m_assigmentOperator(_assignmentOperator), m_rightHandSide(_rightHandSide) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Token::Value getAssignmentOperator() const { return m_assigmentOperator; }
|
||||
private:
|
||||
ptr<Expression> m_leftHandSide;
|
||||
ASTPointer<Expression> m_leftHandSide;
|
||||
Token::Value m_assigmentOperator;
|
||||
ptr<Expression> m_rightHandSide;
|
||||
ASTPointer<Expression> m_rightHandSide;
|
||||
};
|
||||
|
||||
class UnaryOperation: public Expression
|
||||
{
|
||||
public:
|
||||
UnaryOperation(Location const& _location, Token::Value _operator,
|
||||
ptr<Expression> const& _subExpression, bool _isPrefix)
|
||||
ASTPointer<Expression> const& _subExpression, bool _isPrefix)
|
||||
: Expression(_location), m_operator(_operator),
|
||||
m_subExpression(_subExpression), m_isPrefix(_isPrefix) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Token::Value getOperator() const { return m_operator; }
|
||||
bool isPrefixOperation() const { return m_isPrefix; }
|
||||
private:
|
||||
Token::Value m_operator;
|
||||
ptr<Expression> m_subExpression;
|
||||
ASTPointer<Expression> m_subExpression;
|
||||
bool m_isPrefix;
|
||||
};
|
||||
|
||||
class BinaryOperation: public Expression
|
||||
{
|
||||
public:
|
||||
BinaryOperation(Location const& _location, ptr<Expression> const& _left,
|
||||
Token::Value _operator, ptr<Expression> const& _right)
|
||||
BinaryOperation(Location const& _location, ASTPointer<Expression> const& _left,
|
||||
Token::Value _operator, ASTPointer<Expression> const& _right)
|
||||
: Expression(_location), m_left(_left), m_operator(_operator), m_right(_right) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Token::Value getOperator() const { return m_operator; }
|
||||
private:
|
||||
ptr<Expression> m_left;
|
||||
ASTPointer<Expression> m_left;
|
||||
Token::Value m_operator;
|
||||
ptr<Expression> m_right;
|
||||
ASTPointer<Expression> m_right;
|
||||
|
||||
ptr<Type> m_commonType;
|
||||
std::shared_ptr<Type const> m_commonType;
|
||||
};
|
||||
|
||||
/// Can be ordinary function call, type cast or struct construction.
|
||||
class FunctionCall: public Expression
|
||||
{
|
||||
public:
|
||||
FunctionCall(Location const& _location, ptr<Expression> const& _expression,
|
||||
std::vector<ptr<Expression>> const& _arguments)
|
||||
FunctionCall(Location const& _location, ASTPointer<Expression> const& _expression,
|
||||
std::vector<ASTPointer<Expression>> const& _arguments)
|
||||
: Expression(_location), m_expression(_expression), m_arguments(_arguments) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
private:
|
||||
ptr<Expression> m_expression;
|
||||
std::vector<ptr<Expression>> m_arguments;
|
||||
ASTPointer<Expression> m_expression;
|
||||
std::vector<ASTPointer<Expression>> m_arguments;
|
||||
};
|
||||
|
||||
class MemberAccess: public Expression
|
||||
{
|
||||
public:
|
||||
MemberAccess(Location const& _location, ptr<Expression> _expression,
|
||||
ptr<ASTString> const& _memberName)
|
||||
MemberAccess(Location const& _location, ASTPointer<Expression> _expression,
|
||||
ASTPointer<ASTString> const& _memberName)
|
||||
: Expression(_location), m_expression(_expression), m_memberName(_memberName) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
const ASTString& getMemberName() const { return *m_memberName; }
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
private:
|
||||
ptr<Expression> m_expression;
|
||||
ptr<ASTString> m_memberName;
|
||||
ASTPointer<Expression> m_expression;
|
||||
ASTPointer<ASTString> m_memberName;
|
||||
};
|
||||
|
||||
class IndexAccess: public Expression
|
||||
{
|
||||
public:
|
||||
IndexAccess(Location const& _location, ptr<Expression> const& _base,
|
||||
ptr<Expression> const& _index)
|
||||
IndexAccess(Location const& _location, ASTPointer<Expression> const& _base,
|
||||
ASTPointer<Expression> const& _index)
|
||||
: Expression(_location), m_base(_base), m_index(_index) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
private:
|
||||
ptr<Expression> m_base;
|
||||
ptr<Expression> m_index;
|
||||
ASTPointer<Expression> m_base;
|
||||
ASTPointer<Expression> m_index;
|
||||
};
|
||||
|
||||
class PrimaryExpression: public Expression
|
||||
@ -460,16 +461,16 @@ public:
|
||||
class Identifier: public PrimaryExpression
|
||||
{
|
||||
public:
|
||||
Identifier(Location const& _location, ptr<ASTString> const& _name)
|
||||
Identifier(Location const& _location, ASTPointer<ASTString> const& _name)
|
||||
: PrimaryExpression(_location), m_name(_name) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
ASTString const& getName() const { return *m_name; }
|
||||
void setReferencedDeclaration(Declaration& _referencedDeclaration) { m_referencedDeclaration = &_referencedDeclaration; }
|
||||
Declaration* getReferencedDeclaration() { return m_referencedDeclaration; }
|
||||
private:
|
||||
ptr<ASTString> m_name;
|
||||
ASTPointer<ASTString> m_name;
|
||||
|
||||
//! Declaration the name refers to.
|
||||
Declaration* m_referencedDeclaration;
|
||||
@ -481,7 +482,7 @@ public:
|
||||
ElementaryTypeNameExpression(Location const& _location, Token::Value _typeToken)
|
||||
: PrimaryExpression(_location), m_typeToken(_typeToken) {}
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Token::Value getTypeToken() const { return m_typeToken; }
|
||||
private:
|
||||
@ -491,16 +492,16 @@ private:
|
||||
class Literal: public PrimaryExpression
|
||||
{
|
||||
public:
|
||||
Literal(Location const& _location, Token::Value _token, ptr<ASTString> const& _value)
|
||||
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 ptr<Type> checkTypeRequirements() override;
|
||||
virtual void checkTypeRequirements() override;
|
||||
|
||||
Token::Value getToken() const { return m_token; }
|
||||
ASTString const& getValue() const { return *m_value; }
|
||||
private:
|
||||
Token::Value m_token;
|
||||
ptr<ASTString> m_value;
|
||||
ASTPointer<ASTString> m_value;
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
@ -69,7 +69,7 @@ class Literal;
|
||||
// not do reference counting but point to a special memory area that is completely released
|
||||
// explicitly.
|
||||
template <class T>
|
||||
using ptr = std::shared_ptr<T>;
|
||||
using ASTPointer = std::shared_ptr<T>;
|
||||
|
||||
using ASTString = std::string;
|
||||
|
||||
|
@ -28,7 +28,7 @@ namespace dev
|
||||
namespace solidity
|
||||
{
|
||||
|
||||
ASTPrinter::ASTPrinter(ptr<ASTNode> _ast, std::string const& _source)
|
||||
ASTPrinter::ASTPrinter(ASTPointer<ASTNode> const& _ast, std::string const& _source)
|
||||
: m_indentation(0), m_source(_source), m_ast(_ast)
|
||||
{
|
||||
}
|
||||
|
@ -35,7 +35,7 @@ class ASTPrinter: public ASTVisitor
|
||||
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(ptr<ASTNode> _ast, const std::string& _source = std::string());
|
||||
ASTPrinter(ASTPointer<ASTNode> const& _ast, const std::string& _source = std::string());
|
||||
/// Output the string representation of the AST to _stream.
|
||||
void print(std::ostream& _stream);
|
||||
|
||||
@ -108,7 +108,7 @@ private:
|
||||
|
||||
int m_indentation;
|
||||
std::string m_source;
|
||||
ptr<ASTNode> m_ast;
|
||||
ASTPointer<ASTNode> m_ast;
|
||||
std::ostream* m_ostream;
|
||||
};
|
||||
|
||||
|
@ -42,9 +42,9 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
|
||||
DeclarationRegistrationHelper registrar(m_scopes, _contract);
|
||||
m_currentScope = &m_scopes[&_contract];
|
||||
//@todo structs
|
||||
for (ptr<VariableDeclaration> const& variable: _contract.getStateVariables())
|
||||
for (ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables())
|
||||
ReferencesResolver resolver(*variable, *this, nullptr);
|
||||
for (ptr<FunctionDefinition> const& function: _contract.getDefinedFunctions())
|
||||
for (ASTPointer<FunctionDefinition> const& function: _contract.getDefinedFunctions())
|
||||
{
|
||||
m_currentScope = &m_scopes[function.get()];
|
||||
ReferencesResolver referencesResolver(*function, *this,
|
||||
@ -53,7 +53,7 @@ void NameAndTypeResolver::resolveNamesAndTypes(ContractDefinition& _contract)
|
||||
// First, the parameter types of all functions need to be resolved before we can check
|
||||
// the types, since it is possible to call functions that are only defined later
|
||||
// in the source.
|
||||
for (ptr<FunctionDefinition> const& function: _contract.getDefinedFunctions())
|
||||
for (ASTPointer<FunctionDefinition> const& function: _contract.getDefinedFunctions())
|
||||
{
|
||||
m_currentScope = &m_scopes[function.get()];
|
||||
function->getBody().checkTypeRequirements();
|
||||
|
@ -23,7 +23,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include <libsolidity/Scope.h>
|
||||
|
172
Parser.cpp
172
Parser.cpp
@ -31,7 +31,7 @@ namespace dev
|
||||
namespace solidity
|
||||
{
|
||||
|
||||
ptr<ContractDefinition> Parser::parse(std::shared_ptr<Scanner> const& _scanner)
|
||||
ASTPointer<ContractDefinition> Parser::parse(std::shared_ptr<Scanner> const& _scanner)
|
||||
{
|
||||
m_scanner = _scanner;
|
||||
return parseContractDefinition();
|
||||
@ -48,10 +48,10 @@ public:
|
||||
void markEndPosition() { m_location.end = m_parser.getEndPosition(); }
|
||||
void setLocationEmpty() { m_location.end = m_location.start; }
|
||||
/// Set the end position to the one of the given node.
|
||||
void setEndPositionFromNode(ptr<ASTNode> const& _node) { m_location.end = _node->getLocation().end; }
|
||||
void setEndPositionFromNode(ASTPointer<ASTNode> const& _node) { m_location.end = _node->getLocation().end; }
|
||||
|
||||
template <class NodeType, typename... Args>
|
||||
ptr<NodeType> createNode(Args&& ... _args)
|
||||
ASTPointer<NodeType> createNode(Args&& ... _args)
|
||||
{
|
||||
if (m_location.end < 0)
|
||||
markEndPosition();
|
||||
@ -74,15 +74,15 @@ int Parser::getEndPosition() const
|
||||
}
|
||||
|
||||
|
||||
ptr<ContractDefinition> Parser::parseContractDefinition()
|
||||
ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
expectToken(Token::CONTRACT);
|
||||
ptr<ASTString> name = expectIdentifierToken();
|
||||
ASTPointer<ASTString> name = expectIdentifierToken();
|
||||
expectToken(Token::LBRACE);
|
||||
std::vector<ptr<StructDefinition>> structs;
|
||||
std::vector<ptr<VariableDeclaration>> stateVariables;
|
||||
std::vector<ptr<FunctionDefinition>> functions;
|
||||
std::vector<ASTPointer<StructDefinition>> structs;
|
||||
std::vector<ASTPointer<VariableDeclaration>> stateVariables;
|
||||
std::vector<ASTPointer<FunctionDefinition>> functions;
|
||||
bool visibilityIsPublic = true;
|
||||
while (true)
|
||||
{
|
||||
@ -115,19 +115,19 @@ ptr<ContractDefinition> Parser::parseContractDefinition()
|
||||
return nodeFactory.createNode<ContractDefinition>(name, structs, stateVariables, functions);
|
||||
}
|
||||
|
||||
ptr<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
|
||||
ASTPointer<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
expectToken(Token::FUNCTION);
|
||||
ptr<ASTString> name(expectIdentifierToken());
|
||||
ptr<ParameterList> parameters(parseParameterList());
|
||||
ASTPointer<ASTString> name(expectIdentifierToken());
|
||||
ASTPointer<ParameterList> parameters(parseParameterList());
|
||||
bool isDeclaredConst = false;
|
||||
if (m_scanner->getCurrentToken() == Token::CONST)
|
||||
{
|
||||
isDeclaredConst = true;
|
||||
m_scanner->next();
|
||||
}
|
||||
ptr<ParameterList> returnParameters;
|
||||
ASTPointer<ParameterList> returnParameters;
|
||||
if (m_scanner->getCurrentToken() == Token::RETURNS)
|
||||
{
|
||||
bool const permitEmptyParameterList = false;
|
||||
@ -139,20 +139,20 @@ ptr<FunctionDefinition> Parser::parseFunctionDefinition(bool _isPublic)
|
||||
// create an empty parameter list at a zero-length location
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
nodeFactory.setLocationEmpty();
|
||||
returnParameters = nodeFactory.createNode<ParameterList>(std::vector<ptr<VariableDeclaration>>());
|
||||
returnParameters = nodeFactory.createNode<ParameterList>(std::vector<ASTPointer<VariableDeclaration>>());
|
||||
}
|
||||
ptr<Block> block = parseBlock();
|
||||
ASTPointer<Block> block = parseBlock();
|
||||
nodeFactory.setEndPositionFromNode(block);
|
||||
return nodeFactory.createNode<FunctionDefinition>(name, _isPublic, parameters,
|
||||
isDeclaredConst, returnParameters, block);
|
||||
}
|
||||
|
||||
ptr<StructDefinition> Parser::parseStructDefinition()
|
||||
ASTPointer<StructDefinition> Parser::parseStructDefinition()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
expectToken(Token::STRUCT);
|
||||
ptr<ASTString> name = expectIdentifierToken();
|
||||
std::vector<ptr<VariableDeclaration>> members;
|
||||
ASTPointer<ASTString> name = expectIdentifierToken();
|
||||
std::vector<ASTPointer<VariableDeclaration>> members;
|
||||
expectToken(Token::LBRACE);
|
||||
while (m_scanner->getCurrentToken() != Token::RBRACE)
|
||||
{
|
||||
@ -165,17 +165,17 @@ ptr<StructDefinition> Parser::parseStructDefinition()
|
||||
return nodeFactory.createNode<StructDefinition>(name, members);
|
||||
}
|
||||
|
||||
ptr<VariableDeclaration> Parser::parseVariableDeclaration(bool _allowVar)
|
||||
ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(bool _allowVar)
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
ptr<TypeName> type = parseTypeName(_allowVar);
|
||||
ASTPointer<TypeName> type = parseTypeName(_allowVar);
|
||||
nodeFactory.markEndPosition();
|
||||
return nodeFactory.createNode<VariableDeclaration>(type, expectIdentifierToken());
|
||||
}
|
||||
|
||||
ptr<TypeName> Parser::parseTypeName(bool _allowVar)
|
||||
ASTPointer<TypeName> Parser::parseTypeName(bool _allowVar)
|
||||
{
|
||||
ptr<TypeName> type;
|
||||
ASTPointer<TypeName> type;
|
||||
Token::Value token = m_scanner->getCurrentToken();
|
||||
if (Token::isElementaryTypeName(token))
|
||||
{
|
||||
@ -203,28 +203,28 @@ ptr<TypeName> Parser::parseTypeName(bool _allowVar)
|
||||
return type;
|
||||
}
|
||||
|
||||
ptr<Mapping> Parser::parseMapping()
|
||||
ASTPointer<Mapping> Parser::parseMapping()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
expectToken(Token::MAPPING);
|
||||
expectToken(Token::LPAREN);
|
||||
if (!Token::isElementaryTypeName(m_scanner->getCurrentToken()))
|
||||
throwExpectationError("Expected elementary type name for mapping key type");
|
||||
ptr<ElementaryTypeName> keyType;
|
||||
ASTPointer<ElementaryTypeName> keyType;
|
||||
keyType = ASTNodeFactory(*this).createNode<ElementaryTypeName>(m_scanner->getCurrentToken());
|
||||
m_scanner->next();
|
||||
expectToken(Token::ARROW);
|
||||
bool const allowVar = false;
|
||||
ptr<TypeName> valueType = parseTypeName(allowVar);
|
||||
ASTPointer<TypeName> valueType = parseTypeName(allowVar);
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RPAREN);
|
||||
return nodeFactory.createNode<Mapping>(keyType, valueType);
|
||||
}
|
||||
|
||||
ptr<ParameterList> Parser::parseParameterList(bool _allowEmpty)
|
||||
ASTPointer<ParameterList> Parser::parseParameterList(bool _allowEmpty)
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
std::vector<ptr<VariableDeclaration>> parameters;
|
||||
std::vector<ASTPointer<VariableDeclaration>> parameters;
|
||||
expectToken(Token::LPAREN);
|
||||
if (!_allowEmpty || m_scanner->getCurrentToken() != Token::RPAREN)
|
||||
{
|
||||
@ -241,11 +241,11 @@ ptr<ParameterList> Parser::parseParameterList(bool _allowEmpty)
|
||||
return nodeFactory.createNode<ParameterList>(parameters);
|
||||
}
|
||||
|
||||
ptr<Block> Parser::parseBlock()
|
||||
ASTPointer<Block> Parser::parseBlock()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
expectToken(Token::LBRACE);
|
||||
std::vector<ptr<Statement>> statements;
|
||||
std::vector<ASTPointer<Statement>> statements;
|
||||
while (m_scanner->getCurrentToken() != Token::RBRACE)
|
||||
statements.push_back(parseStatement());
|
||||
nodeFactory.markEndPosition();
|
||||
@ -253,9 +253,9 @@ ptr<Block> Parser::parseBlock()
|
||||
return nodeFactory.createNode<Block>(statements);
|
||||
}
|
||||
|
||||
ptr<Statement> Parser::parseStatement()
|
||||
ASTPointer<Statement> Parser::parseStatement()
|
||||
{
|
||||
ptr<Statement> statement;
|
||||
ASTPointer<Statement> statement;
|
||||
switch (m_scanner->getCurrentToken())
|
||||
{
|
||||
case Token::IF:
|
||||
@ -274,7 +274,7 @@ ptr<Statement> Parser::parseStatement()
|
||||
case Token::RETURN:
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
ptr<Expression> expression;
|
||||
ASTPointer<Expression> expression;
|
||||
if (m_scanner->next() != Token::SEMICOLON)
|
||||
{
|
||||
expression = parseExpression();
|
||||
@ -301,15 +301,15 @@ ptr<Statement> Parser::parseStatement()
|
||||
return statement;
|
||||
}
|
||||
|
||||
ptr<IfStatement> Parser::parseIfStatement()
|
||||
ASTPointer<IfStatement> Parser::parseIfStatement()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
expectToken(Token::IF);
|
||||
expectToken(Token::LPAREN);
|
||||
ptr<Expression> condition = parseExpression();
|
||||
ASTPointer<Expression> condition = parseExpression();
|
||||
expectToken(Token::RPAREN);
|
||||
ptr<Statement> trueBody = parseStatement();
|
||||
ptr<Statement> falseBody;
|
||||
ASTPointer<Statement> trueBody = parseStatement();
|
||||
ASTPointer<Statement> falseBody;
|
||||
if (m_scanner->getCurrentToken() == Token::ELSE)
|
||||
{
|
||||
m_scanner->next();
|
||||
@ -321,24 +321,24 @@ ptr<IfStatement> Parser::parseIfStatement()
|
||||
return nodeFactory.createNode<IfStatement>(condition, trueBody, falseBody);
|
||||
}
|
||||
|
||||
ptr<WhileStatement> Parser::parseWhileStatement()
|
||||
ASTPointer<WhileStatement> Parser::parseWhileStatement()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
expectToken(Token::WHILE);
|
||||
expectToken(Token::LPAREN);
|
||||
ptr<Expression> condition = parseExpression();
|
||||
ASTPointer<Expression> condition = parseExpression();
|
||||
expectToken(Token::RPAREN);
|
||||
ptr<Statement> body = parseStatement();
|
||||
ASTPointer<Statement> body = parseStatement();
|
||||
nodeFactory.setEndPositionFromNode(body);
|
||||
return nodeFactory.createNode<WhileStatement>(condition, body);
|
||||
}
|
||||
|
||||
ptr<VariableDefinition> Parser::parseVariableDefinition()
|
||||
ASTPointer<VariableDefinition> Parser::parseVariableDefinition()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
bool const allowVar = true;
|
||||
ptr<VariableDeclaration> variable = parseVariableDeclaration(allowVar);
|
||||
ptr<Expression> value;
|
||||
ASTPointer<VariableDeclaration> variable = parseVariableDeclaration(allowVar);
|
||||
ASTPointer<Expression> value;
|
||||
if (m_scanner->getCurrentToken() == Token::ASSIGN)
|
||||
{
|
||||
m_scanner->next();
|
||||
@ -350,22 +350,22 @@ ptr<VariableDefinition> Parser::parseVariableDefinition()
|
||||
return nodeFactory.createNode<VariableDefinition>(variable, value);
|
||||
}
|
||||
|
||||
ptr<Expression> Parser::parseExpression()
|
||||
ASTPointer<Expression> Parser::parseExpression()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
ptr<Expression> expression = parseBinaryExpression();
|
||||
ASTPointer<Expression> expression = parseBinaryExpression();
|
||||
if (!Token::isAssignmentOp(m_scanner->getCurrentToken()))
|
||||
return expression;
|
||||
Token::Value assignmentOperator = expectAssignmentOperator();
|
||||
ptr<Expression> rightHandSide = parseExpression();
|
||||
ASTPointer<Expression> rightHandSide = parseExpression();
|
||||
nodeFactory.setEndPositionFromNode(rightHandSide);
|
||||
return nodeFactory.createNode<Assignment>(expression, assignmentOperator, rightHandSide);
|
||||
}
|
||||
|
||||
ptr<Expression> Parser::parseBinaryExpression(int _minPrecedence)
|
||||
ASTPointer<Expression> Parser::parseBinaryExpression(int _minPrecedence)
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
ptr<Expression> expression = parseUnaryExpression();
|
||||
ASTPointer<Expression> expression = parseUnaryExpression();
|
||||
int precedence = Token::precedence(m_scanner->getCurrentToken());
|
||||
for (; precedence >= _minPrecedence; --precedence)
|
||||
{
|
||||
@ -373,7 +373,7 @@ ptr<Expression> Parser::parseBinaryExpression(int _minPrecedence)
|
||||
{
|
||||
Token::Value op = m_scanner->getCurrentToken();
|
||||
m_scanner->next();
|
||||
ptr<Expression> right = parseBinaryExpression(precedence + 1);
|
||||
ASTPointer<Expression> right = parseBinaryExpression(precedence + 1);
|
||||
nodeFactory.setEndPositionFromNode(right);
|
||||
expression = nodeFactory.createNode<BinaryOperation>(expression, op, right);
|
||||
}
|
||||
@ -381,7 +381,7 @@ ptr<Expression> Parser::parseBinaryExpression(int _minPrecedence)
|
||||
return expression;
|
||||
}
|
||||
|
||||
ptr<Expression> Parser::parseUnaryExpression()
|
||||
ASTPointer<Expression> Parser::parseUnaryExpression()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
Token::Value token = m_scanner->getCurrentToken();
|
||||
@ -389,14 +389,14 @@ ptr<Expression> Parser::parseUnaryExpression()
|
||||
{
|
||||
// prefix expression
|
||||
m_scanner->next();
|
||||
ptr<Expression> subExpression = parseUnaryExpression();
|
||||
ASTPointer<Expression> subExpression = parseUnaryExpression();
|
||||
nodeFactory.setEndPositionFromNode(subExpression);
|
||||
return nodeFactory.createNode<UnaryOperation>(token, subExpression, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// potential postfix expression
|
||||
ptr<Expression> subExpression = parseLeftHandSideExpression();
|
||||
ASTPointer<Expression> subExpression = parseLeftHandSideExpression();
|
||||
token = m_scanner->getCurrentToken();
|
||||
if (!Token::isCountOp(token))
|
||||
return subExpression;
|
||||
@ -406,38 +406,38 @@ ptr<Expression> Parser::parseUnaryExpression()
|
||||
}
|
||||
}
|
||||
|
||||
ptr<Expression> Parser::parseLeftHandSideExpression()
|
||||
ASTPointer<Expression> Parser::parseLeftHandSideExpression()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
ptr<Expression> expression = parsePrimaryExpression();
|
||||
ASTPointer<Expression> expression = parsePrimaryExpression();
|
||||
while (true)
|
||||
{
|
||||
switch (m_scanner->getCurrentToken())
|
||||
{
|
||||
case Token::LBRACK:
|
||||
{
|
||||
m_scanner->next();
|
||||
ptr<Expression> index = parseExpression();
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RBRACK);
|
||||
expression = nodeFactory.createNode<IndexAccess>(expression, index);
|
||||
}
|
||||
{
|
||||
m_scanner->next();
|
||||
ASTPointer<Expression> index = parseExpression();
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RBRACK);
|
||||
expression = nodeFactory.createNode<IndexAccess>(expression, index);
|
||||
}
|
||||
break;
|
||||
case Token::PERIOD:
|
||||
{
|
||||
m_scanner->next();
|
||||
nodeFactory.markEndPosition();
|
||||
expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken());
|
||||
}
|
||||
{
|
||||
m_scanner->next();
|
||||
nodeFactory.markEndPosition();
|
||||
expression = nodeFactory.createNode<MemberAccess>(expression, expectIdentifierToken());
|
||||
}
|
||||
break;
|
||||
case Token::LPAREN:
|
||||
{
|
||||
m_scanner->next();
|
||||
std::vector<ptr<Expression>> arguments = parseFunctionCallArguments();
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RPAREN);
|
||||
expression = nodeFactory.createNode<FunctionCall>(expression, arguments);
|
||||
}
|
||||
{
|
||||
m_scanner->next();
|
||||
std::vector<ASTPointer<Expression>> arguments = parseFunctionCallArguments();
|
||||
nodeFactory.markEndPosition();
|
||||
expectToken(Token::RPAREN);
|
||||
expression = nodeFactory.createNode<FunctionCall>(expression, arguments);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return expression;
|
||||
@ -445,16 +445,16 @@ ptr<Expression> Parser::parseLeftHandSideExpression()
|
||||
}
|
||||
}
|
||||
|
||||
ptr<Expression> Parser::parsePrimaryExpression()
|
||||
ASTPointer<Expression> Parser::parsePrimaryExpression()
|
||||
{
|
||||
ASTNodeFactory nodeFactory(*this);
|
||||
Token::Value token = m_scanner->getCurrentToken();
|
||||
ptr<Expression> expression;
|
||||
ASTPointer<Expression> expression;
|
||||
switch (token)
|
||||
{
|
||||
case Token::TRUE_LITERAL:
|
||||
case Token::FALSE_LITERAL:
|
||||
expression = nodeFactory.createNode<Literal>(token, ptr<ASTString>());
|
||||
expression = nodeFactory.createNode<Literal>(token, ASTPointer<ASTString>());
|
||||
m_scanner->next();
|
||||
break;
|
||||
case Token::NUMBER:
|
||||
@ -467,12 +467,12 @@ ptr<Expression> Parser::parsePrimaryExpression()
|
||||
expression = nodeFactory.createNode<Identifier>(getLiteralAndAdvance());
|
||||
break;
|
||||
case Token::LPAREN:
|
||||
{
|
||||
m_scanner->next();
|
||||
ptr<Expression> expression = parseExpression();
|
||||
expectToken(Token::RPAREN);
|
||||
return expression;
|
||||
}
|
||||
{
|
||||
m_scanner->next();
|
||||
ASTPointer<Expression> expression = parseExpression();
|
||||
expectToken(Token::RPAREN);
|
||||
return expression;
|
||||
}
|
||||
default:
|
||||
if (Token::isElementaryTypeName(token))
|
||||
{
|
||||
@ -483,16 +483,16 @@ ptr<Expression> Parser::parsePrimaryExpression()
|
||||
else
|
||||
{
|
||||
throwExpectationError("Expected primary expression.");
|
||||
return ptr<Expression>(); // this is not reached
|
||||
return ASTPointer<Expression>(); // this is not reached
|
||||
}
|
||||
break;
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
std::vector<ptr<Expression>> Parser::parseFunctionCallArguments()
|
||||
std::vector<ASTPointer<Expression>> Parser::parseFunctionCallArguments()
|
||||
{
|
||||
std::vector<ptr<Expression>> arguments;
|
||||
std::vector<ASTPointer<Expression>> arguments;
|
||||
if (m_scanner->getCurrentToken() != Token::RPAREN)
|
||||
{
|
||||
arguments.push_back(parseExpression());
|
||||
@ -521,16 +521,16 @@ Token::Value Parser::expectAssignmentOperator()
|
||||
return op;
|
||||
}
|
||||
|
||||
ptr<ASTString> Parser::expectIdentifierToken()
|
||||
ASTPointer<ASTString> Parser::expectIdentifierToken()
|
||||
{
|
||||
if (m_scanner->getCurrentToken() != Token::IDENTIFIER)
|
||||
throwExpectationError("Expected identifier");
|
||||
return getLiteralAndAdvance();
|
||||
}
|
||||
|
||||
ptr<ASTString> Parser::getLiteralAndAdvance()
|
||||
ASTPointer<ASTString> Parser::getLiteralAndAdvance()
|
||||
{
|
||||
ptr<ASTString> identifier = std::make_shared<ASTString>(m_scanner->getCurrentLiteral());
|
||||
ASTPointer<ASTString> identifier = std::make_shared<ASTString>(m_scanner->getCurrentLiteral());
|
||||
m_scanner->next();
|
||||
return identifier;
|
||||
}
|
||||
|
42
Parser.h
42
Parser.h
@ -34,7 +34,7 @@ class Scanner;
|
||||
class Parser
|
||||
{
|
||||
public:
|
||||
ptr<ContractDefinition> parse(std::shared_ptr<Scanner> const& _scanner);
|
||||
ASTPointer<ContractDefinition> parse(std::shared_ptr<Scanner> const& _scanner);
|
||||
|
||||
private:
|
||||
class ASTNodeFactory;
|
||||
@ -46,24 +46,24 @@ private:
|
||||
|
||||
/// Parsing functions for the AST nodes
|
||||
/// @{
|
||||
ptr<ContractDefinition> parseContractDefinition();
|
||||
ptr<FunctionDefinition> parseFunctionDefinition(bool _isPublic);
|
||||
ptr<StructDefinition> parseStructDefinition();
|
||||
ptr<VariableDeclaration> parseVariableDeclaration(bool _allowVar);
|
||||
ptr<TypeName> parseTypeName(bool _allowVar);
|
||||
ptr<Mapping> parseMapping();
|
||||
ptr<ParameterList> parseParameterList(bool _allowEmpty = true);
|
||||
ptr<Block> parseBlock();
|
||||
ptr<Statement> parseStatement();
|
||||
ptr<IfStatement> parseIfStatement();
|
||||
ptr<WhileStatement> parseWhileStatement();
|
||||
ptr<VariableDefinition> parseVariableDefinition();
|
||||
ptr<Expression> parseExpression();
|
||||
ptr<Expression> parseBinaryExpression(int _minPrecedence = 4);
|
||||
ptr<Expression> parseUnaryExpression();
|
||||
ptr<Expression> parseLeftHandSideExpression();
|
||||
ptr<Expression> parsePrimaryExpression();
|
||||
std::vector<ptr<Expression>> parseFunctionCallArguments();
|
||||
ASTPointer<ContractDefinition> parseContractDefinition();
|
||||
ASTPointer<FunctionDefinition> parseFunctionDefinition(bool _isPublic);
|
||||
ASTPointer<StructDefinition> parseStructDefinition();
|
||||
ASTPointer<VariableDeclaration> parseVariableDeclaration(bool _allowVar);
|
||||
ASTPointer<TypeName> parseTypeName(bool _allowVar);
|
||||
ASTPointer<Mapping> parseMapping();
|
||||
ASTPointer<ParameterList> parseParameterList(bool _allowEmpty = true);
|
||||
ASTPointer<Block> parseBlock();
|
||||
ASTPointer<Statement> parseStatement();
|
||||
ASTPointer<IfStatement> parseIfStatement();
|
||||
ASTPointer<WhileStatement> parseWhileStatement();
|
||||
ASTPointer<VariableDefinition> parseVariableDefinition();
|
||||
ASTPointer<Expression> parseExpression();
|
||||
ASTPointer<Expression> parseBinaryExpression(int _minPrecedence = 4);
|
||||
ASTPointer<Expression> parseUnaryExpression();
|
||||
ASTPointer<Expression> parseLeftHandSideExpression();
|
||||
ASTPointer<Expression> parsePrimaryExpression();
|
||||
std::vector<ASTPointer<Expression>> parseFunctionCallArguments();
|
||||
/// @}
|
||||
|
||||
/// Helper functions
|
||||
@ -71,8 +71,8 @@ private:
|
||||
/// If current token value is not _value, throw exception otherwise advance token.
|
||||
void expectToken(Token::Value _value);
|
||||
Token::Value expectAssignmentOperator();
|
||||
ptr<ASTString> expectIdentifierToken();
|
||||
ptr<ASTString> getLiteralAndAdvance();
|
||||
ASTPointer<ASTString> expectIdentifierToken();
|
||||
ASTPointer<ASTString> getLiteralAndAdvance();
|
||||
void throwExpectationError(std::string const& _description);
|
||||
/// @}
|
||||
|
||||
|
31
Scanner.cpp
31
Scanner.cpp
@ -81,12 +81,15 @@ bool IsIdentifierPart(char c)
|
||||
|
||||
int HexValue(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9') return c - '0';
|
||||
else if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
else if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
else if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
else return -1;
|
||||
}
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
Scanner::Scanner(CharStream const& _source)
|
||||
{
|
||||
@ -409,13 +412,15 @@ bool Scanner::scanEscape()
|
||||
c = '\t';
|
||||
break;
|
||||
case 'u':
|
||||
if (!scanHexNumber(c, 4)) return false;
|
||||
if (!scanHexNumber(c, 4))
|
||||
return false;
|
||||
break;
|
||||
case 'v':
|
||||
c = '\v';
|
||||
break;
|
||||
case 'x':
|
||||
if (!scanHexNumber(c, 2)) return false;
|
||||
if (!scanHexNumber(c, 2))
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
@ -612,9 +617,8 @@ case ch:
|
||||
int const keyword_length = sizeof(keyword) - 1; \
|
||||
BOOST_STATIC_ASSERT(keyword_length >= kMinLength); \
|
||||
BOOST_STATIC_ASSERT(keyword_length <= kMaxLength); \
|
||||
if (input == keyword) { \
|
||||
return token; \
|
||||
} \
|
||||
if (input == keyword) \
|
||||
return token; \
|
||||
}
|
||||
KEYWORDS(KEYWORD_GROUP_CASE, KEYWORD)
|
||||
}
|
||||
@ -635,9 +639,11 @@ Token::Value Scanner::scanIdentifierOrKeyword()
|
||||
|
||||
char CharStream::advanceAndGet()
|
||||
{
|
||||
if (isPastEndOfInput()) return 0;
|
||||
if (isPastEndOfInput())
|
||||
return 0;
|
||||
++m_pos;
|
||||
if (isPastEndOfInput()) return 0;
|
||||
if (isPastEndOfInput())
|
||||
return 0;
|
||||
return get();
|
||||
}
|
||||
|
||||
@ -653,7 +659,8 @@ std::string CharStream::getLineAtPosition(int _position) const
|
||||
// if _position points to \n, it returns the line before the \n
|
||||
using size_type = std::string::size_type;
|
||||
size_type searchStart = std::min<size_type>(m_source.size(), _position);
|
||||
if (searchStart > 0) searchStart--;
|
||||
if (searchStart > 0)
|
||||
searchStart--;
|
||||
size_type lineStart = m_source.rfind('\n', searchStart);
|
||||
if (lineStart == std::string::npos)
|
||||
lineStart = 0;
|
||||
|
1
Scope.h
1
Scope.h
@ -23,7 +23,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
#include <libsolidity/ASTForward.h>
|
||||
|
16
Types.cpp
16
Types.cpp
@ -28,7 +28,7 @@ namespace dev
|
||||
namespace solidity
|
||||
{
|
||||
|
||||
ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken)
|
||||
std::shared_ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken)
|
||||
{
|
||||
if (Token::INT <= _typeToken && _typeToken <= Token::HASH256)
|
||||
{
|
||||
@ -52,18 +52,18 @@ ptr<Type> Type::fromElementaryTypeName(Token::Value _typeToken)
|
||||
BOOST_ASSERT(false); // @todo add other tyes
|
||||
}
|
||||
|
||||
ptr<Type> Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName)
|
||||
std::shared_ptr<Type> Type::fromUserDefinedTypeName(UserDefinedTypeName const& _typeName)
|
||||
{
|
||||
return std::make_shared<StructType>(*_typeName.getReferencedStruct());
|
||||
}
|
||||
|
||||
ptr<Type> Type::fromMapping(Mapping const&)
|
||||
std::shared_ptr<Type> Type::fromMapping(Mapping const&)
|
||||
{
|
||||
BOOST_ASSERT(false); //@todo not yet implemented
|
||||
return ptr<Type>();
|
||||
return std::shared_ptr<Type>();
|
||||
}
|
||||
|
||||
ptr<Type> Type::forLiteral(Literal const& _literal)
|
||||
std::shared_ptr<Type> Type::forLiteral(Literal const& _literal)
|
||||
{
|
||||
switch (_literal.getToken())
|
||||
{
|
||||
@ -73,13 +73,13 @@ ptr<Type> Type::forLiteral(Literal const& _literal)
|
||||
case Token::NUMBER:
|
||||
return IntegerType::smallestTypeForLiteral(_literal.getValue());
|
||||
case Token::STRING_LITERAL:
|
||||
return ptr<Type>(); // @todo
|
||||
return std::shared_ptr<Type>(); // @todo
|
||||
default:
|
||||
return ptr<Type>();
|
||||
return std::shared_ptr<Type>();
|
||||
}
|
||||
}
|
||||
|
||||
ptr<IntegerType> IntegerType::smallestTypeForLiteral(const std::string&)
|
||||
std::shared_ptr<IntegerType> IntegerType::smallestTypeForLiteral(std::string const&)
|
||||
{
|
||||
//@todo
|
||||
return std::make_shared<IntegerType>(256, Modifier::UNSIGNED);
|
||||
|
35
Types.h
35
Types.h
@ -26,7 +26,7 @@
|
||||
#include <string>
|
||||
#include <boost/noncopyable.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
|
||||
#include <libsolidity/ASTForward.h>
|
||||
#include <libsolidity/Token.h>
|
||||
|
||||
namespace dev
|
||||
@ -34,18 +34,6 @@ namespace dev
|
||||
namespace solidity
|
||||
{
|
||||
|
||||
// AST forward declarations
|
||||
class ContractDefinition;
|
||||
class FunctionDefinition;
|
||||
class StructDefinition;
|
||||
class Literal;
|
||||
class ElementaryTypeName;
|
||||
class UserDefinedTypeName;
|
||||
class Mapping;
|
||||
|
||||
template <typename T>
|
||||
using ptr = std::shared_ptr<T>;
|
||||
|
||||
// @todo realMxN, string<N>, mapping
|
||||
|
||||
class Type: private boost::noncopyable
|
||||
@ -57,11 +45,11 @@ public:
|
||||
};
|
||||
|
||||
//! factory functions that convert an AST TypeName to a Type.
|
||||
static ptr<Type> fromElementaryTypeName(Token::Value _typeToken);
|
||||
static ptr<Type> fromUserDefinedTypeName(UserDefinedTypeName const& _typeName);
|
||||
static ptr<Type> fromMapping(Mapping const& _typeName);
|
||||
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 ptr<Type> forLiteral(Literal const& _literal);
|
||||
static std::shared_ptr<Type> forLiteral(Literal const& _literal);
|
||||
|
||||
virtual Category getCategory() const = 0;
|
||||
virtual bool isImplicitlyConvertibleTo(Type const&) const { return false; }
|
||||
@ -82,7 +70,7 @@ public:
|
||||
};
|
||||
virtual Category getCategory() const { return Category::INTEGER; }
|
||||
|
||||
static ptr<IntegerType> smallestTypeForLiteral(std::string const& _literal);
|
||||
static std::shared_ptr<IntegerType> smallestTypeForLiteral(std::string const& _literal);
|
||||
|
||||
explicit IntegerType(int _bits, Modifier _modifier = Modifier::UNSIGNED);
|
||||
|
||||
@ -95,6 +83,7 @@ public:
|
||||
bool isHash() const { return m_modifier == Modifier::HASH || m_modifier == Modifier::ADDRESS; }
|
||||
bool isAddress() const { return m_modifier == Modifier::ADDRESS; }
|
||||
int isSigned() const { return m_modifier == Modifier::SIGNED; }
|
||||
|
||||
private:
|
||||
int m_bits;
|
||||
Modifier m_modifier;
|
||||
@ -125,6 +114,7 @@ public:
|
||||
virtual Category getCategory() const { return Category::CONTRACT; }
|
||||
ContractType(ContractDefinition const& _contract): m_contract(_contract) {}
|
||||
virtual bool isImplicitlyConvertibleTo(Type const& _convertTo) const;
|
||||
|
||||
private:
|
||||
ContractDefinition const& m_contract;
|
||||
};
|
||||
@ -139,6 +129,7 @@ public:
|
||||
{
|
||||
return _operator == Token::DELETE;
|
||||
}
|
||||
|
||||
private:
|
||||
StructDefinition const& m_struct;
|
||||
};
|
||||
@ -150,6 +141,7 @@ public:
|
||||
FunctionType(FunctionDefinition const& _function): m_function(_function) {}
|
||||
|
||||
FunctionDefinition const& getFunction() const { return m_function; }
|
||||
|
||||
private:
|
||||
FunctionDefinition const& m_function;
|
||||
};
|
||||
@ -175,11 +167,12 @@ class TypeType: public Type
|
||||
{
|
||||
public:
|
||||
virtual Category getCategory() const { return Category::TYPE; }
|
||||
TypeType(ptr<Type> const& _actualType): m_actualType(_actualType) {}
|
||||
TypeType(std::shared_ptr<Type const> const& _actualType): m_actualType(_actualType) {}
|
||||
|
||||
std::shared_ptr<Type const> const& getActualType() const { return m_actualType; }
|
||||
|
||||
ptr<Type> const& getActualType() { return m_actualType; }
|
||||
private:
|
||||
ptr<Type> m_actualType;
|
||||
std::shared_ptr<Type const> m_actualType;
|
||||
};
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user