Extract referencedDeclaration as helper.

This commit is contained in:
chriseth 2021-03-24 16:14:58 +01:00
parent 13d3b35141
commit 99fcf62736
6 changed files with 28 additions and 30 deletions

View File

@ -44,6 +44,18 @@ ASTNode::ASTNode(int64_t _id, SourceLocation _location):
{ {
} }
Declaration const* ASTNode::referencedDeclaration(Expression const& _expression)
{
if (auto const* memberAccess = dynamic_cast<MemberAccess const*>(&_expression))
return memberAccess->annotation().referencedDeclaration;
else if (auto const* identifierPath = dynamic_cast<IdentifierPath const*>(&_expression))
return identifierPath->annotation().referencedDeclaration;
else if (auto const* identifier = dynamic_cast<Identifier const*>(&_expression))
return identifier->annotation().referencedDeclaration;
else
return nullptr;
}
ASTAnnotation& ASTNode::annotation() const ASTAnnotation& ASTNode::annotation() const
{ {
if (!m_annotation) if (!m_annotation)

View File

@ -112,6 +112,10 @@ public:
template <class T> template <class T>
static std::vector<T const*> filteredNodes(std::vector<ASTPointer<ASTNode>> const& _nodes); static std::vector<T const*> filteredNodes(std::vector<ASTPointer<ASTNode>> const& _nodes);
/// Extracts the referenced declaration from all nodes whose annotations support
/// `referencedDeclaration`.
static Declaration const* referencedDeclaration(Expression const& _expression);
/// Returns the source code location of this node. /// Returns the source code location of this node.
SourceLocation const& location() const { return m_location; } SourceLocation const& location() const { return m_location; }

View File

@ -28,26 +28,21 @@ bool isConstantVariableRecursive(VariableDeclaration const& _varDecl)
{ {
solAssert(_varDecl.isConstant(), "Constant variable expected"); solAssert(_varDecl.isConstant(), "Constant variable expected");
auto referencedDeclaration = [&](Expression const* _e) -> VariableDeclaration const* auto visitor = [](VariableDeclaration const& _variable, util::CycleDetector<VariableDeclaration>& _cycleDetector, size_t _depth)
{
if (auto identifier = dynamic_cast<Identifier const*>(_e))
return dynamic_cast<VariableDeclaration const*>(identifier->annotation().referencedDeclaration);
else if (auto memberAccess = dynamic_cast<MemberAccess const*>(_e))
return dynamic_cast<VariableDeclaration const*>(memberAccess->annotation().referencedDeclaration);
return nullptr;
};
auto visitor = [&](VariableDeclaration const& _variable, util::CycleDetector<VariableDeclaration>& _cycleDetector, size_t _depth)
{ {
solAssert(_depth < 256, "Recursion depth limit reached"); solAssert(_depth < 256, "Recursion depth limit reached");
if (!_variable.value())
if (auto referencedVarDecl = referencedDeclaration(_variable.value().get())) // This should result in an error later on.
if (referencedVarDecl->isConstant())
if (_cycleDetector.run(*referencedVarDecl))
return; return;
if (auto referencedVarDecl = dynamic_cast<VariableDeclaration const*>(
ASTNode::referencedDeclaration(*_variable.value()))
)
if (referencedVarDecl->isConstant())
_cycleDetector.run(*referencedVarDecl);
}; };
return util::CycleDetector<VariableDeclaration>(visitor).run(_varDecl); return util::CycleDetector<VariableDeclaration>(visitor).run(_varDecl) != nullptr;
} }
VariableDeclaration const* rootConstVariableDeclaration(VariableDeclaration const& _varDecl) VariableDeclaration const* rootConstVariableDeclaration(VariableDeclaration const& _varDecl)

View File

@ -122,13 +122,3 @@ string IRNames::zeroValue(Type const& _type, string const& _variableName)
{ {
return "zero_" + _type.identifier() + _variableName; return "zero_" + _type.identifier() + _variableName;
} }
FunctionDefinition const* IRHelpers::referencedFunctionDeclaration(Expression const& _expression)
{
if (auto memberAccess = dynamic_cast<MemberAccess const*>(&_expression))
return dynamic_cast<FunctionDefinition const*>(memberAccess->annotation().referencedDeclaration);
else if (auto identifier = dynamic_cast<Identifier const*>(&_expression))
return dynamic_cast<FunctionDefinition const*>(identifier->annotation().referencedDeclaration);
else
return nullptr;
}

View File

@ -66,11 +66,6 @@ struct IRNames
static std::string zeroValue(Type const& _type, std::string const& _variableName); static std::string zeroValue(Type const& _type, std::string const& _variableName);
}; };
struct IRHelpers
{
static FunctionDefinition const* referencedFunctionDeclaration(Expression const& _expression);
};
} }
// Overloading std::less() makes it possible to use YulArity as a map key. We could define operator< // Overloading std::less() makes it possible to use YulArity as a map key. We could define operator<

View File

@ -903,7 +903,9 @@ void IRGeneratorForStatements::endVisit(FunctionCall const& _functionCall)
case FunctionType::Kind::Internal: case FunctionType::Kind::Internal:
{ {
auto identifier = dynamic_cast<Identifier const*>(&_functionCall.expression()); auto identifier = dynamic_cast<Identifier const*>(&_functionCall.expression());
FunctionDefinition const* functionDef = IRHelpers::referencedFunctionDeclaration(_functionCall.expression()); auto const* functionDef = dynamic_cast<FunctionDefinition const*>(
ASTNode::referencedDeclaration(_functionCall.expression())
);
if (functionDef) if (functionDef)
{ {