Skip to content

Commit 93616cd

Browse files
committed
Push Clang's "exported module name" notion up to Swift's FileUnit
It's a pretty obscure feature (and one we wish we didn't need), but sometimes API is initially exposed through one module in order to build another one, and we want the canonical presented name to be something else. Push this concept into Swift's AST properly so that other parts of the compiler stop having to know that this is a Clang-specific special case. No functionality change in this commit; will be used in the next commit.
1 parent 61d3b0d commit 93616cd

File tree

5 files changed

+36
-37
lines changed

5 files changed

+36
-37
lines changed

include/swift/AST/Module.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,14 @@ class FileUnit : public DeclContext {
810810
return nullptr;
811811
}
812812

813+
/// Returns the name to use when referencing entities in this file.
814+
///
815+
/// Usually this is the module name itself, but certain Clang features allow
816+
/// substituting another name instead.
817+
virtual StringRef getExportedModuleName() const {
818+
return getParentModule()->getName().str();
819+
}
820+
813821
/// Traverse the decls within this file.
814822
///
815823
/// \returns true if traversal was aborted, false if it completed

include/swift/ClangImporter/ClangModule.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ class ClangModuleUnit final : public LoadedFile {
6262
/// Retrieve the "exported" name of the module, which is usually the module
6363
/// name, but might be the name of the public module through which this
6464
/// (private) module is re-exported.
65-
StringRef getExportedModuleName() const;
65+
StringRef getExportedModuleName() const override;
6666

6767
virtual bool isSystemModule() const override;
6868

lib/Serialization/ModuleFile.cpp

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
#include "swift/AST/USRGeneration.h"
2626
#include "swift/Basic/Range.h"
2727
#include "swift/ClangImporter/ClangImporter.h"
28-
#include "swift/ClangImporter/ClangModule.h"
2928
#include "swift/Serialization/BCReadingExtras.h"
3029
#include "swift/Serialization/SerializedModuleLoader.h"
3130
#include "llvm/ADT/StringExtras.h"
@@ -1842,15 +1841,8 @@ void ModuleFile::loadExtensions(NominalTypeDecl *nominal) {
18421841
}
18431842

18441843
if (nominal->getParent()->isModuleScopeContext()) {
1845-
auto parentModule = nominal->getParentModule();
1846-
StringRef moduleName = parentModule->getName().str();
1847-
1848-
// If the originating module is a private module whose interface is
1849-
// re-exported via public module, check the name of the public module.
1850-
if (auto clangModuleUnit =
1851-
dyn_cast<ClangModuleUnit>(parentModule->getFiles().front())) {
1852-
moduleName = clangModuleUnit->getExportedModuleName();
1853-
}
1844+
auto parentFile = cast<FileUnit>(nominal->getParent());
1845+
StringRef moduleName = parentFile->getExportedModuleName();
18541846

18551847
for (auto item : *iter) {
18561848
if (item.first != moduleName)

lib/Serialization/Serialization.cpp

Lines changed: 19 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -180,7 +180,7 @@ namespace {
180180
int32_t getNameDataForBase(const NominalTypeDecl *nominal,
181181
StringRef *dataToWrite = nullptr) {
182182
if (nominal->getDeclContext()->isModuleScopeContext())
183-
return -Serializer.addModuleRef(nominal->getParentModule());
183+
return -Serializer.addContainingModuleRef(nominal->getDeclContext());
184184

185185
auto &mangledName = MangledNameCache[nominal];
186186
if (mangledName.empty())
@@ -731,7 +731,12 @@ IdentifierID Serializer::addFilename(StringRef filename) {
731731
return addUniquedString(filename).second;
732732
}
733733

734-
IdentifierID Serializer::addModuleRef(const ModuleDecl *M) {
734+
IdentifierID Serializer::addContainingModuleRef(const DeclContext *DC) {
735+
assert(!isa<ModuleDecl>(DC) &&
736+
"References should be to things within modules");
737+
const FileUnit *file = cast<FileUnit>(DC->getModuleScopeContext());
738+
const ModuleDecl *M = file->getParentModule();
739+
735740
if (M == this->M)
736741
return CURRENT_MODULE_ID;
737742
if (M == this->M->getASTContext().TheBuiltinModule)
@@ -743,18 +748,10 @@ IdentifierID Serializer::addModuleRef(const ModuleDecl *M) {
743748
if (M == clangImporter->getImportedHeaderModule())
744749
return OBJC_HEADER_MODULE_ID;
745750

746-
// If we're referring to a member of a private module that will be
747-
// re-exported via a public module, record the public module's name.
748-
if (auto clangModuleUnit =
749-
dyn_cast<ClangModuleUnit>(M->getFiles().front())) {
750-
auto exportedModuleName =
751-
M->getASTContext().getIdentifier(
752-
clangModuleUnit->getExportedModuleName());
753-
return addDeclBaseNameRef(exportedModuleName);
754-
}
755-
756-
assert(!M->getName().empty());
757-
return addDeclBaseNameRef(M->getName());
751+
auto exportedModuleName = file->getExportedModuleName();
752+
assert(!exportedModuleName.empty());
753+
auto exportedModuleID = M->getASTContext().getIdentifier(exportedModuleName);
754+
return addDeclBaseNameRef(exportedModuleID);
758755
}
759756

760757
SILLayoutID Serializer::addSILLayoutRef(SILLayout *layout) {
@@ -1650,7 +1647,7 @@ Serializer::writeConformance(ProtocolConformanceRef conformanceRef,
16501647
abbrCode,
16511648
addDeclRef(normal->getProtocol()),
16521649
addDeclRef(normal->getType()->getAnyNominal()),
1653-
addModuleRef(normal->getDeclContext()->getParentModule()));
1650+
addContainingModuleRef(normal->getDeclContext()));
16541651
}
16551652
break;
16561653
}
@@ -1885,14 +1882,13 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
18851882
case DeclContextKind::EnumElementDecl:
18861883
llvm_unreachable("cannot cross-reference this context");
18871884

1888-
case DeclContextKind::FileUnit:
1889-
DC = cast<FileUnit>(DC)->getParentModule();
1890-
LLVM_FALLTHROUGH;
1891-
18921885
case DeclContextKind::Module:
1886+
llvm_unreachable("should only cross-reference something within a file");
1887+
1888+
case DeclContextKind::FileUnit:
18931889
abbrCode = DeclTypeAbbrCodes[XRefLayout::Code];
18941890
XRefLayout::emitRecord(Out, ScratchRecord, abbrCode,
1895-
addModuleRef(cast<ModuleDecl>(DC)), pathLen);
1891+
addContainingModuleRef(DC), pathLen);
18961892
break;
18971893

18981894
case DeclContextKind::GenericTypeDecl: {
@@ -1929,7 +1925,7 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
19291925
genericSig = ext->getGenericSignature()->getCanonicalSignature();
19301926
}
19311927
XRefExtensionPathPieceLayout::emitRecord(
1932-
Out, ScratchRecord, abbrCode, addModuleRef(DC->getParentModule()),
1928+
Out, ScratchRecord, abbrCode, addContainingModuleRef(DC),
19331929
addGenericSignatureRef(genericSig));
19341930
break;
19351931
}
@@ -2022,7 +2018,7 @@ void Serializer::writeCrossReference(const Decl *D) {
20222018
unsigned abbrCode;
20232019

20242020
if (auto op = dyn_cast<OperatorDecl>(D)) {
2025-
writeCrossReference(op->getModuleContext(), 1);
2021+
writeCrossReference(op->getDeclContext(), 1);
20262022

20272023
abbrCode = DeclTypeAbbrCodes[XRefOperatorOrAccessorPathPieceLayout::Code];
20282024
auto nameID = addDeclBaseNameRef(op->getName());
@@ -2034,7 +2030,7 @@ void Serializer::writeCrossReference(const Decl *D) {
20342030
}
20352031

20362032
if (auto prec = dyn_cast<PrecedenceGroupDecl>(D)) {
2037-
writeCrossReference(prec->getModuleContext(), 1);
2033+
writeCrossReference(prec->getDeclContext(), 1);
20382034

20392035
abbrCode = DeclTypeAbbrCodes[XRefOperatorOrAccessorPathPieceLayout::Code];
20402036
auto nameID = addDeclBaseNameRef(prec->getName());

lib/Serialization/Serialization.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -540,13 +540,16 @@ class Serializer : public SerializerBase {
540540
/// Records the use of the given SILLayout.
541541
SILLayoutID addSILLayoutRef(SILLayout *layout);
542542

543-
/// Records the use of the given module.
543+
/// Records the module containing \p DC.
544544
///
545-
/// The module's name will be scheduled for serialization if necessary.
545+
/// The module's name will be scheduled for serialization if necessary. This
546+
/// may not be exactly the same as the name of the module containing DC;
547+
/// instead, it will match the containing file's "exported module name".
546548
///
547549
/// \returns The ID for the identifier for the module's name, or one of the
548550
/// special module codes defined above.
549-
IdentifierID addModuleRef(const ModuleDecl *M);
551+
/// \see FileUnit::getExportedModuleName
552+
IdentifierID addContainingModuleRef(const DeclContext *DC);
550553

551554
/// Write a normal protocol conformance.
552555
void writeNormalConformance(const NormalProtocolConformance *conformance);

0 commit comments

Comments
 (0)