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