brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · 925276e Raw
101 lines · cpp
1//===-- FortranVariableInterface.cpp.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-exception6//7//===----------------------------------------------------------------------===//8//9// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/10//11//===----------------------------------------------------------------------===//12 13#include "flang/Optimizer/Dialect/FortranVariableInterface.h"14 15#include "flang/Optimizer/Dialect/FortranVariableInterface.cpp.inc"16 17llvm::LogicalResult18fir::FortranVariableOpInterface::verifyDeclareLikeOpImpl(mlir::Value memref) {19  const unsigned numExplicitTypeParams = getExplicitTypeParams().size();20  mlir::Type memType = memref.getType();21  const bool sourceIsBoxValue = mlir::isa<fir::BaseBoxType>(memType);22  const bool sourceIsBoxAddress = fir::isBoxAddress(memType);23  const bool sourceIsBox = sourceIsBoxValue || sourceIsBoxAddress;24  if (isCharacter()) {25    if (numExplicitTypeParams > 1)26      return emitOpError(27          "of character entity must have at most one length parameter");28    if (numExplicitTypeParams == 0 && !sourceIsBox)29      return emitOpError("must be provided exactly one type parameter when its "30                         "base is a character that is not a box");31 32  } else if (auto recordType =33                 mlir::dyn_cast<fir::RecordType>(getElementType())) {34    if (numExplicitTypeParams < recordType.getNumLenParams() && !sourceIsBox)35      return emitOpError("must be provided all the derived type length "36                         "parameters when the base is not a box");37    if (numExplicitTypeParams > recordType.getNumLenParams())38      return emitOpError("has too many length parameters");39  } else if (numExplicitTypeParams != 0) {40    return emitOpError("of numeric, logical, or assumed type entity must not "41                       "have length parameters");42  }43 44  if (isArray()) {45    if (mlir::Value shape = getShape()) {46      if (sourceIsBoxAddress)47        return emitOpError("for box address must not have a shape operand");48      unsigned shapeRank = 0;49      if (auto shapeType = mlir::dyn_cast<fir::ShapeType>(shape.getType())) {50        shapeRank = shapeType.getRank();51      } else if (auto shapeShiftType =52                     mlir::dyn_cast<fir::ShapeShiftType>(shape.getType())) {53        shapeRank = shapeShiftType.getRank();54      } else {55        if (!sourceIsBoxValue)56          return emitOpError(57              "of array entity with a raw address base must have a "58              "shape operand that is a shape or shapeshift");59        shapeRank = mlir::cast<fir::ShiftType>(shape.getType()).getRank();60      }61 62      std::optional<unsigned> rank = getRank();63      if (!rank || *rank != shapeRank)64        return emitOpError("has conflicting shape and base operand ranks");65    } else if (!sourceIsBox) {66      return emitOpError(67          "of array entity with a raw address base must have a shape "68          "operand that is a shape or shapeshift");69    }70  }71  return mlir::success();72}73 74mlir::LogicalResult75fir::detail::verifyFortranVariableStorageOpInterface(mlir::Operation *op) {76  auto storageIface = mlir::cast<fir::FortranVariableStorageOpInterface>(op);77  mlir::Value storage = storageIface.getStorage();78  std::uint64_t storageOffset = storageIface.getStorageOffset();79  if (!storage) {80    if (storageOffset != 0)81      return op->emitOpError(82          "storage offset specified without the storage reference");83    return mlir::success();84  }85 86  auto storageType =87      mlir::dyn_cast<fir::SequenceType>(fir::unwrapRefType(storage.getType()));88  if (!storageType || storageType.getDimension() != 1)89    return op->emitOpError("storage must be a vector");90  if (storageType.hasDynamicExtents())91    return op->emitOpError("storage must have known extent");92  if (storageType.getEleTy() != mlir::IntegerType::get(op->getContext(), 8))93    return op->emitOpError("storage must be an array of i8 elements");94  if (storageOffset > storageType.getConstantArraySize())95    return op->emitOpError("storage offset exceeds the storage size");96  // TODO: we should probably verify that the (offset + sizeof(var))97  // is within the storage object, but this requires mlir::DataLayout.98  // Can we make it available during the verification?99  return mlir::success();100}101