Skip to content

Commit d8df1bf

Browse files
authored
Merge pull request #23474 from jrose-apple/export-au-prince
[ParseableInterface] Honor "exported module names"
2 parents 09cfd9e + 0366343 commit d8df1bf

File tree

16 files changed

+95
-43
lines changed

16 files changed

+95
-43
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/AST/PrintOptions.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ struct PrintOptions {
185185
/// type might be ambiguous.
186186
bool FullyQualifiedTypesIfAmbiguous = false;
187187

188+
/// If true, printed module names will use the "exported" name, which may be
189+
/// different from the regular name.
190+
///
191+
/// \see FileUnit::getExportedModuleName
192+
bool UseExportedModuleNames = false;
193+
188194
/// Print Swift.Array and Swift.Optional with sugared syntax
189195
/// ([] and ?), even if there are no sugar type nodes.
190196
bool SynthesizeSugarOnTypes = false;

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-
std::string getExportedModuleName() const;
65+
StringRef getExportedModuleName() const override;
6666

6767
virtual bool isSystemModule() const override;
6868

lib/AST/ASTPrinter.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ PrintOptions PrintOptions::printParseableInterfaceFile() {
9999
result.TypeDefinitions = true;
100100
result.PrintIfConfig = false;
101101
result.FullyQualifiedTypes = true;
102+
result.UseExportedModuleNames = true;
102103
result.AllowNullTypes = false;
103104
result.SkipImports = true;
104105
result.OmitNameOfInaccessibleProperties = true;
@@ -3342,8 +3343,14 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
33423343

33433344
template <typename T>
33443345
void printModuleContext(T *Ty) {
3345-
ModuleDecl *Mod = Ty->getDecl()->getModuleContext();
3346-
Printer.printModuleRef(Mod, Mod->getName());
3346+
FileUnit *File = cast<FileUnit>(Ty->getDecl()->getModuleScopeContext());
3347+
ModuleDecl *Mod = File->getParentModule();
3348+
3349+
Identifier Name = Mod->getName();
3350+
if (Options.UseExportedModuleNames)
3351+
Name = Mod->getASTContext().getIdentifier(File->getExportedModuleName());
3352+
3353+
Printer.printModuleRef(Mod, Name);
33473354
Printer << ".";
33483355
}
33493356

lib/ClangImporter/ClangImporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3146,7 +3146,7 @@ clang::ASTContext &ClangModuleUnit::getClangASTContext() const {
31463146
return owner.getClangASTContext();
31473147
}
31483148

3149-
std::string ClangModuleUnit::getExportedModuleName() const {
3149+
StringRef ClangModuleUnit::getExportedModuleName() const {
31503150
if (clangModule && !clangModule->ExportAsModule.empty())
31513151
return clangModule->ExportAsModule;
31523152

lib/Serialization/Deserialization.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1149,7 +1149,7 @@ static bool isReExportedToModule(const ValueDecl *value,
11491149
= dyn_cast<ClangModuleUnit>(valueDC->getModuleScopeContext());
11501150
if (!fromClangModule)
11511151
return false;
1152-
std::string exportedName = fromClangModule->getExportedModuleName();
1152+
StringRef exportedName = fromClangModule->getExportedModuleName();
11531153

11541154
auto toClangModule
11551155
= dyn_cast<ClangModuleUnit>(expectedModule->getFiles().front());

lib/Serialization/ModuleFile.cpp

Lines changed: 2 additions & 12 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,17 +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-
std::string exportedModuleName;
1851-
if (auto clangModuleUnit =
1852-
dyn_cast<ClangModuleUnit>(parentModule->getFiles().front())) {
1853-
exportedModuleName = clangModuleUnit->getExportedModuleName();
1854-
moduleName = exportedModuleName;
1855-
}
1844+
auto parentFile = cast<FileUnit>(nominal->getParent());
1845+
StringRef moduleName = parentFile->getExportedModuleName();
18561846

18571847
for (auto item : *iter) {
18581848
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);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#import <ExportAsCoreKit.h>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct CKThing {
2+
long value;
3+
};
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module CoreKit {
2+
header "CoreKit.h"
3+
header "ExportAsCoreKit.h"
4+
export *
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
#import <ExportAsCoreKit.h>
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
struct CKThing {
2+
long value;
3+
};
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module CoreKit {
2+
header "CoreKit.h"
3+
export *
4+
}
5+
6+
module ExportAsCoreKit_BAD {
7+
header "ExportAsCoreKit.h"
8+
export_as CoreKit
9+
export *
10+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -typecheck -emit-parseable-module-interface-path %t/CoreKitClient.swiftinterface -module-name CoreKitClient -I %S/Inputs/exported-module-name-before %s
3+
// RUN: %FileCheck -implicit-check-not BAD %s < %t/CoreKitClient.swiftinterface
4+
5+
// Test that we can rebuild it even when the "export as" module goes away.
6+
// RUN: %target-swift-frontend -build-module-from-parseable-interface -o %t/CoreKitClient.swiftmodule -I %S/Inputs/exported-module-name-after %t/CoreKitClient.swiftinterface
7+
8+
// CHECK: import CoreKit
9+
import CoreKit
10+
11+
// CHECK-LABEL: public struct CKThingWrapper : RawRepresentable {
12+
public struct CKThingWrapper: RawRepresentable {
13+
public var rawValue: CKThing
14+
public init(rawValue: CKThing) {
15+
self.rawValue = rawValue
16+
}
17+
// Note that this is CoreKit.CKThing, not ExportAsCoreKit.CKThing
18+
// CHECK: public typealias RawValue = CoreKit.CKThing
19+
} // CHECK: {{^}$}}

0 commit comments

Comments
 (0)