diff --git a/flang/include/flang/Optimizer/Support/InternalNames.h b/flang/include/flang/Optimizer/Support/InternalNames.h --- a/flang/include/flang/Optimizer/Support/InternalNames.h +++ b/flang/include/flang/Optimizer/Support/InternalNames.h @@ -41,7 +41,8 @@ INTRINSIC_TYPE_DESC, PROCEDURE, TYPE_DESC, - VARIABLE + VARIABLE, + NAMELIST_GROUP }; /// Components of an unparsed unique name @@ -112,6 +113,11 @@ llvm::Optional host, llvm::StringRef name); + /// Unique a namelist group name + static std::string doNamelistGroup(llvm::ArrayRef modules, + llvm::Optional host, + llvm::StringRef name); + /// Entry point for the PROGRAM (called by the runtime) /// Can be overridden with the `--main-entry-name=` option. static llvm::StringRef doProgramEntry(); diff --git a/flang/lib/Lower/Mangler.cpp b/flang/lib/Lower/Mangler.cpp --- a/flang/lib/Lower/Mangler.cpp +++ b/flang/lib/Lower/Mangler.cpp @@ -114,6 +114,12 @@ symbolName); return fir::NameUniquer::doVariable(modNames, optHost, symbolName); }, + [&](const Fortran::semantics::NamelistDetails &) { + auto modNames = moduleNames(ultimateSymbol); + auto optHost = hostName(ultimateSymbol); + return fir::NameUniquer::doNamelistGroup(modNames, optHost, + symbolName); + }, [&](const Fortran::semantics::CommonBlockDetails &) { return fir::NameUniquer::doCommonBlock(symbolName); }, diff --git a/flang/lib/Optimizer/Support/InternalNames.cpp b/flang/lib/Optimizer/Support/InternalNames.cpp --- a/flang/lib/Optimizer/Support/InternalNames.cpp +++ b/flang/lib/Optimizer/Support/InternalNames.cpp @@ -205,6 +205,15 @@ return result.append(toLower(name)); } +std::string +fir::NameUniquer::doNamelistGroup(llvm::ArrayRef modules, + llvm::Optional host, + llvm::StringRef name) { + std::string result = prefix(); + result.append(doModulesHost(modules, host)).append("G"); + return result.append(toLower(name)); +} + llvm::StringRef fir::NameUniquer::doProgramEntry() { if (mainEntryName.size()) return mainEntryName; @@ -279,6 +288,10 @@ else kinds.push_back(readInt(uniq, i, i + 1, end)); break; + case 'G': + nk = NameKind::NAMELIST_GROUP; + name = readName(uniq, i, i + 1, end); + break; default: assert(false && "unknown uniquing code"); diff --git a/flang/unittests/Optimizer/InternalNamesTest.cpp b/flang/unittests/Optimizer/InternalNamesTest.cpp --- a/flang/unittests/Optimizer/InternalNamesTest.cpp +++ b/flang/unittests/Optimizer/InternalNamesTest.cpp @@ -162,6 +162,12 @@ 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; @@ -208,6 +214,11 @@ 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); } // main() from gtest_main