Mark expressions that are called directly in the annotations

This commit is contained in:
Mathias Baumann 2020-11-24 12:27:55 +01:00
parent f9f9f6251d
commit c3da529a18
2 changed files with 18 additions and 1 deletions

View File

@ -2303,11 +2303,19 @@ bool TypeChecker::visit(FunctionCall const& _functionCall)
functionType = dynamic_cast<FunctionType const*>(expressionType); functionType = dynamic_cast<FunctionType const*>(expressionType);
funcCallAnno.kind = FunctionCallKind::FunctionCall; funcCallAnno.kind = FunctionCallKind::FunctionCall;
if (auto memberAccess = dynamic_cast<MemberAccess const*>(&_functionCall.expression()))
{
if (dynamic_cast<FunctionDefinition const*>(memberAccess->annotation().referencedDeclaration))
_functionCall.expression().annotation().calledDirectly = true;
}
else if (auto identifier = dynamic_cast<Identifier const*>(&_functionCall.expression()))
if (dynamic_cast<FunctionDefinition const*>(identifier->annotation().referencedDeclaration))
_functionCall.expression().annotation().calledDirectly = true;
// Purity for function calls also depends upon the callee and its FunctionType // Purity for function calls also depends upon the callee and its FunctionType
funcCallAnno.isPure = funcCallAnno.isPure =
argumentsArePure && argumentsArePure &&
*_functionCall.expression().annotation().isPure && *_functionCall.expression().annotation().isPure &&
functionType &&
functionType->isPure(); functionType->isPure();
if ( if (

View File

@ -260,6 +260,15 @@ struct ExpressionAnnotation: ASTAnnotation
/// Types and - if given - names of arguments if the expr. is a function /// Types and - if given - names of arguments if the expr. is a function
/// that is called, used for overload resolution /// that is called, used for overload resolution
std::optional<FuncCallArguments> arguments; std::optional<FuncCallArguments> arguments;
/// True if the expression consists solely of the name of the function and the function is called immediately
/// instead of being stored or processed. The name may be qualified with the name of a contract, library
/// module, etc., that clarifies the scope. For example: `m.L.f()`, where `m` is a module, `L` is a library
/// and `f` is a function is a direct call. This means that the function to be called is known at compilation
/// time and it's not necessary to rely on any runtime dispatch mechanism to resolve it.
/// Note that even the simplest expressions, like `(f)()`, result in an indirect call even if they consist of
/// values known at compilation time.
bool calledDirectly = false;
}; };
struct IdentifierAnnotation: ExpressionAnnotation struct IdentifierAnnotation: ExpressionAnnotation