Skip to content
This repository was archived by the owner on Jan 10, 2023. It is now read-only.

Commit df437f3

Browse files
committed
Merge branch 'main' of github.com:apple/swift into tensorflow-stage
* 'main' of github.com:apple/swift: When qualifying Clang types with a module, make sure we choose a visible module (swiftlang#32465)
2 parents aa4afd3 + f4e74f7 commit df437f3

File tree

6 files changed

+109
-8
lines changed

6 files changed

+109
-8
lines changed

include/swift/AST/PrintOptions.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,8 @@ struct PrintOptions {
550550
/// attributes.
551551
///
552552
/// \see swift::emitSwiftInterface
553-
static PrintOptions printSwiftInterfaceFile(bool preferTypeRepr,
553+
static PrintOptions printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
554+
bool preferTypeRepr,
554555
bool printFullConvention,
555556
bool printSPIs);
556557

lib/AST/ASTPrinter.cpp

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,14 +108,16 @@ static bool contributesToParentTypeStorage(const AbstractStorageDecl *ASD) {
108108
return !ND->isResilient() && ASD->hasStorage() && !ASD->isStatic();
109109
}
110110

111-
PrintOptions PrintOptions::printSwiftInterfaceFile(bool preferTypeRepr,
111+
PrintOptions PrintOptions::printSwiftInterfaceFile(ModuleDecl *ModuleToPrint,
112+
bool preferTypeRepr,
112113
bool printFullConvention,
113114
bool printSPIs) {
114115
PrintOptions result;
115116
result.IsForSwiftInterface = true;
116117
result.PrintLongAttrsOnSeparateLines = true;
117118
result.TypeDefinitions = true;
118119
result.PrintIfConfig = false;
120+
result.CurrentModule = ModuleToPrint;
119121
result.FullyQualifiedTypes = true;
120122
result.UseExportedModuleNames = true;
121123
result.AllowNullTypes = false;
@@ -3649,6 +3651,8 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
36493651

36503652
ASTPrinter &Printer;
36513653
const PrintOptions &Options;
3654+
Optional<llvm::DenseMap<const clang::Module *, ModuleDecl *>>
3655+
VisibleClangModules;
36523656

36533657
void printGenericArgs(ArrayRef<Type> Args) {
36543658
if (Args.empty())
@@ -3679,7 +3683,7 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
36793683
}
36803684
}
36813685

3682-
/// Determinee whether the given type has a simple representation
3686+
/// Determine whether the given type has a simple representation
36833687
/// under the current print options.
36843688
bool isSimpleUnderPrintOptions(Type T) {
36853689
if (auto typealias = dyn_cast<TypeAliasType>(T.getPointer())) {
@@ -3701,19 +3705,100 @@ class TypePrinter : public TypeVisitor<TypePrinter> {
37013705
return T->hasSimpleTypeRepr();
37023706
}
37033707

3708+
/// Computes the map that is cached by `getVisibleClangModules()`.
3709+
/// Do not call directly.
3710+
llvm::DenseMap<const clang::Module *, ModuleDecl *>
3711+
computeVisibleClangModules() {
3712+
assert(Options.CurrentModule &&
3713+
"CurrentModule needs to be set to determine imported Clang modules");
3714+
3715+
llvm::DenseMap<const clang::Module *, ModuleDecl *> Result;
3716+
3717+
// For the current module, consider both private and public imports.
3718+
ModuleDecl::ImportFilter Filter = ModuleDecl::ImportFilterKind::Exported;
3719+
Filter |= ModuleDecl::ImportFilterKind::Default;
3720+
Filter |= ModuleDecl::ImportFilterKind::SPIAccessControl;
3721+
SmallVector<ImportedModule, 4> Imports;
3722+
Options.CurrentModule->getImportedModules(Imports, Filter);
3723+
3724+
SmallVector<ModuleDecl *, 4> ModulesToProcess;
3725+
for (const auto &Import : Imports) {
3726+
ModulesToProcess.push_back(Import.importedModule);
3727+
}
3728+
3729+
SmallPtrSet<ModuleDecl *, 4> Processed;
3730+
while (!ModulesToProcess.empty()) {
3731+
ModuleDecl *Mod = ModulesToProcess.back();
3732+
ModulesToProcess.pop_back();
3733+
3734+
if (!Processed.insert(Mod).second)
3735+
continue;
3736+
3737+
if (const clang::Module *ClangModule = Mod->findUnderlyingClangModule())
3738+
Result[ClangModule] = Mod;
3739+
3740+
// For transitive imports, consider only public imports.
3741+
Imports.clear();
3742+
Mod->getImportedModules(Imports, ModuleDecl::ImportFilterKind::Exported);
3743+
for (const auto &Import : Imports) {
3744+
ModulesToProcess.push_back(Import.importedModule);
3745+
}
3746+
}
3747+
3748+
return Result;
3749+
}
3750+
3751+
/// Returns all Clang modules that are visible from `Options.CurrentModule`.
3752+
/// This includes any modules that are imported transitively through public
3753+
/// (`@_exported`) imports.
3754+
///
3755+
/// The returned map associates each visible Clang module with the
3756+
/// corresponding Swift module.
3757+
const llvm::DenseMap<const clang::Module *, ModuleDecl *> &
3758+
getVisibleClangModules() {
3759+
if (!VisibleClangModules) {
3760+
VisibleClangModules = computeVisibleClangModules();
3761+
}
3762+
return *VisibleClangModules;
3763+
}
3764+
37043765
template <typename T>
37053766
void printModuleContext(T *Ty) {
37063767
FileUnit *File = cast<FileUnit>(Ty->getDecl()->getModuleScopeContext());
37073768
ModuleDecl *Mod = File->getParentModule();
3769+
StringRef ExportedModuleName = File->getExportedModuleName();
3770+
3771+
// Clang declarations need special treatment: Multiple Clang modules can
3772+
// contain the same declarations from a textually included header, but not
3773+
// all of these modules may be visible. We therefore need to make sure we
3774+
// choose a module that is visible from the current module. This is possible
3775+
// only if we know what the current module is.
3776+
const clang::Decl *ClangDecl = Ty->getDecl()->getClangDecl();
3777+
if (ClangDecl && Options.CurrentModule) {
3778+
for (auto *Redecl : ClangDecl->redecls()) {
3779+
clang::Module *ClangModule =
3780+
Redecl->getOwningModule()->getTopLevelModule();
3781+
if (!ClangModule)
3782+
continue;
3783+
3784+
if (ModuleDecl *VisibleModule =
3785+
getVisibleClangModules().lookup(ClangModule)) {
3786+
Mod = VisibleModule;
3787+
ExportedModuleName = ClangModule->ExportAsModule;
3788+
break;
3789+
}
3790+
}
3791+
}
37083792

37093793
if (Options.MapCrossImportOverlaysToDeclaringModule) {
37103794
if (ModuleDecl *Declaring = Mod->getDeclaringModuleIfCrossImportOverlay())
37113795
Mod = Declaring;
37123796
}
37133797

37143798
Identifier Name = Mod->getName();
3715-
if (Options.UseExportedModuleNames)
3716-
Name = Mod->getASTContext().getIdentifier(File->getExportedModuleName());
3799+
if (Options.UseExportedModuleNames && !ExportedModuleName.empty()) {
3800+
Name = Mod->getASTContext().getIdentifier(ExportedModuleName);
3801+
}
37173802

37183803
Printer.printModuleRef(Mod, Name);
37193804
Printer << ".";

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -517,7 +517,7 @@ bool swift::emitSwiftInterface(raw_ostream &out,
517517
printImports(out, Opts, M);
518518

519519
const PrintOptions printOptions = PrintOptions::printSwiftInterfaceFile(
520-
Opts.PreserveTypesAsWritten, Opts.PrintFullConvention, Opts.PrintSPIs);
520+
M, Opts.PreserveTypesAsWritten, Opts.PrintFullConvention, Opts.PrintSPIs);
521521
InheritedProtocolCollector::PerTypeMap inheritedProtocolMap;
522522

523523
SmallVector<Decl *, 16> topLevelDecls;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@_spi(dummy) import HelperModule
2+
3+
public func funcTakingForeignStruct(_ param: ForeignStruct) {}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// This tests verifies that SPI visible modules are understood by the machinery
2+
// that produces .swiftinterface files.
3+
//
4+
// See the documentation for the print-qualified-clang-types.swift test next to
5+
// this one for more context.
6+
7+
// RUN: %empty-directory(%t)
8+
// RUN: mkdir %t/helper_module %t/spi_main_module
9+
// RUN: %target-swift-frontend -enable-library-evolution -swift-version 5 -emit-module -o %t/helper_module/HelperModule.swiftmodule %S/Inputs/HelperModule.swift -I %S/Inputs
10+
// RUN: %target-swift-frontend -enable-library-evolution -swift-version 5 -emit-module -o %t/spi_main_module/SpiMainModule.swiftmodule -emit-module-interface-path %t/spi_main_module/SpiMainModule.swiftinterface -I %t/helper_module %S/Inputs/SpiMainModule.swift -I %S/Inputs
11+
// RUN: %FileCheck --input-file=%t/spi_main_module/SpiMainModule.swiftinterface %s
12+
// RUN: %target-swift-frontend -typecheck -swift-version 5 %t/spi_main_module/SpiMainModule.swiftinterface -I %t/helper_module -I %S/Inputs
13+
14+
// CHECK: public func funcTakingForeignStruct(_ param: ForeignB.ForeignStruct)

test/Interop/C/modules/print-qualified-clang-types/print-qualified-clang-types.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,3 @@
3434
// RUN: %target-swift-frontend -typecheck -swift-version 5 %t/main_module/MainModule.swiftinterface -I %t/helper_module -I %S/Inputs
3535

3636
// CHECK: public func funcTakingForeignStruct(_ param: ForeignB.ForeignStruct)
37-
38-
// REQUIRES: SR-13032

0 commit comments

Comments
 (0)