xref: /llvm-project/flang/include/flang/Lower/ConvertType.h (revision e45f6e93d0b90e917eff61ac104a673c52ee2322)
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