1 //===- FortranVariableTest.cpp --------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "gtest/gtest.h"
10 #include "flang/Optimizer/Dialect/FIROps.h"
11 #include "flang/Optimizer/Support/InitFIR.h"
13 struct FortranVariableTest
: public testing::Test
{
16 fir::support::loadDialects(context
);
17 builder
= std::make_unique
<mlir::OpBuilder
>(&context
);
18 mlir::Location loc
= builder
->getUnknownLoc();
20 // Set up a Module with a dummy function operation inside.
21 // Set the insertion point in the function entry block.
22 mlir::ModuleOp mod
= builder
->create
<mlir::ModuleOp
>(loc
);
23 mlir::func::FuncOp func
=
24 mlir::func::FuncOp::create(loc
, "fortran_variable_tests",
25 builder
->getFunctionType(std::nullopt
, std::nullopt
));
26 auto *entryBlock
= func
.addEntryBlock();
28 builder
->setInsertionPointToStart(entryBlock
);
31 mlir::Location
getLoc() { return builder
->getUnknownLoc(); }
32 mlir::Value
createConstant(std::int64_t cst
) {
33 mlir::Type indexType
= builder
->getIndexType();
34 return builder
->create
<mlir::arith::ConstantOp
>(
35 getLoc(), indexType
, builder
->getIntegerAttr(indexType
, cst
));
38 mlir::Value
createShape(llvm::ArrayRef
<mlir::Value
> extents
) {
39 return builder
->create
<fir::ShapeOp
>(getLoc(), extents
);
41 mlir::MLIRContext context
;
42 std::unique_ptr
<mlir::OpBuilder
> builder
;
45 TEST_F(FortranVariableTest
, SimpleScalar
) {
46 mlir::Location loc
= getLoc();
47 mlir::Type eleType
= mlir::FloatType::getF32(&context
);
48 mlir::Value addr
= builder
->create
<fir::AllocaOp
>(loc
, eleType
);
49 auto name
= mlir::StringAttr::get(&context
, "x");
50 auto declare
= builder
->create
<fir::DeclareOp
>(loc
, addr
.getType(), addr
,
51 /*shape=*/mlir::Value
{}, /*typeParams=*/std::nullopt
, name
,
52 /*fortran_attrs=*/fir::FortranVariableFlagsAttr
{});
54 fir::FortranVariableOpInterface fortranVariable
= declare
;
55 EXPECT_FALSE(fortranVariable
.isArray());
56 EXPECT_FALSE(fortranVariable
.isCharacter());
57 EXPECT_FALSE(fortranVariable
.isPointer());
58 EXPECT_FALSE(fortranVariable
.isAllocatable());
59 EXPECT_FALSE(fortranVariable
.hasExplicitCharLen());
60 EXPECT_EQ(fortranVariable
.getElementType(), eleType
);
61 EXPECT_EQ(fortranVariable
.getElementOrSequenceType(),
62 fortranVariable
.getElementType());
63 EXPECT_NE(fortranVariable
.getBase(), addr
);
64 EXPECT_EQ(fortranVariable
.getBase().getType(), addr
.getType());
67 TEST_F(FortranVariableTest
, CharacterScalar
) {
68 mlir::Location loc
= getLoc();
69 mlir::Type eleType
= fir::CharacterType::getUnknownLen(&context
, 4);
70 mlir::Value len
= createConstant(42);
71 llvm::SmallVector
<mlir::Value
> typeParams
{len
};
72 mlir::Value addr
= builder
->create
<fir::AllocaOp
>(
73 loc
, eleType
, /*pinned=*/false, typeParams
);
74 auto name
= mlir::StringAttr::get(&context
, "x");
75 auto declare
= builder
->create
<fir::DeclareOp
>(loc
, addr
.getType(), addr
,
76 /*shape=*/mlir::Value
{}, typeParams
, name
,
77 /*fortran_attrs=*/fir::FortranVariableFlagsAttr
{});
79 fir::FortranVariableOpInterface fortranVariable
= declare
;
80 EXPECT_FALSE(fortranVariable
.isArray());
81 EXPECT_TRUE(fortranVariable
.isCharacter());
82 EXPECT_FALSE(fortranVariable
.isPointer());
83 EXPECT_FALSE(fortranVariable
.isAllocatable());
84 EXPECT_TRUE(fortranVariable
.hasExplicitCharLen());
85 EXPECT_EQ(fortranVariable
.getElementType(), eleType
);
86 EXPECT_EQ(fortranVariable
.getElementOrSequenceType(),
87 fortranVariable
.getElementType());
88 EXPECT_NE(fortranVariable
.getBase(), addr
);
89 EXPECT_EQ(fortranVariable
.getBase().getType(), addr
.getType());
90 EXPECT_EQ(fortranVariable
.getExplicitCharLen(), len
);
93 TEST_F(FortranVariableTest
, SimpleArray
) {
94 mlir::Location loc
= getLoc();
95 mlir::Type eleType
= mlir::FloatType::getF32(&context
);
96 llvm::SmallVector
<mlir::Value
> extents
{
97 createConstant(10), createConstant(20), createConstant(30)};
98 fir::SequenceType::Shape
typeShape(
99 extents
.size(), fir::SequenceType::getUnknownExtent());
100 mlir::Type seqTy
= fir::SequenceType::get(typeShape
, eleType
);
101 mlir::Value addr
= builder
->create
<fir::AllocaOp
>(
102 loc
, seqTy
, /*pinned=*/false, /*typeParams=*/std::nullopt
, extents
);
103 mlir::Value shape
= createShape(extents
);
104 auto name
= mlir::StringAttr::get(&context
, "x");
105 auto declare
= builder
->create
<fir::DeclareOp
>(loc
, addr
.getType(), addr
,
106 shape
, /*typeParams*/ std::nullopt
, name
,
107 /*fortran_attrs=*/fir::FortranVariableFlagsAttr
{});
109 fir::FortranVariableOpInterface fortranVariable
= declare
;
110 EXPECT_TRUE(fortranVariable
.isArray());
111 EXPECT_FALSE(fortranVariable
.isCharacter());
112 EXPECT_FALSE(fortranVariable
.isPointer());
113 EXPECT_FALSE(fortranVariable
.isAllocatable());
114 EXPECT_FALSE(fortranVariable
.hasExplicitCharLen());
115 EXPECT_EQ(fortranVariable
.getElementType(), eleType
);
116 EXPECT_EQ(fortranVariable
.getElementOrSequenceType(), seqTy
);
117 EXPECT_NE(fortranVariable
.getBase(), addr
);
118 EXPECT_EQ(fortranVariable
.getBase().getType(), addr
.getType());
121 TEST_F(FortranVariableTest
, CharacterArray
) {
122 mlir::Location loc
= getLoc();
123 mlir::Type eleType
= fir::CharacterType::getUnknownLen(&context
, 4);
124 mlir::Value len
= createConstant(42);
125 llvm::SmallVector
<mlir::Value
> typeParams
{len
};
126 llvm::SmallVector
<mlir::Value
> extents
{
127 createConstant(10), createConstant(20), createConstant(30)};
128 fir::SequenceType::Shape
typeShape(
129 extents
.size(), fir::SequenceType::getUnknownExtent());
130 mlir::Type seqTy
= fir::SequenceType::get(typeShape
, eleType
);
131 mlir::Value addr
= builder
->create
<fir::AllocaOp
>(
132 loc
, seqTy
, /*pinned=*/false, typeParams
, extents
);
133 mlir::Value shape
= createShape(extents
);
134 auto name
= mlir::StringAttr::get(&context
, "x");
135 auto declare
= builder
->create
<fir::DeclareOp
>(loc
, addr
.getType(), addr
,
136 shape
, typeParams
, name
,
137 /*fortran_attrs=*/fir::FortranVariableFlagsAttr
{});
139 fir::FortranVariableOpInterface fortranVariable
= declare
;
140 EXPECT_TRUE(fortranVariable
.isArray());
141 EXPECT_TRUE(fortranVariable
.isCharacter());
142 EXPECT_FALSE(fortranVariable
.isPointer());
143 EXPECT_FALSE(fortranVariable
.isAllocatable());
144 EXPECT_TRUE(fortranVariable
.hasExplicitCharLen());
145 EXPECT_EQ(fortranVariable
.getElementType(), eleType
);
146 EXPECT_EQ(fortranVariable
.getElementOrSequenceType(), seqTy
);
147 EXPECT_NE(fortranVariable
.getBase(), addr
);
148 EXPECT_EQ(fortranVariable
.getBase().getType(), addr
.getType());
149 EXPECT_EQ(fortranVariable
.getExplicitCharLen(), len
);