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, 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 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 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 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 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 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 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 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 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 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 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 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