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