1//===- InternalNamesTest.cpp -- InternalNames unit tests ------------------===//
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 "flang/Optimizer/Support/InternalNames.h"
10#include "gtest/gtest.h"
11#include <optional>
12#include <string>
13
14using namespace fir;
15using llvm::SmallVector;
16
17struct DeconstructedName {
18 DeconstructedName(llvm::StringRef name) : name{name} {}
19 DeconstructedName(llvm::ArrayRef<std::string> modules,
20 llvm::ArrayRef<std::string> procs, std::int64_t blockId,
21 llvm::StringRef name, llvm::ArrayRef<std::int64_t> kinds)
22 : modules{modules.begin(), modules.end()}, procs{procs.begin(),
23 procs.end()},
24 blockId{blockId}, name{name}, kinds{kinds.begin(), kinds.end()} {}
25
26 bool isObjEqual(const NameUniquer::DeconstructedName &actualObj) {
27 return actualObj.modules == modules && actualObj.procs == procs &&
28 actualObj.blockId == blockId && actualObj.name == name &&
29 actualObj.kinds == kinds;
30 }
31
32 llvm::SmallVector<std::string> modules;
33 llvm::SmallVector<std::string> procs;
34 std::int64_t blockId;
35 std::string name;
36 llvm::SmallVector<std::int64_t> kinds;
37};
38
39void validateDeconstructedName(
40 std::pair<NameUniquer::NameKind, NameUniquer::DeconstructedName> &actual,
41 NameUniquer::NameKind &expectedNameKind,
42 struct DeconstructedName &components) {
43 EXPECT_EQ(actual.first, expectedNameKind)
44 << "Possible error: NameKind mismatch";
45 ASSERT_TRUE(components.isObjEqual(actual.second))
46 << "Possible error: DeconstructedName mismatch";
47}
48
49TEST(InternalNamesTest, doCommonBlockTest) {
50 std::string actual = NameUniquer::doCommonBlock("hello");
51 std::string actualBlank = NameUniquer::doCommonBlock("");
52 std::string expectedMangledName = "_QChello";
53 std::string expectedMangledNameBlank = "_QC";
54 ASSERT_EQ(actual, expectedMangledName);
55 ASSERT_EQ(actualBlank, expectedMangledNameBlank);
56}
57
58TEST(InternalNamesTest, doGeneratedTest) {
59 std::string actual = NameUniquer::doGenerated("@MAIN");
60 std::string expectedMangledName = "_QQ@MAIN";
61 ASSERT_EQ(actual, expectedMangledName);
62
63 std::string actual1 = NameUniquer::doGenerated("@_ZNSt8ios_base4InitC1Ev");
64 std::string expectedMangledName1 = "_QQ@_ZNSt8ios_base4InitC1Ev";
65 ASSERT_EQ(actual1, expectedMangledName1);
66
67 std::string actual2 = NameUniquer::doGenerated("_QQ@MAIN");
68 std::string expectedMangledName2 = "_QQ_QQ@MAIN";
69 ASSERT_EQ(actual2, expectedMangledName2);
70}
71
72TEST(InternalNamesTest, doConstantTest) {
73 std::string actual =
74 NameUniquer::doConstant({"mod1", "mod2"}, {"foo"}, 0, "Hello");
75 std::string expectedMangledName = "_QMmod1Smod2FfooEChello";
76 ASSERT_EQ(actual, expectedMangledName);
77}
78
79TEST(InternalNamesTest, doProcedureTest) {
80 std::string actual = NameUniquer::doProcedure({"mod1", "mod2"}, {}, "HeLLo");
81 std::string expectedMangledName = "_QMmod1Smod2Phello";
82 ASSERT_EQ(actual, expectedMangledName);
83}
84
85TEST(InternalNamesTest, doTypeTest) {
86 std::string actual = NameUniquer::doType({}, {}, 0, "mytype", {4, -1});
87 std::string expectedMangledName = "_QTmytypeK4KN1";
88 ASSERT_EQ(actual, expectedMangledName);
89}
90
91TEST(InternalNamesTest, doIntrinsicTypeDescriptorTest) {
92 using IntrinsicType = fir::NameUniquer::IntrinsicType;
93 std::string actual = NameUniquer::doIntrinsicTypeDescriptor(
94 {}, {}, 0, IntrinsicType::REAL, 42);
95 std::string expectedMangledName = "_QYIrealK42";
96 ASSERT_EQ(actual, expectedMangledName);
97
98 actual = NameUniquer::doIntrinsicTypeDescriptor(
99 {}, {}, 0, IntrinsicType::REAL, {});
100 expectedMangledName = "_QYIrealK0";
101 ASSERT_EQ(actual, expectedMangledName);
102
103 actual = NameUniquer::doIntrinsicTypeDescriptor(
104 {}, {}, 0, IntrinsicType::INTEGER, 3);
105 expectedMangledName = "_QYIintegerK3";
106 ASSERT_EQ(actual, expectedMangledName);
107
108 actual = NameUniquer::doIntrinsicTypeDescriptor(
109 {}, {}, 0, IntrinsicType::LOGICAL, 2);
110 expectedMangledName = "_QYIlogicalK2";
111 ASSERT_EQ(actual, expectedMangledName);
112
113 actual = NameUniquer::doIntrinsicTypeDescriptor(
114 {}, {}, 0, IntrinsicType::CHARACTER, 4);
115 expectedMangledName = "_QYIcharacterK4";
116 ASSERT_EQ(actual, expectedMangledName);
117
118 actual = NameUniquer::doIntrinsicTypeDescriptor(
119 {}, {}, 0, IntrinsicType::COMPLEX, 4);
120 expectedMangledName = "_QYIcomplexK4";
121 ASSERT_EQ(actual, expectedMangledName);
122}
123
124TEST(InternalNamesTest, doDispatchTableTest) {
125 std::string actual =
126 NameUniquer::doDispatchTable({}, {}, 0, "MyTYPE", {2, 8, 18});
127 std::string expectedMangledName = "_QDTmytypeK2K8K18";
128 ASSERT_EQ(actual, expectedMangledName);
129}
130
131TEST(InternalNamesTest, doVariableTest) {
132 std::string actual = NameUniquer::doVariable(
133 {"mod1", "mod2"}, {""}, 0, "intvar"); // Function is present and is blank.
134 std::string expectedMangledName = "_QMmod1Smod2FEintvar";
135 ASSERT_EQ(actual, expectedMangledName);
136
137 std::string actual2 = NameUniquer::doVariable(
138 {"mod1", "mod2"}, {}, 0, "intVariable"); // Function is not present.
139 std::string expectedMangledName2 = "_QMmod1Smod2Eintvariable";
140 ASSERT_EQ(actual2, expectedMangledName2);
141}
142
143TEST(InternalNamesTest, doProgramEntry) {
144 llvm::StringRef actual = NameUniquer::doProgramEntry();
145 std::string expectedMangledName = "_QQmain";
146 ASSERT_EQ(actual.str(), expectedMangledName);
147}
148
149TEST(InternalNamesTest, doNamelistGroup) {
150 std::string actual = NameUniquer::doNamelistGroup({"mod1"}, {}, "nlg");
151 std::string expectedMangledName = "_QMmod1Nnlg";
152 ASSERT_EQ(actual, expectedMangledName);
153}
154
155TEST(InternalNamesTest, deconstructTest) {
156 std::pair actual = NameUniquer::deconstruct("_QChello");
157 auto expectedNameKind = NameUniquer::NameKind::COMMON;
158 struct DeconstructedName expectedComponents {
159 {}, {}, 0, "hello", {}
160 };
161 validateDeconstructedName(actual, expectedNameKind, expectedComponents);
162}
163
164TEST(InternalNamesTest, complexdeconstructTest) {
165 using NameKind = fir::NameUniquer::NameKind;
166 std::pair actual = NameUniquer::deconstruct("_QMmodSs1modSs2modFsubPfun");
167 auto expectedNameKind = NameKind::PROCEDURE;
168 struct DeconstructedName expectedComponents = {
169 {"mod", "s1mod", "s2mod"}, {"sub"}, 0, "fun", {}};
170 validateDeconstructedName(actual, expectedNameKind, expectedComponents);
171
172 actual = NameUniquer::deconstruct("_QPsub");
173 expectedNameKind = NameKind::PROCEDURE;
174 expectedComponents = {{}, {}, 0, "sub", {}};
175 validateDeconstructedName(actual, expectedNameKind, expectedComponents);
176
177 actual = NameUniquer::deconstruct("_QCvariables");
178 expectedNameKind = NameKind::COMMON;
179 expectedComponents = {{}, {}, 0, "variables", {}};
180 validateDeconstructedName(actual, expectedNameKind, expectedComponents);
181
182 actual = NameUniquer::deconstruct("_QMmodEintvar");
183 expectedNameKind = NameKind::VARIABLE;
184 expectedComponents = {{"mod"}, {}, 0, "intvar", {}};
185 validateDeconstructedName(actual, expectedNameKind, expectedComponents);
186
187 actual = NameUniquer::deconstruct("_QMmodECpi");
188 expectedNameKind = NameKind::CONSTANT;
189 expectedComponents = {{"mod"}, {}, 0, "pi", {}};
190 validateDeconstructedName(actual, expectedNameKind, expectedComponents);
191
192 actual = NameUniquer::deconstruct("_QTyourtypeK4KN6");
193 expectedNameKind = NameKind::DERIVED_TYPE;
194 expectedComponents = {{}, {}, 0, "yourtype", {4, -6}};
195 validateDeconstructedName(actual, expectedNameKind, expectedComponents);
196
197 actual = NameUniquer::deconstruct("_QDTt");
198 expectedNameKind = NameKind::DISPATCH_TABLE;
199 expectedComponents = {{}, {}, 0, "t", {}};
200 validateDeconstructedName(actual, expectedNameKind, expectedComponents);
201
202 actual = NameUniquer::deconstruct("_QFmstartNmpitop");
203 expectedNameKind = NameKind::NAMELIST_GROUP;
204 expectedComponents = {{}, {"mstart"}, 0, "mpitop", {}};
205 validateDeconstructedName(actual, expectedNameKind, expectedComponents);
206}
207
208TEST(InternalNamesTest, needExternalNameMangling) {
209 ASSERT_FALSE(
210 NameUniquer::needExternalNameMangling("_QMmodSs1modSs2modFsubPfun"));
211 ASSERT_FALSE(NameUniquer::needExternalNameMangling("omp_num_thread"));
212 ASSERT_FALSE(NameUniquer::needExternalNameMangling(""));
213 ASSERT_FALSE(NameUniquer::needExternalNameMangling("_QDTmytypeK2K8K18"));
214 ASSERT_FALSE(NameUniquer::needExternalNameMangling("exit_"));
215 ASSERT_FALSE(NameUniquer::needExternalNameMangling("_QFfooEx"));
216 ASSERT_FALSE(NameUniquer::needExternalNameMangling("_QFmstartNmpitop"));
217 ASSERT_TRUE(NameUniquer::needExternalNameMangling("_QPfoo"));
218 ASSERT_TRUE(NameUniquer::needExternalNameMangling("_QPbar"));
219 ASSERT_TRUE(NameUniquer::needExternalNameMangling("_QCa"));
220}
221
222TEST(InternalNamesTest, isExternalFacingUniquedName) {
223 std::pair result = NameUniquer::deconstruct("_QMmodSs1modSs2modFsubPfun");
224
225 ASSERT_FALSE(NameUniquer::isExternalFacingUniquedName(result));
226 result = NameUniquer::deconstruct("omp_num_thread");
227 ASSERT_FALSE(NameUniquer::isExternalFacingUniquedName(result));
228 result = NameUniquer::deconstruct("");
229 ASSERT_FALSE(NameUniquer::isExternalFacingUniquedName(result));
230 result = NameUniquer::deconstruct("_QDTmytypeK2K8K18");
231 ASSERT_FALSE(NameUniquer::isExternalFacingUniquedName(result));
232 result = NameUniquer::deconstruct("exit_");
233 ASSERT_FALSE(NameUniquer::isExternalFacingUniquedName(result));
234 result = NameUniquer::deconstruct("_QPfoo");
235 ASSERT_TRUE(NameUniquer::isExternalFacingUniquedName(result));
236 result = NameUniquer::deconstruct("_QPbar");
237 ASSERT_TRUE(NameUniquer::isExternalFacingUniquedName(result));
238 result = NameUniquer::deconstruct("_QCa");
239 ASSERT_TRUE(NameUniquer::isExternalFacingUniquedName(result));
240}
241
242TEST(InternalNamesTest, getTypeDescriptorName) {
243 std::string derivedTypeName = "_QMdispatch1Tp1";
244 std::string expectedBindingTableName = "_QMdispatch1E.dt.p1";
245 ASSERT_EQ(expectedBindingTableName,
246 fir::NameUniquer::getTypeDescriptorName(derivedTypeName));
247 ASSERT_EQ("", fir::NameUniquer::getTypeDescriptorName("_QMdispatch1Pp1"));
248}
249
250TEST(InternalNamesTest, getTypeDescriptorBindingTableName) {
251 std::string derivedTypeName = "_QMdispatch1Tp1";
252 std::string expectedBindingTableName = "_QMdispatch1E.v.p1";
253 ASSERT_EQ(expectedBindingTableName,
254 fir::NameUniquer::getTypeDescriptorBindingTableName(derivedTypeName));
255 ASSERT_EQ("",
256 fir::NameUniquer::getTypeDescriptorBindingTableName("_QMdispatch1Pp1"));
257}
258
259// main() from gtest_main
260

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