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