1 //===-- Lower/ConvertType.h -- lowering of types ----------------*- 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 // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ 10 // 11 //===----------------------------------------------------------------------===// 12 /// 13 /// Conversion of front-end TYPE, KIND, ATTRIBUTE (TKA) information to FIR/MLIR. 14 /// This is meant to be the single point of truth (SPOT) for all type 15 /// conversions when lowering to FIR. This implements all lowering of parse 16 /// tree TKA to the FIR type system. If one is converting front-end types and 17 /// not using one of the routines provided here, it's being done wrong. 18 /// 19 //===----------------------------------------------------------------------===// 20 21 #ifndef FORTRAN_LOWER_CONVERT_TYPE_H 22 #define FORTRAN_LOWER_CONVERT_TYPE_H 23 24 #include "flang/Common/Fortran.h" 25 #include "flang/Evaluate/type.h" 26 #include "mlir/IR/BuiltinTypes.h" 27 28 namespace mlir { 29 class Location; 30 class MLIRContext; 31 class Type; 32 } // namespace mlir 33 34 namespace Fortran { 35 namespace common { 36 template <typename> 37 class Reference; 38 } // namespace common 39 40 namespace evaluate { 41 template <typename> 42 class Expr; 43 template <typename> 44 class FunctionRef; 45 struct SomeType; 46 } // namespace evaluate 47 48 namespace semantics { 49 class Symbol; 50 class DerivedTypeSpec; 51 class DerivedTypeDetails; 52 class Scope; 53 } // namespace semantics 54 55 namespace lower { 56 class AbstractConverter; 57 namespace pft { 58 struct Variable; 59 } 60 61 using SomeExpr = evaluate::Expr<evaluate::SomeType>; 62 using SymbolRef = common::Reference<const semantics::Symbol>; 63 64 // Type for compile time constant length type parameters. 65 using LenParameterTy = std::int64_t; 66 67 /// Get a FIR type based on a category and kind. 68 mlir::Type getFIRType(mlir::MLIRContext *ctxt, common::TypeCategory tc, 69 int kind, llvm::ArrayRef<LenParameterTy>); 70 71 /// Get a FIR type for a derived type 72 mlir::Type 73 translateDerivedTypeToFIRType(Fortran::lower::AbstractConverter &, 74 const Fortran::semantics::DerivedTypeSpec &); 75 76 /// Translate a SomeExpr to an mlir::Type. 77 mlir::Type translateSomeExprToFIRType(Fortran::lower::AbstractConverter &, 78 const SomeExpr &expr); 79 80 /// Translate a Fortran::semantics::Symbol to an mlir::Type. 81 mlir::Type translateSymbolToFIRType(Fortran::lower::AbstractConverter &, 82 const SymbolRef symbol); 83 84 /// Translate a Fortran::lower::pft::Variable to an mlir::Type. 85 mlir::Type translateVariableToFIRType(Fortran::lower::AbstractConverter &, 86 const pft::Variable &variable); 87 88 /// Translate a REAL of KIND to the mlir::Type. 89 mlir::Type convertReal(mlir::MLIRContext *ctxt, int KIND); 90 91 bool isDerivedTypeWithLenParameters(const semantics::Symbol &); 92 93 template <typename T> 94 class TypeBuilder { 95 public: 96 static mlir::Type genType(Fortran::lower::AbstractConverter &, 97 const Fortran::evaluate::FunctionRef<T> &); 98 }; 99 using namespace evaluate; 100 FOR_EACH_SPECIFIC_TYPE(extern template class TypeBuilder, ) 101 102 /// A helper class to reverse iterate through the component names of a derived 103 /// type, including the parent component and the component of the parents. This 104 /// is useful to deal with StructureConstructor lowering. 105 class ComponentReverseIterator { 106 public: ComponentReverseIterator(const Fortran::semantics::DerivedTypeSpec & derived)107 ComponentReverseIterator(const Fortran::semantics::DerivedTypeSpec &derived) { 108 setCurrentType(derived); 109 } 110 /// Does the current type has a component with \name (does not look-up the 111 /// components of the parent if any)? If there is a match, the iterator 112 /// is advanced to the search result. lookup(const Fortran::parser::CharBlock & name)113 bool lookup(const Fortran::parser::CharBlock &name) { 114 componentIt = std::find(componentIt, componentItEnd, name); 115 return componentIt != componentItEnd; 116 }; 117 118 /// Advance iterator to the last components of the current type parent. 119 const Fortran::semantics::DerivedTypeSpec &advanceToParentType(); 120 121 private: 122 void setCurrentType(const Fortran::semantics::DerivedTypeSpec &derived); 123 const Fortran::semantics::DerivedTypeSpec *currentParentType = nullptr; 124 const Fortran::semantics::DerivedTypeDetails *currentTypeDetails = nullptr; 125 using name_iterator = 126 std::list<Fortran::parser::CharBlock>::const_reverse_iterator; 127 name_iterator componentIt{}; 128 name_iterator componentItEnd{}; 129 }; 130 } // namespace lower 131 } // namespace Fortran 132 133 #endif // FORTRAN_LOWER_CONVERT_TYPE_H 134