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