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