Files
clang-p2996/flang/lib/Optimizer/Dialect/FortranVariableInterface.cpp
Jean Perier 32e7e17d86 [flang] Add hlfir.declare operation
This operation will be used to declare named variables in HLFIR.
See the added description in HLFIROpBase.td for more info about it.

The motivation behind this operation is described in https://reviews.llvm.org/D137634.

The FortranVariableInterface verifier is changed a bit. It used to
operate using the result type to verify the provided shape and length
parameters. This is a bit incorrect because what matters to verify the
information is the input address (This worked OK with fir.declare where
the input memref type is the same as the output result). Also, not all
operation defining variables will have an input memref with the same
meaning (hlfir.designate and hlfir.associate for instance).
Hence, this verifier is now optional and must be provided a memref to
operate.

Differential Revision: https://reviews.llvm.org/D137781
2022-11-14 10:27:12 +01:00

70 lines
3.1 KiB
C++

//===-- FortranVariableInterface.cpp.cpp ----------------------------------===//
//
// 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/
//
//===----------------------------------------------------------------------===//
#include "flang/Optimizer/Dialect/FortranVariableInterface.h"
#include "flang/Optimizer/Dialect/FortranVariableInterface.cpp.inc"
mlir::LogicalResult
fir::FortranVariableOpInterface::verifyDeclareLikeOpImpl(mlir::Value memref) {
const unsigned numExplicitTypeParams = getExplicitTypeParams().size();
mlir::Type memType = memref.getType();
const bool sourceIsBoxValue = memType.isa<fir::BaseBoxType>();
const bool sourceIsBoxAddress = fir::isBoxAddress(memType);
const bool sourceIsBox = sourceIsBoxValue || sourceIsBoxAddress;
if (isCharacter()) {
if (numExplicitTypeParams > 1)
return emitOpError(
"of character entity must have at most one length parameter");
if (numExplicitTypeParams == 0 && !sourceIsBox)
return emitOpError("must be provided exactly one type parameter when its "
"base is a character that is not a box");
} else if (auto recordType = getElementType().dyn_cast<fir::RecordType>()) {
if (numExplicitTypeParams < recordType.getNumLenParams() && !sourceIsBox)
return emitOpError("must be provided all the derived type length "
"parameters when the base is not a box");
if (numExplicitTypeParams > recordType.getNumLenParams())
return emitOpError("has too many length parameters");
} else if (numExplicitTypeParams != 0) {
return emitOpError("of numeric, logical, or assumed type entity must not "
"have length parameters");
}
if (isArray()) {
if (mlir::Value shape = getShape()) {
if (sourceIsBoxAddress)
return emitOpError("for box address must not have a shape operand");
unsigned shapeRank = 0;
if (auto shapeType = shape.getType().dyn_cast<fir::ShapeType>()) {
shapeRank = shapeType.getRank();
} else if (auto shapeShiftType =
shape.getType().dyn_cast<fir::ShapeShiftType>()) {
shapeRank = shapeShiftType.getRank();
} else {
if (!sourceIsBoxValue)
emitOpError("of array entity with a raw address base must have a "
"shape operand that is a shape or shapeshift");
shapeRank = shape.getType().cast<fir::ShiftType>().getRank();
}
llvm::Optional<unsigned> rank = getRank();
if (!rank || *rank != shapeRank)
return emitOpError("has conflicting shape and base operand ranks");
} else if (!sourceIsBox) {
emitOpError("of array entity with a raw address base must have a shape "
"operand that is a shape or shapeshift");
}
}
return mlir::success();
}