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   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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
159 TEST(InternalNamesTest, doProgramEntry) {
160   llvm::StringRef actual = NameUniquer::doProgramEntry();
161   std::string expectedMangledName = "_QQmain";
162   ASSERT_EQ(actual.str(), expectedMangledName);
163 }
164 
165 TEST(InternalNamesTest, deconstructTest) {
166   std::pair actual = NameUniquer::deconstruct("_QBhello");
167   auto expectedNameKind = NameUniquer::NameKind::COMMON;
168   struct DeconstructedName expectedComponents {
169     {}, {}, "hello", {}
170   };
171   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
172 }
173 
174 TEST(InternalNamesTest, complexdeconstructTest) {
175   using NameKind = fir::NameUniquer::NameKind;
176   std::pair actual = NameUniquer::deconstruct("_QMmodSs1modSs2modFsubPfun");
177   auto expectedNameKind = NameKind::PROCEDURE;
178   struct DeconstructedName expectedComponents = {
179       {"mod", "s1mod", "s2mod"}, {"sub"}, "fun", {}};
180   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
181 
182   actual = NameUniquer::deconstruct("_QPsub");
183   expectedNameKind = NameKind::PROCEDURE;
184   expectedComponents = {{}, {}, "sub", {}};
185   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
186 
187   actual = NameUniquer::deconstruct("_QBvariables");
188   expectedNameKind = NameKind::COMMON;
189   expectedComponents = {{}, {}, "variables", {}};
190   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
191 
192   actual = NameUniquer::deconstruct("_QMmodEintvar");
193   expectedNameKind = NameKind::VARIABLE;
194   expectedComponents = {{"mod"}, {}, "intvar", {}};
195   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
196 
197   actual = NameUniquer::deconstruct("_QMmodECpi");
198   expectedNameKind = NameKind::CONSTANT;
199   expectedComponents = {{"mod"}, {}, "pi", {}};
200   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
201 
202   actual = NameUniquer::deconstruct("_QTyourtypeK4KN6");
203   expectedNameKind = NameKind::DERIVED_TYPE;
204   expectedComponents = {{}, {}, "yourtype", {4, -6}};
205   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
206 
207   actual = NameUniquer::deconstruct("_QDTt");
208   expectedNameKind = NameKind::DISPATCH_TABLE;
209   expectedComponents = {{}, {}, "t", {}};
210   validateDeconstructedName(actual, expectedNameKind, expectedComponents);
211 }
212 
213 // main() from gtest_main
214