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 {
18   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 
24   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, 2> modules;
34   llvm::Optional<std::string> host;
35   std::string name;
36   llvm::SmallVector<std::int64_t, 4> kinds;
37 };
38 
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 
49 TEST(InternalNamesTest, doBlockDataTest) {
50   NameUniquer obj;
51   std::string actual = obj.doBlockData("blockdatatest");
52   std::string actualBlank = obj.doBlockData("");
53   std::string expectedMangledName = "_QLblockdatatest";
54   std::string expectedMangledNameBlank = "_QL";
55   ASSERT_EQ(actual, expectedMangledName);
56   ASSERT_EQ(actualBlank, expectedMangledNameBlank);
57 }
58 
59 TEST(InternalNamesTest, doCommonBlockTest) {
60   NameUniquer obj;
61   std::string actual = obj.doCommonBlock("hello");
62   std::string actualBlank = obj.doCommonBlock("");
63   std::string expectedMangledName = "_QBhello";
64   std::string expectedMangledNameBlank = "_QB";
65   ASSERT_EQ(actual, expectedMangledName);
66   ASSERT_EQ(actualBlank, expectedMangledNameBlank);
67 }
68 
69 TEST(InternalNamesTest, doGeneratedTest) {
70   NameUniquer obj;
71   std::string actual = obj.doGenerated("@MAIN");
72   std::string expectedMangledName = "_QQ@MAIN";
73   ASSERT_EQ(actual, expectedMangledName);
74 
75   std::string actual1 = obj.doGenerated("@_ZNSt8ios_base4InitC1Ev");
76   std::string expectedMangledName1 = "_QQ@_ZNSt8ios_base4InitC1Ev";
77   ASSERT_EQ(actual1, expectedMangledName1);
78 
79   std::string actual2 = obj.doGenerated("_QQ@MAIN");
80   std::string expectedMangledName2 = "_QQ_QQ@MAIN";
81   ASSERT_EQ(actual2, expectedMangledName2);
82 }
83 
84 TEST(InternalNamesTest, doConstantTest) {
85   NameUniquer obj;
86   std::string actual = obj.doConstant({"mod1", "mod2"}, {"foo"}, "Hello");
87   std::string expectedMangledName = "_QMmod1Smod2FfooEChello";
88   ASSERT_EQ(actual, expectedMangledName);
89 }
90 
91 TEST(InternalNamesTest, doProcedureTest) {
92   NameUniquer obj;
93   std::string actual = obj.doProcedure({"mod1", "mod2"}, {}, "HeLLo");
94   std::string expectedMangledName = "_QMmod1Smod2Phello";
95   ASSERT_EQ(actual, expectedMangledName);
96 }
97 
98 TEST(InternalNamesTest, doTypeTest) {
99   NameUniquer obj;
100   std::string actual = obj.doType({}, {}, "mytype", {4, -1});
101   std::string expectedMangledName = "_QTmytypeK4KN1";
102   ASSERT_EQ(actual, expectedMangledName);
103 }
104 
105 TEST(InternalNamesTest, doIntrinsicTypeDescriptorTest) {
106   using IntrinsicType = fir::NameUniquer::IntrinsicType;
107   NameUniquer obj;
108   std::string actual =
109       obj.doIntrinsicTypeDescriptor({}, {}, IntrinsicType::REAL, 42);
110   std::string expectedMangledName = "_QCrealK42";
111   ASSERT_EQ(actual, expectedMangledName);
112 
113   actual = obj.doIntrinsicTypeDescriptor({}, {}, IntrinsicType::REAL, {});
114   expectedMangledName = "_QCrealK0";
115   ASSERT_EQ(actual, expectedMangledName);
116 
117   actual = obj.doIntrinsicTypeDescriptor({}, {}, IntrinsicType::INTEGER, 3);
118   expectedMangledName = "_QCintegerK3";
119   ASSERT_EQ(actual, expectedMangledName);
120 
121   actual = obj.doIntrinsicTypeDescriptor({}, {}, IntrinsicType::LOGICAL, 2);
122   expectedMangledName = "_QClogicalK2";
123   ASSERT_EQ(actual, expectedMangledName);
124 
125   actual = obj.doIntrinsicTypeDescriptor({}, {}, IntrinsicType::CHARACTER, 4);
126   expectedMangledName = "_QCcharacterK4";
127   ASSERT_EQ(actual, expectedMangledName);
128 
129   actual = obj.doIntrinsicTypeDescriptor({}, {}, IntrinsicType::COMPLEX, 4);
130   expectedMangledName = "_QCcomplexK4";
131   ASSERT_EQ(actual, expectedMangledName);
132 }
133 
134 TEST(InternalNamesTest, doDispatchTableTest) {
135   NameUniquer obj;
136   std::string actual = obj.doDispatchTable({}, {}, "MyTYPE", {2, 8, 18});
137   std::string expectedMangledName = "_QDTmytypeK2K8K18";
138   ASSERT_EQ(actual, expectedMangledName);
139 }
140 
141 TEST(InternalNamesTest, doTypeDescriptorTest) {
142   NameUniquer obj;
143   std::string actual = obj.doTypeDescriptor(
144       {StringRef("moD1")}, {StringRef("foo")}, "MyTYPE", {2, 8});
145   std::string expectedMangledName = "_QMmod1FfooCTmytypeK2K8";
146   ASSERT_EQ(actual, expectedMangledName);
147 }
148 
149 TEST(InternalNamesTest, doVariableTest) {
150   NameUniquer obj;
151   std::string actual = obj.doVariable(
152       {"mod1", "mod2"}, {""}, "intvar"); // Function is present and is blank.
153   std::string expectedMangledName = "_QMmod1Smod2FEintvar";
154   ASSERT_EQ(actual, expectedMangledName);
155 
156   std::string actual2 = obj.doVariable(
157       {"mod1", "mod2"}, {}, "intVariable"); // Function is not present.
158   std::string expectedMangledName2 = "_QMmod1Smod2Eintvariable";
159   ASSERT_EQ(actual2, expectedMangledName2);
160 }
161 
162 TEST(InternalNamesTest, doProgramEntry) {
163   NameUniquer obj;
164   llvm::StringRef actual = obj.doProgramEntry();
165   std::string expectedMangledName = "_QQmain";
166   ASSERT_EQ(actual.str(), expectedMangledName);
167 }
168 
169 TEST(InternalNamesTest, deconstructTest) {
170   NameUniquer obj;
171   std::pair actual = obj.deconstruct("_QBhello");
172   auto expectedNameKind = NameUniquer::NameKind::COMMON;
173   struct DeconstructedName expectedComponents {
174     {}, {}, "hello", {}
175   };
176   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
177 }
178 
179 TEST(InternalNamesTest, complexdeconstructTest) {
180   using NameKind = fir::NameUniquer::NameKind;
181   NameUniquer obj;
182   std::pair actual = obj.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 = obj.deconstruct("_QPsub");
189   expectedNameKind = NameKind::PROCEDURE;
190   expectedComponents = {{}, {}, "sub", {}};
191   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
192 
193   actual = obj.deconstruct("_QBvariables");
194   expectedNameKind = NameKind::COMMON;
195   expectedComponents = {{}, {}, "variables", {}};
196   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
197 
198   actual = obj.deconstruct("_QMmodEintvar");
199   expectedNameKind = NameKind::VARIABLE;
200   expectedComponents = {{"mod"}, {}, "intvar", {}};
201   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
202 
203   actual = obj.deconstruct("_QMmodECpi");
204   expectedNameKind = NameKind::CONSTANT;
205   expectedComponents = {{"mod"}, {}, "pi", {}};
206   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
207 
208   actual = obj.deconstruct("_QTyourtypeK4KN6");
209   expectedNameKind = NameKind::DERIVED_TYPE;
210   expectedComponents = {{}, {}, "yourtype", {4, -6}};
211   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
212 
213   actual = obj.deconstruct("_QDTt");
214   expectedNameKind = NameKind::DISPATCH_TABLE;
215   expectedComponents = {{}, {}, "t", {}};
216   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
217 }
218 
219 // main() from gtest_main
220