| //===-- Lower/ConvertType.h -- lowering of types ----------------*- C++ -*-===// |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/ |
| // |
| //===----------------------------------------------------------------------===// |
| /// |
| /// Conversion of front-end TYPE, KIND, ATTRIBUTE (TKA) information to FIR/MLIR. |
| /// This is meant to be the single point of truth (SPOT) for all type |
| /// conversions when lowering to FIR. This implements all lowering of parse |
| /// tree TKA to the FIR type system. If one is converting front-end types and |
| /// not using one of the routines provided here, it's being done wrong. |
| /// |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef FORTRAN_LOWER_CONVERT_TYPE_H |
| #define FORTRAN_LOWER_CONVERT_TYPE_H |
| |
| #include "flang/Common/Fortran.h" |
| #include "flang/Evaluate/type.h" |
| #include "mlir/IR/BuiltinTypes.h" |
| |
| namespace mlir { |
| class Location; |
| class MLIRContext; |
| class Type; |
| } // namespace mlir |
| |
| namespace Fortran { |
| namespace common { |
| template <typename> |
| class Reference; |
| } // namespace common |
| |
| namespace evaluate { |
| template <typename> |
| class Expr; |
| template <typename> |
| class FunctionRef; |
| struct SomeType; |
| } // namespace evaluate |
| |
| namespace semantics { |
| class Symbol; |
| class DerivedTypeSpec; |
| class DerivedTypeDetails; |
| class Scope; |
| } // namespace semantics |
| |
| namespace lower { |
| class AbstractConverter; |
| namespace pft { |
| struct Variable; |
| } |
| |
| using SomeExpr = evaluate::Expr<evaluate::SomeType>; |
| using SymbolRef = common::Reference<const semantics::Symbol>; |
| |
| // Type for compile time constant length type parameters. |
| using LenParameterTy = std::int64_t; |
| |
| /// Get a FIR type based on a category and kind. |
| mlir::Type getFIRType(mlir::MLIRContext *ctxt, common::TypeCategory tc, |
| int kind, llvm::ArrayRef<LenParameterTy>); |
| |
| /// Get a FIR type for a derived type |
| mlir::Type |
| translateDerivedTypeToFIRType(Fortran::lower::AbstractConverter &, |
| const Fortran::semantics::DerivedTypeSpec &); |
| |
| /// Translate a SomeExpr to an mlir::Type. |
| mlir::Type translateSomeExprToFIRType(Fortran::lower::AbstractConverter &, |
| const SomeExpr &expr); |
| |
| /// Translate a Fortran::semantics::Symbol to an mlir::Type. |
| mlir::Type translateSymbolToFIRType(Fortran::lower::AbstractConverter &, |
| const SymbolRef symbol); |
| |
| /// Translate a Fortran::lower::pft::Variable to an mlir::Type. |
| mlir::Type translateVariableToFIRType(Fortran::lower::AbstractConverter &, |
| const pft::Variable &variable); |
| |
| /// Translate a REAL of KIND to the mlir::Type. |
| mlir::Type convertReal(mlir::MLIRContext *ctxt, int KIND); |
| |
| bool isDerivedTypeWithLenParameters(const semantics::Symbol &); |
| |
| template <typename T> |
| class TypeBuilder { |
| public: |
| static mlir::Type genType(Fortran::lower::AbstractConverter &, |
| const Fortran::evaluate::FunctionRef<T> &); |
| }; |
| using namespace evaluate; |
| FOR_EACH_SPECIFIC_TYPE(extern template class TypeBuilder, ) |
| |
| /// A helper class to reverse iterate through the component names of a derived |
| /// type, including the parent component and the component of the parents. This |
| /// is useful to deal with StructureConstructor lowering. |
| class ComponentReverseIterator { |
| public: |
| ComponentReverseIterator(const Fortran::semantics::DerivedTypeSpec &derived) { |
| setCurrentType(derived); |
| } |
| /// Does the current type has a component with \name (does not look-up the |
| /// components of the parent if any)? If there is a match, the iterator |
| /// is advanced to the search result. |
| bool lookup(const Fortran::parser::CharBlock &name) { |
| componentIt = std::find(componentIt, componentItEnd, name); |
| return componentIt != componentItEnd; |
| }; |
| |
| /// Advance iterator to the last components of the current type parent. |
| const Fortran::semantics::DerivedTypeSpec &advanceToParentType(); |
| |
| private: |
| void setCurrentType(const Fortran::semantics::DerivedTypeSpec &derived); |
| const Fortran::semantics::DerivedTypeSpec *currentParentType = nullptr; |
| const Fortran::semantics::DerivedTypeDetails *currentTypeDetails = nullptr; |
| using name_iterator = |
| std::list<Fortran::parser::CharBlock>::const_reverse_iterator; |
| name_iterator componentIt{}; |
| name_iterator componentItEnd{}; |
| }; |
| } // namespace lower |
| } // namespace Fortran |
| |
| #endif // FORTRAN_LOWER_CONVERT_TYPE_H |