FLANG
check-expression.h
1//===-- include/flang/Evaluate/check-expression.h ---------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// Static expression checking
10
11#ifndef FORTRAN_EVALUATE_CHECK_EXPRESSION_H_
12#define FORTRAN_EVALUATE_CHECK_EXPRESSION_H_
13
14#include "expression.h"
15#include "intrinsics.h"
16#include "type.h"
17#include <optional>
18
19namespace Fortran::parser {
21}
22namespace Fortran::semantics {
23class Scope;
24}
25
26namespace Fortran::evaluate {
27
28// Predicate: true when an expression is a constant expression (in the
29// strict sense of the Fortran standard); it may not (yet) be a hard
30// constant value.
31template <typename A> bool IsConstantExpr(const A &);
32extern template bool IsConstantExpr(const Expr<SomeType> &);
33extern template bool IsConstantExpr(const Expr<SomeInteger> &);
34extern template bool IsConstantExpr(const Expr<SubscriptInteger> &);
35extern template bool IsConstantExpr(const StructureConstructor &);
36
37// Predicate: true when an expression is a constant expression (in the
38// strict sense of the Fortran standard) or a dummy argument with
39// INTENT(IN) and no VALUE. This is useful for representing explicit
40// shapes of other dummy arguments.
41template <typename A> bool IsScopeInvariantExpr(const A &);
42extern template bool IsScopeInvariantExpr(const Expr<SomeType> &);
43extern template bool IsScopeInvariantExpr(const Expr<SomeInteger> &);
44extern template bool IsScopeInvariantExpr(const Expr<SubscriptInteger> &);
45
46// Predicate: true when an expression actually is a typed Constant<T>,
47// perhaps with parentheses and wrapping around it. False for all typeless
48// expressions, including BOZ literals.
49template <typename A> bool IsActuallyConstant(const A &);
50extern template bool IsActuallyConstant(const Expr<SomeType> &);
51extern template bool IsActuallyConstant(const Expr<SomeInteger> &);
52extern template bool IsActuallyConstant(const Expr<SubscriptInteger> &);
53extern template bool IsActuallyConstant(
54 const std::optional<Expr<SubscriptInteger>> &);
55
56// Checks whether an expression is an object designator with
57// constant addressing and no vector-valued subscript.
58// If a non-null ContextualMessages pointer is passed, an error message
59// will be generated if and only if the result of the function is false.
60bool IsInitialDataTarget(
61 const Expr<SomeType> &, parser::ContextualMessages * = nullptr);
62
63bool IsInitialProcedureTarget(const Symbol &);
64bool IsInitialProcedureTarget(const ProcedureDesignator &);
65bool IsInitialProcedureTarget(const Expr<SomeType> &);
66
67// Validate the value of a named constant, the static initial
68// value of a non-pointer non-allocatable non-dummy variable, or the
69// default initializer of a component of a derived type (or instantiation
70// of a derived type). Converts type and expands scalars as necessary.
71std::optional<Expr<SomeType>> NonPointerInitializationExpr(const Symbol &,
72 Expr<SomeType> &&, FoldingContext &,
73 const semantics::Scope *instantiation = nullptr);
74
75// Check whether an expression is a specification expression
76// (10.1.11(2), C1010). Constant expressions are always valid
77// specification expressions.
78
79template <typename A>
80void CheckSpecificationExpr(const A &, const semantics::Scope &,
81 FoldingContext &, bool forElementalFunctionResult);
82extern template void CheckSpecificationExpr(const Expr<SomeType> &x,
83 const semantics::Scope &, FoldingContext &,
84 bool forElementalFunctionResult);
85extern template void CheckSpecificationExpr(const Expr<SomeInteger> &x,
86 const semantics::Scope &, FoldingContext &,
87 bool forElementalFunctionResult);
88extern template void CheckSpecificationExpr(const Expr<SubscriptInteger> &x,
89 const semantics::Scope &, FoldingContext &,
90 bool forElementalFunctionResult);
91extern template void CheckSpecificationExpr(
92 const std::optional<Expr<SomeType>> &x, const semantics::Scope &,
93 FoldingContext &, bool forElementalFunctionResult);
94extern template void CheckSpecificationExpr(
95 const std::optional<Expr<SomeInteger>> &x, const semantics::Scope &,
96 FoldingContext &, bool forElementalFunctionResult);
97extern template void CheckSpecificationExpr(
98 const std::optional<Expr<SubscriptInteger>> &x, const semantics::Scope &,
99 FoldingContext &, bool forElementalFunctionResult);
100
101// Contiguity & "simple contiguity" (9.5.4)
102template <typename A>
103std::optional<bool> IsContiguous(const A &, FoldingContext &);
104extern template std::optional<bool> IsContiguous(
105 const Expr<SomeType> &, FoldingContext &);
106extern template std::optional<bool> IsContiguous(
107 const ArrayRef &, FoldingContext &);
108extern template std::optional<bool> IsContiguous(
109 const Substring &, FoldingContext &);
110extern template std::optional<bool> IsContiguous(
111 const Component &, FoldingContext &);
112extern template std::optional<bool> IsContiguous(
113 const ComplexPart &, FoldingContext &);
114extern template std::optional<bool> IsContiguous(
115 const CoarrayRef &, FoldingContext &);
116extern template std::optional<bool> IsContiguous(
117 const Symbol &, FoldingContext &);
118static inline std::optional<bool> IsContiguous(
119 const SymbolRef &s, FoldingContext &c) {
120 return IsContiguous(s.get(), c);
121}
122template <typename A>
123bool IsSimplyContiguous(const A &x, FoldingContext &context) {
124 return IsContiguous(x, context).value_or(false);
125}
126
127template <typename A> bool IsErrorExpr(const A &);
128extern template bool IsErrorExpr(const Expr<SomeType> &);
129
130std::optional<parser::Message> CheckStatementFunction(
131 const Symbol &, const Expr<SomeType> &, FoldingContext &);
132
133} // namespace Fortran::evaluate
134#endif
Definition: message.h:363
Definition: call.h:34
Definition: check-expression.h:19