Add the external name conversion pass needed for compiler interoperability. This pass convert the Flang internal symbol name to the common gfortran convention. Clean up old passes without implementation in the Passes.ts file so the project and fir-opt can build correctly. This patch is part of the upstreaming effort from fir-dev branch. Reviewed By: schweitz Differential Revision: https://reviews.llvm.org/D111057
257 lines
9.9 KiB
C++
257 lines
9.9 KiB
C++
//===- InternalNamesTest.cpp -- InternalNames unit tests ------------------===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "flang/Optimizer/Support/InternalNames.h"
|
|
#include "gtest/gtest.h"
|
|
#include <string>
|
|
|
|
using namespace fir;
|
|
using llvm::SmallVector;
|
|
using llvm::StringRef;
|
|
|
|
struct DeconstructedName {
|
|
DeconstructedName(llvm::ArrayRef<std::string> modules,
|
|
llvm::Optional<std::string> host, llvm::StringRef name,
|
|
llvm::ArrayRef<std::int64_t> kinds)
|
|
: modules{modules.begin(), modules.end()}, host{host}, name{name},
|
|
kinds{kinds.begin(), kinds.end()} {}
|
|
|
|
bool isObjEqual(const NameUniquer::DeconstructedName &actualObj) {
|
|
if ((actualObj.name == name) && (actualObj.modules == modules) &&
|
|
(actualObj.host == host) && (actualObj.kinds == kinds)) {
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private:
|
|
llvm::SmallVector<std::string, 2> modules;
|
|
llvm::Optional<std::string> host;
|
|
std::string name;
|
|
llvm::SmallVector<std::int64_t, 4> kinds;
|
|
};
|
|
|
|
void validateDeconstructedName(
|
|
std::pair<NameUniquer::NameKind, NameUniquer::DeconstructedName> &actual,
|
|
NameUniquer::NameKind &expectedNameKind,
|
|
struct DeconstructedName &components) {
|
|
EXPECT_EQ(actual.first, expectedNameKind)
|
|
<< "Possible error: NameKind mismatch";
|
|
ASSERT_TRUE(components.isObjEqual(actual.second))
|
|
<< "Possible error: DeconstructedName mismatch";
|
|
}
|
|
|
|
TEST(InternalNamesTest, doBlockDataTest) {
|
|
std::string actual = NameUniquer::doBlockData("blockdatatest");
|
|
std::string actualBlank = NameUniquer::doBlockData("");
|
|
std::string expectedMangledName = "_QLblockdatatest";
|
|
std::string expectedMangledNameBlank = "_QL";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
ASSERT_EQ(actualBlank, expectedMangledNameBlank);
|
|
}
|
|
|
|
TEST(InternalNamesTest, doCommonBlockTest) {
|
|
std::string actual = NameUniquer::doCommonBlock("hello");
|
|
std::string actualBlank = NameUniquer::doCommonBlock("");
|
|
std::string expectedMangledName = "_QBhello";
|
|
std::string expectedMangledNameBlank = "_QB";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
ASSERT_EQ(actualBlank, expectedMangledNameBlank);
|
|
}
|
|
|
|
TEST(InternalNamesTest, doGeneratedTest) {
|
|
std::string actual = NameUniquer::doGenerated("@MAIN");
|
|
std::string expectedMangledName = "_QQ@MAIN";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
|
|
std::string actual1 = NameUniquer::doGenerated("@_ZNSt8ios_base4InitC1Ev");
|
|
std::string expectedMangledName1 = "_QQ@_ZNSt8ios_base4InitC1Ev";
|
|
ASSERT_EQ(actual1, expectedMangledName1);
|
|
|
|
std::string actual2 = NameUniquer::doGenerated("_QQ@MAIN");
|
|
std::string expectedMangledName2 = "_QQ_QQ@MAIN";
|
|
ASSERT_EQ(actual2, expectedMangledName2);
|
|
}
|
|
|
|
TEST(InternalNamesTest, doConstantTest) {
|
|
std::string actual =
|
|
NameUniquer::doConstant({"mod1", "mod2"}, {"foo"}, "Hello");
|
|
std::string expectedMangledName = "_QMmod1Smod2FfooEChello";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
}
|
|
|
|
TEST(InternalNamesTest, doProcedureTest) {
|
|
std::string actual = NameUniquer::doProcedure({"mod1", "mod2"}, {}, "HeLLo");
|
|
std::string expectedMangledName = "_QMmod1Smod2Phello";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
}
|
|
|
|
TEST(InternalNamesTest, doTypeTest) {
|
|
std::string actual = NameUniquer::doType({}, {}, "mytype", {4, -1});
|
|
std::string expectedMangledName = "_QTmytypeK4KN1";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
}
|
|
|
|
TEST(InternalNamesTest, doIntrinsicTypeDescriptorTest) {
|
|
using IntrinsicType = fir::NameUniquer::IntrinsicType;
|
|
std::string actual =
|
|
NameUniquer::doIntrinsicTypeDescriptor({}, {}, IntrinsicType::REAL, 42);
|
|
std::string expectedMangledName = "_QCrealK42";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
|
|
actual =
|
|
NameUniquer::doIntrinsicTypeDescriptor({}, {}, IntrinsicType::REAL, {});
|
|
expectedMangledName = "_QCrealK0";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
|
|
actual =
|
|
NameUniquer::doIntrinsicTypeDescriptor({}, {}, IntrinsicType::INTEGER, 3);
|
|
expectedMangledName = "_QCintegerK3";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
|
|
actual =
|
|
NameUniquer::doIntrinsicTypeDescriptor({}, {}, IntrinsicType::LOGICAL, 2);
|
|
expectedMangledName = "_QClogicalK2";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
|
|
actual = NameUniquer::doIntrinsicTypeDescriptor(
|
|
{}, {}, IntrinsicType::CHARACTER, 4);
|
|
expectedMangledName = "_QCcharacterK4";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
|
|
actual =
|
|
NameUniquer::doIntrinsicTypeDescriptor({}, {}, IntrinsicType::COMPLEX, 4);
|
|
expectedMangledName = "_QCcomplexK4";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
}
|
|
|
|
TEST(InternalNamesTest, doDispatchTableTest) {
|
|
std::string actual =
|
|
NameUniquer::doDispatchTable({}, {}, "MyTYPE", {2, 8, 18});
|
|
std::string expectedMangledName = "_QDTmytypeK2K8K18";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
}
|
|
|
|
TEST(InternalNamesTest, doTypeDescriptorTest) {
|
|
std::string actual = NameUniquer::doTypeDescriptor(
|
|
{StringRef("moD1")}, {StringRef("foo")}, "MyTYPE", {2, 8});
|
|
std::string expectedMangledName = "_QMmod1FfooCTmytypeK2K8";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
}
|
|
|
|
TEST(InternalNamesTest, doVariableTest) {
|
|
std::string actual = NameUniquer::doVariable(
|
|
{"mod1", "mod2"}, {""}, "intvar"); // Function is present and is blank.
|
|
std::string expectedMangledName = "_QMmod1Smod2FEintvar";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
|
|
std::string actual2 = NameUniquer::doVariable(
|
|
{"mod1", "mod2"}, {}, "intVariable"); // Function is not present.
|
|
std::string expectedMangledName2 = "_QMmod1Smod2Eintvariable";
|
|
ASSERT_EQ(actual2, expectedMangledName2);
|
|
}
|
|
|
|
TEST(InternalNamesTest, doProgramEntry) {
|
|
llvm::StringRef actual = NameUniquer::doProgramEntry();
|
|
std::string expectedMangledName = "_QQmain";
|
|
ASSERT_EQ(actual.str(), expectedMangledName);
|
|
}
|
|
|
|
TEST(InternalNamesTest, doNamelistGroup) {
|
|
std::string actual = NameUniquer::doNamelistGroup({"mod1"}, {}, "nlg");
|
|
std::string expectedMangledName = "_QMmod1Gnlg";
|
|
ASSERT_EQ(actual, expectedMangledName);
|
|
}
|
|
|
|
TEST(InternalNamesTest, deconstructTest) {
|
|
std::pair actual = NameUniquer::deconstruct("_QBhello");
|
|
auto expectedNameKind = NameUniquer::NameKind::COMMON;
|
|
struct DeconstructedName expectedComponents {
|
|
{}, {}, "hello", {}
|
|
};
|
|
validateDeconstructedName(actual, expectedNameKind, expectedComponents);
|
|
}
|
|
|
|
TEST(InternalNamesTest, complexdeconstructTest) {
|
|
using NameKind = fir::NameUniquer::NameKind;
|
|
std::pair actual = NameUniquer::deconstruct("_QMmodSs1modSs2modFsubPfun");
|
|
auto expectedNameKind = NameKind::PROCEDURE;
|
|
struct DeconstructedName expectedComponents = {
|
|
{"mod", "s1mod", "s2mod"}, {"sub"}, "fun", {}};
|
|
validateDeconstructedName(actual, expectedNameKind, expectedComponents);
|
|
|
|
actual = NameUniquer::deconstruct("_QPsub");
|
|
expectedNameKind = NameKind::PROCEDURE;
|
|
expectedComponents = {{}, {}, "sub", {}};
|
|
validateDeconstructedName(actual, expectedNameKind, expectedComponents);
|
|
|
|
actual = NameUniquer::deconstruct("_QBvariables");
|
|
expectedNameKind = NameKind::COMMON;
|
|
expectedComponents = {{}, {}, "variables", {}};
|
|
validateDeconstructedName(actual, expectedNameKind, expectedComponents);
|
|
|
|
actual = NameUniquer::deconstruct("_QMmodEintvar");
|
|
expectedNameKind = NameKind::VARIABLE;
|
|
expectedComponents = {{"mod"}, {}, "intvar", {}};
|
|
validateDeconstructedName(actual, expectedNameKind, expectedComponents);
|
|
|
|
actual = NameUniquer::deconstruct("_QMmodECpi");
|
|
expectedNameKind = NameKind::CONSTANT;
|
|
expectedComponents = {{"mod"}, {}, "pi", {}};
|
|
validateDeconstructedName(actual, expectedNameKind, expectedComponents);
|
|
|
|
actual = NameUniquer::deconstruct("_QTyourtypeK4KN6");
|
|
expectedNameKind = NameKind::DERIVED_TYPE;
|
|
expectedComponents = {{}, {}, "yourtype", {4, -6}};
|
|
validateDeconstructedName(actual, expectedNameKind, expectedComponents);
|
|
|
|
actual = NameUniquer::deconstruct("_QDTt");
|
|
expectedNameKind = NameKind::DISPATCH_TABLE;
|
|
expectedComponents = {{}, {}, "t", {}};
|
|
validateDeconstructedName(actual, expectedNameKind, expectedComponents);
|
|
|
|
actual = NameUniquer::deconstruct("_QFmstartGmpitop");
|
|
expectedNameKind = NameKind::NAMELIST_GROUP;
|
|
expectedComponents = {{}, {"mstart"}, "mpitop", {}};
|
|
validateDeconstructedName(actual, expectedNameKind, expectedComponents);
|
|
}
|
|
|
|
TEST(InternalNamesTest, needExternalNameMangling) {
|
|
ASSERT_FALSE(
|
|
NameUniquer::needExternalNameMangling("_QMmodSs1modSs2modFsubPfun"));
|
|
ASSERT_FALSE(NameUniquer::needExternalNameMangling("omp_num_thread"));
|
|
ASSERT_FALSE(NameUniquer::needExternalNameMangling(""));
|
|
ASSERT_FALSE(NameUniquer::needExternalNameMangling("_QDTmytypeK2K8K18"));
|
|
ASSERT_FALSE(NameUniquer::needExternalNameMangling("exit_"));
|
|
ASSERT_TRUE(NameUniquer::needExternalNameMangling("_QPfoo"));
|
|
ASSERT_TRUE(NameUniquer::needExternalNameMangling("_QPbar"));
|
|
ASSERT_TRUE(NameUniquer::needExternalNameMangling("_QBa"));
|
|
}
|
|
|
|
TEST(InternalNamesTest, isExternalFacingUniquedName) {
|
|
std::pair result = NameUniquer::deconstruct("_QMmodSs1modSs2modFsubPfun");
|
|
|
|
ASSERT_FALSE(NameUniquer::isExternalFacingUniquedName(result));
|
|
result = NameUniquer::deconstruct("omp_num_thread");
|
|
ASSERT_FALSE(NameUniquer::isExternalFacingUniquedName(result));
|
|
result = NameUniquer::deconstruct("");
|
|
ASSERT_FALSE(NameUniquer::isExternalFacingUniquedName(result));
|
|
result = NameUniquer::deconstruct("_QDTmytypeK2K8K18");
|
|
ASSERT_FALSE(NameUniquer::isExternalFacingUniquedName(result));
|
|
result = NameUniquer::deconstruct("exit_");
|
|
ASSERT_FALSE(NameUniquer::isExternalFacingUniquedName(result));
|
|
result = NameUniquer::deconstruct("_QPfoo");
|
|
ASSERT_TRUE(NameUniquer::isExternalFacingUniquedName(result));
|
|
result = NameUniquer::deconstruct("_QPbar");
|
|
ASSERT_TRUE(NameUniquer::isExternalFacingUniquedName(result));
|
|
result = NameUniquer::deconstruct("_QBa");
|
|
ASSERT_TRUE(NameUniquer::isExternalFacingUniquedName(result));
|
|
}
|
|
|
|
// main() from gtest_main
|