1 //===-- ConvertType.cpp ---------------------------------------------------===//
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 #include "flang/Lower/ConvertType.h"
10 #include "flang/Lower/PFTBuilder.h"
11 #include "flang/Lower/Utils.h"
12 #include "flang/Optimizer/Dialect/FIRType.h"
13 #include "flang/Semantics/tools.h"
14 #include "flang/Semantics/type.h"
15 #include "mlir/IR/Builders.h"
16 #include "mlir/IR/BuiltinTypes.h"
17
18 #undef QUOTE
19 #undef TODO
20 #define QUOTE(X) #X
21 #define TODO(S) \
22 { \
23 emitError(__FILE__ ":" QUOTE(__LINE__) ": type lowering of " S \
24 " not implemented"); \
25 exit(1); \
26 }
27
28 template <typename A>
isConstant(const Fortran::evaluate::Expr<A> & e)29 bool isConstant(const Fortran::evaluate::Expr<A> &e) {
30 return Fortran::evaluate::IsConstantExpr(Fortran::lower::SomeExpr{e});
31 }
32
33 template <typename A>
toConstant(const Fortran::evaluate::Expr<A> & e)34 int64_t toConstant(const Fortran::evaluate::Expr<A> &e) {
35 auto opt = Fortran::evaluate::ToInt64(e);
36 assert(opt.has_value() && "expression didn't resolve to a constant");
37 return opt.value();
38 }
39
40 // one argument template, must be specialized
41 template <Fortran::common::TypeCategory TC>
genFIRType(mlir::MLIRContext *,int)42 mlir::Type genFIRType(mlir::MLIRContext *, int) {
43 return {};
44 }
45
46 // two argument template
47 template <Fortran::common::TypeCategory TC, int KIND>
genFIRType(mlir::MLIRContext * context)48 mlir::Type genFIRType(mlir::MLIRContext *context) {
49 if constexpr (TC == Fortran::common::TypeCategory::Integer) {
50 auto bits{Fortran::evaluate::Type<Fortran::common::TypeCategory::Integer,
51 KIND>::Scalar::bits};
52 return mlir::IntegerType::get(bits, context);
53 } else if constexpr (TC == Fortran::common::TypeCategory::Logical ||
54 TC == Fortran::common::TypeCategory::Character ||
55 TC == Fortran::common::TypeCategory::Complex) {
56 return genFIRType<TC>(context, KIND);
57 } else {
58 return {};
59 }
60 }
61
62 template <>
63 mlir::Type
genFIRType(mlir::MLIRContext * context)64 genFIRType<Fortran::common::TypeCategory::Real, 2>(mlir::MLIRContext *context) {
65 return mlir::FloatType::getF16(context);
66 }
67
68 template <>
69 mlir::Type
genFIRType(mlir::MLIRContext * context)70 genFIRType<Fortran::common::TypeCategory::Real, 3>(mlir::MLIRContext *context) {
71 return mlir::FloatType::getBF16(context);
72 }
73
74 template <>
75 mlir::Type
genFIRType(mlir::MLIRContext * context)76 genFIRType<Fortran::common::TypeCategory::Real, 4>(mlir::MLIRContext *context) {
77 return mlir::FloatType::getF32(context);
78 }
79
80 template <>
81 mlir::Type
genFIRType(mlir::MLIRContext * context)82 genFIRType<Fortran::common::TypeCategory::Real, 8>(mlir::MLIRContext *context) {
83 return mlir::FloatType::getF64(context);
84 }
85
86 template <>
genFIRType(mlir::MLIRContext * context)87 mlir::Type genFIRType<Fortran::common::TypeCategory::Real, 10>(
88 mlir::MLIRContext *context) {
89 return fir::RealType::get(context, 10);
90 }
91
92 template <>
genFIRType(mlir::MLIRContext * context)93 mlir::Type genFIRType<Fortran::common::TypeCategory::Real, 16>(
94 mlir::MLIRContext *context) {
95 return fir::RealType::get(context, 16);
96 }
97
98 template <>
99 mlir::Type
genFIRType(mlir::MLIRContext * context,int kind)100 genFIRType<Fortran::common::TypeCategory::Real>(mlir::MLIRContext *context,
101 int kind) {
102 if (Fortran::evaluate::IsValidKindOfIntrinsicType(
103 Fortran::common::TypeCategory::Real, kind)) {
104 switch (kind) {
105 case 2:
106 return genFIRType<Fortran::common::TypeCategory::Real, 2>(context);
107 case 3:
108 return genFIRType<Fortran::common::TypeCategory::Real, 3>(context);
109 case 4:
110 return genFIRType<Fortran::common::TypeCategory::Real, 4>(context);
111 case 8:
112 return genFIRType<Fortran::common::TypeCategory::Real, 8>(context);
113 case 10:
114 return genFIRType<Fortran::common::TypeCategory::Real, 10>(context);
115 case 16:
116 return genFIRType<Fortran::common::TypeCategory::Real, 16>(context);
117 }
118 }
119 llvm_unreachable("REAL type translation not implemented");
120 }
121
122 template <>
123 mlir::Type
genFIRType(mlir::MLIRContext * context,int kind)124 genFIRType<Fortran::common::TypeCategory::Integer>(mlir::MLIRContext *context,
125 int kind) {
126 if (Fortran::evaluate::IsValidKindOfIntrinsicType(
127 Fortran::common::TypeCategory::Integer, kind)) {
128 switch (kind) {
129 case 1:
130 return genFIRType<Fortran::common::TypeCategory::Integer, 1>(context);
131 case 2:
132 return genFIRType<Fortran::common::TypeCategory::Integer, 2>(context);
133 case 4:
134 return genFIRType<Fortran::common::TypeCategory::Integer, 4>(context);
135 case 8:
136 return genFIRType<Fortran::common::TypeCategory::Integer, 8>(context);
137 case 16:
138 return genFIRType<Fortran::common::TypeCategory::Integer, 16>(context);
139 }
140 }
141 llvm_unreachable("INTEGER type translation not implemented");
142 }
143
144 template <>
145 mlir::Type
genFIRType(mlir::MLIRContext * context,int KIND)146 genFIRType<Fortran::common::TypeCategory::Logical>(mlir::MLIRContext *context,
147 int KIND) {
148 if (Fortran::evaluate::IsValidKindOfIntrinsicType(
149 Fortran::common::TypeCategory::Logical, KIND))
150 return fir::LogicalType::get(context, KIND);
151 return {};
152 }
153
154 template <>
155 mlir::Type
genFIRType(mlir::MLIRContext * context,int KIND)156 genFIRType<Fortran::common::TypeCategory::Character>(mlir::MLIRContext *context,
157 int KIND) {
158 if (Fortran::evaluate::IsValidKindOfIntrinsicType(
159 Fortran::common::TypeCategory::Character, KIND))
160 return fir::CharacterType::get(context, KIND);
161 return {};
162 }
163
164 template <>
165 mlir::Type
genFIRType(mlir::MLIRContext * context,int KIND)166 genFIRType<Fortran::common::TypeCategory::Complex>(mlir::MLIRContext *context,
167 int KIND) {
168 if (Fortran::evaluate::IsValidKindOfIntrinsicType(
169 Fortran::common::TypeCategory::Complex, KIND))
170 return fir::CplxType::get(context, KIND);
171 return {};
172 }
173
174 namespace {
175
176 /// Discover the type of an Fortran::evaluate::Expr<T> and convert it to an
177 /// mlir::Type. The type returned may be an MLIR standard or FIR type.
178 class TypeBuilder {
179 public:
180 /// Constructor.
TypeBuilder(mlir::MLIRContext * context,const Fortran::common::IntrinsicTypeDefaultKinds & defaults)181 explicit TypeBuilder(
182 mlir::MLIRContext *context,
183 const Fortran::common::IntrinsicTypeDefaultKinds &defaults)
184 : context{context}, defaults{defaults} {}
185
186 //===--------------------------------------------------------------------===//
187 // Generate type entry points
188 //===--------------------------------------------------------------------===//
189
190 template <template <typename> typename A, Fortran::common::TypeCategory TC>
gen(const A<Fortran::evaluate::SomeKind<TC>> &)191 mlir::Type gen(const A<Fortran::evaluate::SomeKind<TC>> &) {
192 return genFIRType<TC>(context, defaultKind<TC>());
193 }
194
195 template <template <typename> typename A, Fortran::common::TypeCategory TC,
196 int KIND>
gen(const A<Fortran::evaluate::Type<TC,KIND>> &)197 mlir::Type gen(const A<Fortran::evaluate::Type<TC, KIND>> &) {
198 return genFIRType<TC, KIND>(context);
199 }
200
201 // breaks the conflict between A<Type<TC,KIND>> and Expr<B> deduction
202 template <Fortran::common::TypeCategory TC, int KIND>
203 mlir::Type
gen(const Fortran::evaluate::Expr<Fortran::evaluate::Type<TC,KIND>> &)204 gen(const Fortran::evaluate::Expr<Fortran::evaluate::Type<TC, KIND>> &) {
205 return genFIRType<TC, KIND>(context);
206 }
207
208 // breaks the conflict between A<SomeKind<TC>> and Expr<B> deduction
209 template <Fortran::common::TypeCategory TC>
210 mlir::Type
gen(const Fortran::evaluate::Expr<Fortran::evaluate::SomeKind<TC>> & expr)211 gen(const Fortran::evaluate::Expr<Fortran::evaluate::SomeKind<TC>> &expr) {
212 return genVariant(expr);
213 }
214
215 template <typename A>
gen(const Fortran::evaluate::Expr<A> & expr)216 mlir::Type gen(const Fortran::evaluate::Expr<A> &expr) {
217 return genVariant(expr);
218 }
219
gen(const Fortran::evaluate::DataRef & dref)220 mlir::Type gen(const Fortran::evaluate::DataRef &dref) {
221 return genVariant(dref);
222 }
223
gen(const Fortran::lower::pft::Variable & var)224 mlir::Type gen(const Fortran::lower::pft::Variable &var) {
225 return genSymbolHelper(var.getSymbol(), var.isHeapAlloc(), var.isPointer());
226 }
227
228 /// Type consing from a symbol. A symbol's type must be created from the type
229 /// discovered by the front-end at runtime.
gen(Fortran::semantics::SymbolRef symbol)230 mlir::Type gen(Fortran::semantics::SymbolRef symbol) {
231 return genSymbolHelper(symbol);
232 }
233
234 // non-template, category is runtime values, kind is defaulted
genFIRTy(Fortran::common::TypeCategory tc)235 mlir::Type genFIRTy(Fortran::common::TypeCategory tc) {
236 return genFIRTy(tc, defaultKind(tc));
237 }
238
239 // non-template, arguments are runtime values
genFIRTy(Fortran::common::TypeCategory tc,int kind)240 mlir::Type genFIRTy(Fortran::common::TypeCategory tc, int kind) {
241 switch (tc) {
242 case Fortran::common::TypeCategory::Real:
243 return genFIRType<Fortran::common::TypeCategory::Real>(context, kind);
244 case Fortran::common::TypeCategory::Integer:
245 return genFIRType<Fortran::common::TypeCategory::Integer>(context, kind);
246 case Fortran::common::TypeCategory::Complex:
247 return genFIRType<Fortran::common::TypeCategory::Complex>(context, kind);
248 case Fortran::common::TypeCategory::Logical:
249 return genFIRType<Fortran::common::TypeCategory::Logical>(context, kind);
250 case Fortran::common::TypeCategory::Character:
251 return genFIRType<Fortran::common::TypeCategory::Character>(context,
252 kind);
253 default:
254 break;
255 }
256 llvm_unreachable("unhandled type category");
257 }
258
259 private:
260 //===--------------------------------------------------------------------===//
261 // Generate type helpers
262 //===--------------------------------------------------------------------===//
263
gen(const Fortran::evaluate::ImpliedDoIndex &)264 mlir::Type gen(const Fortran::evaluate::ImpliedDoIndex &) {
265 return genFIRType<Fortran::evaluate::ImpliedDoIndex::Result::category>(
266 context, Fortran::evaluate::ImpliedDoIndex::Result::kind);
267 }
268
gen(const Fortran::evaluate::TypeParamInquiry &)269 mlir::Type gen(const Fortran::evaluate::TypeParamInquiry &) {
270 return genFIRType<Fortran::evaluate::TypeParamInquiry::Result::category>(
271 context, Fortran::evaluate::TypeParamInquiry::Result::kind);
272 }
273
274 template <typename A>
gen(const Fortran::evaluate::Relational<A> &)275 mlir::Type gen(const Fortran::evaluate::Relational<A> &) {
276 return genFIRType<Fortran::common::TypeCategory::Logical, 1>(context);
277 }
278
279 // some sequence of `n` bytes
gen(const Fortran::evaluate::StaticDataObject::Pointer & ptr)280 mlir::Type gen(const Fortran::evaluate::StaticDataObject::Pointer &ptr) {
281 mlir::Type byteTy{mlir::IntegerType::get(8, context)};
282 return fir::SequenceType::get(trivialShape(ptr->itemBytes()), byteTy);
283 }
284
gen(const Fortran::evaluate::Substring & ss)285 mlir::Type gen(const Fortran::evaluate::Substring &ss) {
286 return genVariant(ss.GetBaseObject());
287 }
288
gen(const Fortran::evaluate::NullPointer &)289 mlir::Type gen(const Fortran::evaluate::NullPointer &) {
290 return genTypelessPtr();
291 }
gen(const Fortran::evaluate::ProcedureRef &)292 mlir::Type gen(const Fortran::evaluate::ProcedureRef &) {
293 return genTypelessPtr();
294 }
gen(const Fortran::evaluate::ProcedureDesignator &)295 mlir::Type gen(const Fortran::evaluate::ProcedureDesignator &) {
296 return genTypelessPtr();
297 }
gen(const Fortran::evaluate::BOZLiteralConstant &)298 mlir::Type gen(const Fortran::evaluate::BOZLiteralConstant &) {
299 return genTypelessPtr();
300 }
gen(const Fortran::evaluate::ArrayRef &)301 mlir::Type gen(const Fortran::evaluate::ArrayRef &) { TODO("array ref"); }
gen(const Fortran::evaluate::CoarrayRef &)302 mlir::Type gen(const Fortran::evaluate::CoarrayRef &) { TODO("coarray ref"); }
gen(const Fortran::evaluate::Component &)303 mlir::Type gen(const Fortran::evaluate::Component &) { TODO("component"); }
gen(const Fortran::evaluate::ComplexPart &)304 mlir::Type gen(const Fortran::evaluate::ComplexPart &) {
305 TODO("complex part");
306 }
gen(const Fortran::evaluate::DescriptorInquiry &)307 mlir::Type gen(const Fortran::evaluate::DescriptorInquiry &) {
308 TODO("descriptor inquiry");
309 }
gen(const Fortran::evaluate::StructureConstructor &)310 mlir::Type gen(const Fortran::evaluate::StructureConstructor &) {
311 TODO("structure constructor");
312 }
313
genSeqShape(Fortran::semantics::SymbolRef symbol)314 fir::SequenceType::Shape genSeqShape(Fortran::semantics::SymbolRef symbol) {
315 assert(symbol->IsObjectArray() && "unexpected symbol type");
316 fir::SequenceType::Shape bounds;
317 return seqShapeHelper(symbol, bounds);
318 }
319
genSeqShape(Fortran::semantics::SymbolRef symbol,fir::SequenceType::Extent charLen)320 fir::SequenceType::Shape genSeqShape(Fortran::semantics::SymbolRef symbol,
321 fir::SequenceType::Extent charLen) {
322 assert(symbol->IsObjectArray() && "unexpected symbol type");
323 fir::SequenceType::Shape bounds;
324 bounds.push_back(charLen);
325 return seqShapeHelper(symbol, bounds);
326 }
327
genSymbolHelper(const Fortran::semantics::Symbol & symbol,bool isAlloc=false,bool isPtr=false)328 mlir::Type genSymbolHelper(const Fortran::semantics::Symbol &symbol,
329 bool isAlloc = false, bool isPtr = false) {
330 mlir::Type ty;
331 if (auto *type{symbol.GetType()}) {
332 if (auto *tySpec{type->AsIntrinsic()}) {
333 int kind = toConstant(tySpec->kind());
334 switch (tySpec->category()) {
335 case Fortran::common::TypeCategory::Integer:
336 ty =
337 genFIRType<Fortran::common::TypeCategory::Integer>(context, kind);
338 break;
339 case Fortran::common::TypeCategory::Real:
340 ty = genFIRType<Fortran::common::TypeCategory::Real>(context, kind);
341 break;
342 case Fortran::common::TypeCategory::Complex:
343 ty =
344 genFIRType<Fortran::common::TypeCategory::Complex>(context, kind);
345 break;
346 case Fortran::common::TypeCategory::Character:
347 ty = genFIRType<Fortran::common::TypeCategory::Character>(context,
348 kind);
349 break;
350 case Fortran::common::TypeCategory::Logical:
351 ty =
352 genFIRType<Fortran::common::TypeCategory::Logical>(context, kind);
353 break;
354 default:
355 emitError("symbol has unknown intrinsic type");
356 return {};
357 }
358 } else if (auto *tySpec = type->AsDerived()) {
359 std::vector<std::pair<std::string, mlir::Type>> ps;
360 std::vector<std::pair<std::string, mlir::Type>> cs;
361 auto &symbol = tySpec->typeSymbol();
362 // FIXME: don't want to recurse forever here, but this won't happen
363 // since we don't know the components at this time
364 auto rec = fir::RecordType::get(context, toStringRef(symbol.name()));
365 auto &details = symbol.get<Fortran::semantics::DerivedTypeDetails>();
366 for (auto ¶m : details.paramDecls()) {
367 auto &p{*param};
368 ps.push_back(std::pair{p.name().ToString(), gen(p)});
369 }
370 emitError("the front-end returns symbols of derived type that have "
371 "components that are simple names and not symbols, so cannot "
372 "construct the type '" +
373 toStringRef(symbol.name()) + "'");
374 rec.finalize(ps, cs);
375 ty = rec;
376 } else {
377 emitError("symbol's type must have a type spec");
378 return {};
379 }
380 } else {
381 emitError("symbol must have a type");
382 return {};
383 }
384 if (symbol.IsObjectArray()) {
385 if (symbol.GetType()->category() ==
386 Fortran::semantics::DeclTypeSpec::Character) {
387 auto charLen = fir::SequenceType::getUnknownExtent();
388 const auto &lenParam = symbol.GetType()->characterTypeSpec().length();
389 if (auto expr = lenParam.GetExplicit()) {
390 auto len = Fortran::evaluate::AsGenericExpr(std::move(*expr));
391 auto asInt = Fortran::evaluate::ToInt64(len);
392 if (asInt)
393 charLen = *asInt;
394 }
395 return fir::SequenceType::get(genSeqShape(symbol, charLen), ty);
396 }
397 return fir::SequenceType::get(genSeqShape(symbol), ty);
398 }
399 if (isPtr || Fortran::semantics::IsPointer(symbol))
400 ty = fir::PointerType::get(ty);
401 else if (isAlloc || Fortran::semantics::IsAllocatable(symbol))
402 ty = fir::HeapType::get(ty);
403 return ty;
404 }
405
406 //===--------------------------------------------------------------------===//
407 // Other helper functions
408 //===--------------------------------------------------------------------===//
409
trivialShape(int size)410 fir::SequenceType::Shape trivialShape(int size) {
411 fir::SequenceType::Shape bounds;
412 bounds.emplace_back(size);
413 return bounds;
414 }
415
mkVoid()416 mlir::Type mkVoid() { return mlir::TupleType::get(context); }
genTypelessPtr()417 mlir::Type genTypelessPtr() { return fir::ReferenceType::get(mkVoid()); }
418
419 template <typename A>
genVariant(const A & variant)420 mlir::Type genVariant(const A &variant) {
421 return std::visit([&](const auto &x) { return gen(x); }, variant.u);
422 }
423
424 template <Fortran::common::TypeCategory TC>
defaultKind()425 int defaultKind() {
426 return defaultKind(TC);
427 }
defaultKind(Fortran::common::TypeCategory TC)428 int defaultKind(Fortran::common::TypeCategory TC) {
429 return defaults.GetDefaultKind(TC);
430 }
431
seqShapeHelper(Fortran::semantics::SymbolRef symbol,fir::SequenceType::Shape & bounds)432 fir::SequenceType::Shape seqShapeHelper(Fortran::semantics::SymbolRef symbol,
433 fir::SequenceType::Shape &bounds) {
434 auto &details = symbol->get<Fortran::semantics::ObjectEntityDetails>();
435 const auto size = details.shape().size();
436 for (auto &ss : details.shape()) {
437 auto lb = ss.lbound();
438 auto ub = ss.ubound();
439 if (lb.isAssumed() && ub.isAssumed() && size == 1)
440 return {};
441 if (lb.isExplicit() && ub.isExplicit()) {
442 auto &lbv = lb.GetExplicit();
443 auto &ubv = ub.GetExplicit();
444 if (lbv.has_value() && ubv.has_value() && isConstant(lbv.value()) &&
445 isConstant(ubv.value())) {
446 bounds.emplace_back(toConstant(ubv.value()) -
447 toConstant(lbv.value()) + 1);
448 } else {
449 bounds.emplace_back(fir::SequenceType::getUnknownExtent());
450 }
451 } else {
452 bounds.emplace_back(fir::SequenceType::getUnknownExtent());
453 }
454 }
455 return bounds;
456 }
457
458 //===--------------------------------------------------------------------===//
459 // Emit errors and warnings.
460 //===--------------------------------------------------------------------===//
461
emitError(const llvm::Twine & message)462 mlir::InFlightDiagnostic emitError(const llvm::Twine &message) {
463 return mlir::emitError(mlir::UnknownLoc::get(context), message);
464 }
465
emitWarning(const llvm::Twine & message)466 mlir::InFlightDiagnostic emitWarning(const llvm::Twine &message) {
467 return mlir::emitWarning(mlir::UnknownLoc::get(context), message);
468 }
469
470 //===--------------------------------------------------------------------===//
471
472 mlir::MLIRContext *context;
473 const Fortran::common::IntrinsicTypeDefaultKinds &defaults;
474 };
475
476 } // namespace
477
getFIRType(mlir::MLIRContext * context,const Fortran::common::IntrinsicTypeDefaultKinds & defaults,Fortran::common::TypeCategory tc,int kind)478 mlir::Type Fortran::lower::getFIRType(
479 mlir::MLIRContext *context,
480 const Fortran::common::IntrinsicTypeDefaultKinds &defaults,
481 Fortran::common::TypeCategory tc, int kind) {
482 return TypeBuilder{context, defaults}.genFIRTy(tc, kind);
483 }
484
getFIRType(mlir::MLIRContext * context,const Fortran::common::IntrinsicTypeDefaultKinds & defaults,Fortran::common::TypeCategory tc)485 mlir::Type Fortran::lower::getFIRType(
486 mlir::MLIRContext *context,
487 const Fortran::common::IntrinsicTypeDefaultKinds &defaults,
488 Fortran::common::TypeCategory tc) {
489 return TypeBuilder{context, defaults}.genFIRTy(tc);
490 }
491
translateDataRefToFIRType(mlir::MLIRContext * context,const Fortran::common::IntrinsicTypeDefaultKinds & defaults,const Fortran::evaluate::DataRef & dataRef)492 mlir::Type Fortran::lower::translateDataRefToFIRType(
493 mlir::MLIRContext *context,
494 const Fortran::common::IntrinsicTypeDefaultKinds &defaults,
495 const Fortran::evaluate::DataRef &dataRef) {
496 return TypeBuilder{context, defaults}.gen(dataRef);
497 }
498
translateSomeExprToFIRType(mlir::MLIRContext * context,const Fortran::common::IntrinsicTypeDefaultKinds & defaults,const SomeExpr * expr)499 mlir::Type Fortran::lower::translateSomeExprToFIRType(
500 mlir::MLIRContext *context,
501 const Fortran::common::IntrinsicTypeDefaultKinds &defaults,
502 const SomeExpr *expr) {
503 return TypeBuilder{context, defaults}.gen(*expr);
504 }
505
translateSymbolToFIRType(mlir::MLIRContext * context,const Fortran::common::IntrinsicTypeDefaultKinds & defaults,const SymbolRef symbol)506 mlir::Type Fortran::lower::translateSymbolToFIRType(
507 mlir::MLIRContext *context,
508 const Fortran::common::IntrinsicTypeDefaultKinds &defaults,
509 const SymbolRef symbol) {
510 return TypeBuilder{context, defaults}.gen(symbol);
511 }
512
translateVariableToFIRType(mlir::MLIRContext * context,const Fortran::common::IntrinsicTypeDefaultKinds & defaults,const Fortran::lower::pft::Variable & var)513 mlir::Type Fortran::lower::translateVariableToFIRType(
514 mlir::MLIRContext *context,
515 const Fortran::common::IntrinsicTypeDefaultKinds &defaults,
516 const Fortran::lower::pft::Variable &var) {
517 return TypeBuilder{context, defaults}.gen(var);
518 }
519
convertReal(mlir::MLIRContext * context,int kind)520 mlir::Type Fortran::lower::convertReal(mlir::MLIRContext *context, int kind) {
521 return genFIRType<Fortran::common::TypeCategory::Real>(context, kind);
522 }
523
getSequenceRefType(mlir::Type refType)524 mlir::Type Fortran::lower::getSequenceRefType(mlir::Type refType) {
525 auto type{refType.dyn_cast<fir::ReferenceType>()};
526 assert(type && "expected a reference type");
527 auto elementType{type.getEleTy()};
528 fir::SequenceType::Shape shape{fir::SequenceType::getUnknownExtent()};
529 return fir::ReferenceType::get(fir::SequenceType::get(shape, elementType));
530 }
531