mirror of
https://github.com/ethereum/solidity
synced 2023-10-03 13:03:40 +00:00
added parsing for constant variables
This commit is contained in:
parent
a16677dcfb
commit
67cd3a7180
6
AST.cpp
6
AST.cpp
@ -197,7 +197,7 @@ vector<pair<FixedHash<4>, FunctionTypePointer>> const& ContractDefinition::getIn
|
||||
}
|
||||
|
||||
for (ASTPointer<VariableDeclaration> const& v: contract->getStateVariables())
|
||||
if (v->isPublic() && functionsSeen.count(v->getName()) == 0)
|
||||
if (v->isPublic() && functionsSeen.count(v->getName()) == 0 && !v->isConstant())
|
||||
{
|
||||
FunctionType ftype(*v);
|
||||
functionsSeen.insert(v->getName());
|
||||
@ -322,8 +322,8 @@ string FunctionDefinition::getCanonicalSignature() const
|
||||
|
||||
bool VariableDeclaration::isLValue() const
|
||||
{
|
||||
// External function parameters are Read-Only
|
||||
return !isExternalFunctionParameter();
|
||||
// External function parameters and constant declared variables are Read-Only
|
||||
return !isExternalFunctionParameter() && !m_isConstant;
|
||||
}
|
||||
|
||||
void VariableDeclaration::checkTypeRequirements()
|
||||
|
27
AST.h
27
AST.h
@ -440,13 +440,22 @@ private:
|
||||
class VariableDeclaration: public Declaration
|
||||
{
|
||||
public:
|
||||
VariableDeclaration(SourceLocation const& _location, ASTPointer<TypeName> const& _type,
|
||||
ASTPointer<ASTString> const& _name, ASTPointer<Expression> _value,
|
||||
Visibility _visibility,
|
||||
bool _isStateVar = false, bool _isIndexed = false):
|
||||
Declaration(_location, _name, _visibility),
|
||||
m_typeName(_type), m_value(_value),
|
||||
m_isStateVariable(_isStateVar), m_isIndexed(_isIndexed) {}
|
||||
VariableDeclaration(
|
||||
SourceLocation const& _location,
|
||||
ASTPointer<TypeName> const& _type,
|
||||
ASTPointer<ASTString> const& _name,
|
||||
ASTPointer<Expression> _value,
|
||||
Visibility _visibility,
|
||||
bool _isStateVar = false,
|
||||
bool _isIndexed = false,
|
||||
bool _isConstant = false):
|
||||
Declaration(_location, _name, _visibility),
|
||||
m_typeName(_type),
|
||||
m_value(_value),
|
||||
m_isStateVariable(_isStateVar),
|
||||
m_isIndexed(_isIndexed),
|
||||
m_isConstant(_isConstant){}
|
||||
|
||||
virtual void accept(ASTVisitor& _visitor) override;
|
||||
virtual void accept(ASTConstVisitor& _visitor) const override;
|
||||
|
||||
@ -465,15 +474,17 @@ public:
|
||||
bool isExternalFunctionParameter() const;
|
||||
bool isStateVariable() const { return m_isStateVariable; }
|
||||
bool isIndexed() const { return m_isIndexed; }
|
||||
bool isConstant() const { return m_isConstant; }
|
||||
|
||||
protected:
|
||||
Visibility getDefaultVisibility() const override { return Visibility::Internal; }
|
||||
|
||||
private:
|
||||
ASTPointer<TypeName> m_typeName; ///< can be empty ("var")
|
||||
ASTPointer<Expression> m_value; ///< the assigned value, can be missing
|
||||
ASTPointer<Expression> m_value; ///< the assigned value, can be missing
|
||||
bool m_isStateVariable; ///< Whether or not this is a contract state variable
|
||||
bool m_isIndexed; ///< Whether this is an indexed variable (used by events).
|
||||
bool m_isConstant; ///< Whether the variable is a compile-time constant.
|
||||
|
||||
std::shared_ptr<Type const> m_type; ///< derived type, initially empty
|
||||
};
|
||||
|
@ -276,13 +276,14 @@ void Compiler::registerStateVariables(ContractDefinition const& _contract)
|
||||
{
|
||||
for (ContractDefinition const* contract: boost::adaptors::reverse(_contract.getLinearizedBaseContracts()))
|
||||
for (ASTPointer<VariableDeclaration> const& variable: contract->getStateVariables())
|
||||
m_context.addStateVariable(*variable);
|
||||
if (!variable->isConstant())
|
||||
m_context.addStateVariable(*variable);
|
||||
}
|
||||
|
||||
void Compiler::initializeStateVariables(ContractDefinition const& _contract)
|
||||
{
|
||||
for (ASTPointer<VariableDeclaration> const& variable: _contract.getStateVariables())
|
||||
if (variable->getValue())
|
||||
if (variable->getValue() && !variable->isConstant())
|
||||
ExpressionCompiler(m_context, m_optimize).appendStateVariableInitialization(*variable);
|
||||
}
|
||||
|
||||
|
@ -855,8 +855,11 @@ void ExpressionCompiler::endVisit(Identifier const& _identifier)
|
||||
}
|
||||
else if (FunctionDefinition const* functionDef = dynamic_cast<FunctionDefinition const*>(declaration))
|
||||
m_context << m_context.getVirtualFunctionEntryLabel(*functionDef).pushTag();
|
||||
else if (dynamic_cast<VariableDeclaration const*>(declaration))
|
||||
setLValueFromDeclaration(*declaration, _identifier);
|
||||
else if (auto variable = dynamic_cast<VariableDeclaration const*>(declaration))
|
||||
{
|
||||
if (!variable->isConstant())
|
||||
setLValueFromDeclaration(*declaration, _identifier);
|
||||
}
|
||||
else if (dynamic_cast<ContractDefinition const*>(declaration))
|
||||
{
|
||||
// no-op
|
||||
|
11
Parser.cpp
11
Parser.cpp
@ -135,6 +135,7 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
||||
}
|
||||
while (m_scanner->getCurrentToken() == Token::Comma);
|
||||
expectToken(Token::LBrace);
|
||||
bool isDeclaredConst = false;
|
||||
while (true)
|
||||
{
|
||||
Token::Value currentToken = m_scanner->getCurrentToken();
|
||||
@ -152,13 +153,21 @@ ASTPointer<ContractDefinition> Parser::parseContractDefinition()
|
||||
VarDeclParserOptions options;
|
||||
options.isStateVariable = true;
|
||||
options.allowInitialValue = true;
|
||||
options.isDeclaredConst = isDeclaredConst;
|
||||
stateVariables.push_back(parseVariableDeclaration(options));
|
||||
isDeclaredConst = false;
|
||||
expectToken(Token::Semicolon);
|
||||
}
|
||||
else if (currentToken == Token::Modifier)
|
||||
modifiers.push_back(parseModifierDefinition());
|
||||
else if (currentToken == Token::Event)
|
||||
events.push_back(parseEventDefinition());
|
||||
else if (currentToken == Token::Const)
|
||||
{
|
||||
solAssert(Token::isElementaryTypeName(m_scanner->peekNextToken()), "");
|
||||
isDeclaredConst = true;
|
||||
m_scanner->next();
|
||||
}
|
||||
else
|
||||
BOOST_THROW_EXCEPTION(createParserError("Function, variable, struct or modifier declaration expected."));
|
||||
}
|
||||
@ -348,7 +357,7 @@ ASTPointer<VariableDeclaration> Parser::parseVariableDeclaration(
|
||||
}
|
||||
return nodeFactory.createNode<VariableDeclaration>(type, identifier, value,
|
||||
visibility, _options.isStateVariable,
|
||||
isIndexed);
|
||||
isIndexed, _options.isDeclaredConst);
|
||||
}
|
||||
|
||||
ASTPointer<ModifierDefinition> Parser::parseModifierDefinition()
|
||||
|
1
Parser.h
1
Parser.h
@ -54,6 +54,7 @@ private:
|
||||
bool allowIndexed = false;
|
||||
bool allowEmptyName = false;
|
||||
bool allowInitialValue = false;
|
||||
bool isDeclaredConst = false;
|
||||
};
|
||||
|
||||
///@{
|
||||
|
2
Types.h
2
Types.h
@ -516,7 +516,7 @@ private:
|
||||
std::vector<std::string> m_parameterNames;
|
||||
std::vector<std::string> m_returnParameterNames;
|
||||
Location const m_location;
|
||||
/// true iff the function takes an arbitrary number of arguments of arbitrary types
|
||||
/// true if the function takes an arbitrary number of arguments of arbitrary types
|
||||
bool const m_arbitraryParameters = false;
|
||||
bool const m_gasSet = false; ///< true iff the gas value to be used is on the stack
|
||||
bool const m_valueSet = false; ///< true iff the value to be sent is on the stack
|
||||
|
Loading…
Reference in New Issue
Block a user