xref: /llvm-project/flang/lib/Semantics/definable.h (revision 07b3bba901e7d51b3173631d6af811eae9d84cda)
1 //===-- lib/Semantics/definable.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 #ifndef FORTRAN_SEMANTICS_DEFINABLE_H_
10 #define FORTRAN_SEMANTICS_DEFINABLE_H_
11 
12 // Utilities for checking the definability of variables and pointers in context,
13 // including checks for attempted definitions in PURE subprograms.
14 // Fortran 2018 C1101, C1158, C1594, &c.
15 
16 #include "flang/Common/enum-set.h"
17 #include "flang/Common/idioms.h"
18 #include "flang/Evaluate/expression.h"
19 #include "flang/Parser/char-block.h"
20 #include "flang/Parser/message.h"
21 #include <optional>
22 
23 namespace Fortran::semantics {
24 
25 class Symbol;
26 class Scope;
27 
28 ENUM_CLASS(DefinabilityFlag,
29     VectorSubscriptIsOk, // a vector subscript may appear (i.e., assignment)
30     DuplicatesAreOk, // vector subscript may have duplicates
31     PointerDefinition, // a pointer is being defined, not its target
32     AcceptAllocatable, // treat allocatable as if it were a pointer
33     SourcedAllocation, // ALLOCATE(a,SOURCE=)
34     PolymorphicOkInPure, // don't check for polymorphic type in pure subprogram
35     DoNotNoteDefinition, // context does not imply definition
36     AllowEventLockOrNotifyType)
37 
38 using DefinabilityFlags =
39     common::EnumSet<DefinabilityFlag, DefinabilityFlag_enumSize>;
40 
41 // Tests a symbol or LHS variable or pointer for definability in a given scope.
42 // When the entity is not definable, returns a Message suitable for attachment
43 // to an error or warning message (as a "because: addendum) to explain why the
44 // entity cannot be defined.
45 // When the entity can be defined in that context, returns std::nullopt.
46 std::optional<parser::Message> WhyNotDefinable(
47     parser::CharBlock, const Scope &, DefinabilityFlags, const Symbol &);
48 std::optional<parser::Message> WhyNotDefinable(parser::CharBlock, const Scope &,
49     DefinabilityFlags, const evaluate::Expr<evaluate::SomeType> &);
50 
51 // If a symbol would not be definable in a pure scope, or not be usable as the
52 // target of a pointer assignment in a pure scope, return a constant string
53 // describing why.
54 const char *WhyBaseObjectIsSuspicious(const Symbol &, const Scope &);
55 
56 } // namespace Fortran::semantics
57 #endif // FORTRAN_SEMANTICS_DEFINABLE_H_
58