xref: /llvm-project/flang/include/flang/Lower/ComponentPath.h (revision 91682b2631b224a9f6dca9512b5e0951cc4a7762)
1 //===-- ComponentPath.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_LOWER_COMPONENTPATH_H
10 #define FORTRAN_LOWER_COMPONENTPATH_H
11 
12 #include "flang/Lower/IterationSpace.h"
13 #include "llvm/ADT/SmallVector.h"
14 #include <optional>
15 
16 namespace fir {
17 class ArrayLoadOp;
18 }
19 namespace Fortran::evaluate {
20 class ArrayRef;
21 }
22 
23 namespace Fortran::lower {
24 
25 namespace details {
26 class ImplicitSubscripts {};
27 } // namespace details
28 
29 using PathComponent =
30     std::variant<const evaluate::ArrayRef *, const evaluate::Component *,
31                  const evaluate::ComplexPart *, details::ImplicitSubscripts>;
32 
33 /// Collection of components.
34 ///
35 /// This class is used both to collect front-end post-order functional Expr
36 /// trees and their translations to Values to be used in a pre-order list of
37 /// arguments.
38 class ComponentPath {
39 public:
40   using ExtendRefFunc = std::function<mlir::Value(const mlir::Value &)>;
41 
ComponentPath(bool isImplicit)42   ComponentPath(bool isImplicit) { setPC(isImplicit); }
ComponentPath(bool isImplicit,const evaluate::Substring * ss)43   ComponentPath(bool isImplicit, const evaluate::Substring *ss)
44       : substring(ss) {
45     setPC(isImplicit);
46   }
47   ComponentPath() = delete;
48 
isSlice()49   bool isSlice() const { return !trips.empty() || hasComponents(); }
hasComponents()50   bool hasComponents() const { return !suffixComponents.empty(); }
51   void clear();
52 
hasExtendCoorRef()53   bool hasExtendCoorRef() const { return extendCoorRef.has_value(); }
54   ExtendRefFunc getExtendCoorRef() const;
resetExtendCoorRef()55   void resetExtendCoorRef() { extendCoorRef = std::nullopt; }
56   void resetPC();
57 
58   llvm::SmallVector<PathComponent> reversePath;
59   const evaluate::Substring *substring = nullptr;
60   bool applied = false;
61 
62   llvm::SmallVector<mlir::Value> prefixComponents;
63   llvm::SmallVector<mlir::Value> trips;
64   llvm::SmallVector<mlir::Value> suffixComponents;
65   std::function<IterationSpace(const IterationSpace &)> pc;
66 
67   /// In the case where a path of components involves members that are POINTER
68   /// or ALLOCATABLE, a dereference is required in FIR for semantic correctness.
69   /// This optional continuation allows the generation of those dereferences.
70   /// These accesses are always on Fortran entities of record types, which are
71   /// implicitly in-memory objects.
72   std::optional<ExtendRefFunc> extendCoorRef;
73 
74 private:
75   void setPC(bool isImplicit);
76 };
77 
78 /// Examine each subscript expression of \p x and return true if and only if any
79 /// of the subscripts is a vector or has a rank greater than 0.
80 bool isRankedArrayAccess(const Fortran::evaluate::ArrayRef &x);
81 
82 } // namespace Fortran::lower
83 
84 #endif // FORTRAN_LOWER_COMPONENTPATH_H
85