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> modules; 34 llvm::Optional<std::string> host; 35 std::string name; 36 llvm::SmallVector<std::int64_t> 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, doNamelistGroup) { 166 std::string actual = NameUniquer::doNamelistGroup({"mod1"}, {}, "nlg"); 167 std::string expectedMangledName = "_QMmod1Gnlg"; 168 ASSERT_EQ(actual, expectedMangledName); 169 } 170 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 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 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 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