1//===- FortranVariableTest.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 "gtest/gtest.h"
10#include "flang/Optimizer/Dialect/FIROps.h"
11#include "flang/Optimizer/Support/InitFIR.h"
12
13struct FortranVariableTest : public testing::Test {
14public:
15 void SetUp() {
16 fir::support::loadDialects(context);
17 builder = std::make_unique<mlir::OpBuilder>(&context);
18 mlir::Location loc = builder->getUnknownLoc();
19
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();
27 mod.push_back(mod);
28 builder->setInsertionPointToStart(entryBlock);
29 }
30
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));
36 }
37
38 mlir::Value createShape(llvm::ArrayRef<mlir::Value> extents) {
39 return builder->create<fir::ShapeOp>(getLoc(), extents);
40 }
41 mlir::MLIRContext context;
42 std::unique_ptr<mlir::OpBuilder> builder;
43};
44
45TEST_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{},
53 /*cuda_attr=*/fir::CUDADataAttributeAttr{});
54
55 fir::FortranVariableOpInterface fortranVariable = declare;
56 EXPECT_FALSE(fortranVariable.isArray());
57 EXPECT_FALSE(fortranVariable.isCharacter());
58 EXPECT_FALSE(fortranVariable.isPointer());
59 EXPECT_FALSE(fortranVariable.isAllocatable());
60 EXPECT_FALSE(fortranVariable.hasExplicitCharLen());
61 EXPECT_EQ(fortranVariable.getElementType(), eleType);
62 EXPECT_EQ(fortranVariable.getElementOrSequenceType(),
63 fortranVariable.getElementType());
64 EXPECT_NE(fortranVariable.getBase(), addr);
65 EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
66}
67
68TEST_F(FortranVariableTest, CharacterScalar) {
69 mlir::Location loc = getLoc();
70 mlir::Type eleType = fir::CharacterType::getUnknownLen(&context, 4);
71 mlir::Value len = createConstant(42);
72 llvm::SmallVector<mlir::Value> typeParams{len};
73 mlir::Value addr = builder->create<fir::AllocaOp>(
74 loc, eleType, /*pinned=*/false, typeParams);
75 auto name = mlir::StringAttr::get(&context, "x");
76 auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
77 /*shape=*/mlir::Value{}, typeParams, name,
78 /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},
79 /*cuda_attr=*/fir::CUDADataAttributeAttr{});
80
81 fir::FortranVariableOpInterface fortranVariable = declare;
82 EXPECT_FALSE(fortranVariable.isArray());
83 EXPECT_TRUE(fortranVariable.isCharacter());
84 EXPECT_FALSE(fortranVariable.isPointer());
85 EXPECT_FALSE(fortranVariable.isAllocatable());
86 EXPECT_TRUE(fortranVariable.hasExplicitCharLen());
87 EXPECT_EQ(fortranVariable.getElementType(), eleType);
88 EXPECT_EQ(fortranVariable.getElementOrSequenceType(),
89 fortranVariable.getElementType());
90 EXPECT_NE(fortranVariable.getBase(), addr);
91 EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
92 EXPECT_EQ(fortranVariable.getExplicitCharLen(), len);
93}
94
95TEST_F(FortranVariableTest, SimpleArray) {
96 mlir::Location loc = getLoc();
97 mlir::Type eleType = mlir::FloatType::getF32(&context);
98 llvm::SmallVector<mlir::Value> extents{
99 createConstant(10), createConstant(20), createConstant(30)};
100 fir::SequenceType::Shape typeShape(
101 extents.size(), fir::SequenceType::getUnknownExtent());
102 mlir::Type seqTy = fir::SequenceType::get(typeShape, eleType);
103 mlir::Value addr = builder->create<fir::AllocaOp>(
104 loc, seqTy, /*pinned=*/false, /*typeParams=*/std::nullopt, extents);
105 mlir::Value shape = createShape(extents);
106 auto name = mlir::StringAttr::get(&context, "x");
107 auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
108 shape, /*typeParams*/ std::nullopt, name,
109 /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},
110 /*cuda_attr=*/fir::CUDADataAttributeAttr{});
111
112 fir::FortranVariableOpInterface fortranVariable = declare;
113 EXPECT_TRUE(fortranVariable.isArray());
114 EXPECT_FALSE(fortranVariable.isCharacter());
115 EXPECT_FALSE(fortranVariable.isPointer());
116 EXPECT_FALSE(fortranVariable.isAllocatable());
117 EXPECT_FALSE(fortranVariable.hasExplicitCharLen());
118 EXPECT_EQ(fortranVariable.getElementType(), eleType);
119 EXPECT_EQ(fortranVariable.getElementOrSequenceType(), seqTy);
120 EXPECT_NE(fortranVariable.getBase(), addr);
121 EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
122}
123
124TEST_F(FortranVariableTest, CharacterArray) {
125 mlir::Location loc = getLoc();
126 mlir::Type eleType = fir::CharacterType::getUnknownLen(&context, 4);
127 mlir::Value len = createConstant(42);
128 llvm::SmallVector<mlir::Value> typeParams{len};
129 llvm::SmallVector<mlir::Value> extents{
130 createConstant(10), createConstant(20), createConstant(30)};
131 fir::SequenceType::Shape typeShape(
132 extents.size(), fir::SequenceType::getUnknownExtent());
133 mlir::Type seqTy = fir::SequenceType::get(typeShape, eleType);
134 mlir::Value addr = builder->create<fir::AllocaOp>(
135 loc, seqTy, /*pinned=*/false, typeParams, extents);
136 mlir::Value shape = createShape(extents);
137 auto name = mlir::StringAttr::get(&context, "x");
138 auto declare = builder->create<fir::DeclareOp>(loc, addr.getType(), addr,
139 shape, typeParams, name,
140 /*fortran_attrs=*/fir::FortranVariableFlagsAttr{},
141 /*cuda_attr=*/fir::CUDADataAttributeAttr{});
142
143 fir::FortranVariableOpInterface fortranVariable = declare;
144 EXPECT_TRUE(fortranVariable.isArray());
145 EXPECT_TRUE(fortranVariable.isCharacter());
146 EXPECT_FALSE(fortranVariable.isPointer());
147 EXPECT_FALSE(fortranVariable.isAllocatable());
148 EXPECT_TRUE(fortranVariable.hasExplicitCharLen());
149 EXPECT_EQ(fortranVariable.getElementType(), eleType);
150 EXPECT_EQ(fortranVariable.getElementOrSequenceType(), seqTy);
151 EXPECT_NE(fortranVariable.getBase(), addr);
152 EXPECT_EQ(fortranVariable.getBase().getType(), addr.getType());
153 EXPECT_EQ(fortranVariable.getExplicitCharLen(), len);
154}
155

source code of flang/unittests/Optimizer/FortranVariableTest.cpp