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