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 
19 namespace Fortran::parser {
20 class ContextualMessages;
21 }
22 namespace Fortran::semantics {
23 class Scope;
24 }
25 
26 namespace 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.
31 template <typename A> bool IsConstantExpr(const A &);
32 extern template bool IsConstantExpr(const Expr<SomeType> &);
33 extern template bool IsConstantExpr(const Expr<SomeInteger> &);
34 extern template bool IsConstantExpr(const Expr<SubscriptInteger> &);
35 extern template bool IsConstantExpr(const StructureConstructor &);
36 
37 // Predicate: true when an expression actually is a typed Constant<T>,
38 // perhaps with parentheses and wrapping around it.  False for all typeless
39 // expressions, including BOZ literals.
40 template <typename A> bool IsActuallyConstant(const A &);
41 extern template bool IsActuallyConstant(const Expr<SomeType> &);
42 
43 // Checks whether an expression is an object designator with
44 // constant addressing and no vector-valued subscript.
45 // If a non-null ContextualMessages pointer is passed, an error message
46 // will be generated if and only if the result of the function is false.
47 bool IsInitialDataTarget(
48     const Expr<SomeType> &, parser::ContextualMessages * = nullptr);
49 
50 bool IsInitialProcedureTarget(const Symbol &);
51 bool IsInitialProcedureTarget(const ProcedureDesignator &);
52 bool IsInitialProcedureTarget(const Expr<SomeType> &);
53 
54 // Validate the value of a named constant, the static initial
55 // value of a non-pointer non-allocatable non-dummy variable, or the
56 // default initializer of a component of a derived type (or instantiation
57 // of a derived type).  Converts type and expands scalars as necessary.
58 std::optional<Expr<SomeType>> NonPointerInitializationExpr(const Symbol &,
59     Expr<SomeType> &&, FoldingContext &,
60     const semantics::Scope *instantiation = nullptr);
61 
62 // Check whether an expression is a specification expression
63 // (10.1.11(2), C1010).  Constant expressions are always valid
64 // specification expressions.
65 
66 template <typename A>
67 void CheckSpecificationExpr(
68     const A &, const semantics::Scope &, FoldingContext &);
69 extern template void CheckSpecificationExpr(
70     const Expr<SomeType> &x, const semantics::Scope &, FoldingContext &);
71 extern template void CheckSpecificationExpr(
72     const Expr<SomeInteger> &x, const semantics::Scope &, FoldingContext &);
73 extern template void CheckSpecificationExpr(const Expr<SubscriptInteger> &x,
74     const semantics::Scope &, FoldingContext &);
75 extern template void CheckSpecificationExpr(
76     const std::optional<Expr<SomeType>> &x, const semantics::Scope &,
77     FoldingContext &);
78 extern template void CheckSpecificationExpr(
79     const std::optional<Expr<SomeInteger>> &x, const semantics::Scope &,
80     FoldingContext &);
81 extern template void CheckSpecificationExpr(
82     const std::optional<Expr<SubscriptInteger>> &x, const semantics::Scope &,
83     FoldingContext &);
84 
85 // Simple contiguity (9.5.4)
86 template <typename A> bool IsSimplyContiguous(const A &, FoldingContext &);
87 extern template bool IsSimplyContiguous(
88     const Expr<SomeType> &, FoldingContext &);
89 
90 template <typename A> bool IsErrorExpr(const A &);
91 extern template bool IsErrorExpr(const Expr<SomeType> &);
92 
93 } // namespace Fortran::evaluate
94 #endif
95