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