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