Skip to content

Commit 70977a0

Browse files
authored
Merge pull request swiftlang#30175 from nkcsgexi/expand-module-imports
PrintAsObjc: expand module @imports to header #imports if modules are not supported
2 parents ef309b8 + a2534fa commit 70977a0

File tree

7 files changed

+59
-3
lines changed

7 files changed

+59
-3
lines changed

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,21 @@ static void writeImports(raw_ostream &out,
319319

320320
// Track printed names to handle overlay modules.
321321
llvm::SmallPtrSet<Identifier, 8> seenImports;
322+
llvm::SmallString<256> allPaths;
323+
llvm::SmallSetVector<StringRef, 8> headerImports;
324+
auto insertHeaderPath = [&](clang::Module::Header header,
325+
const clang::Module *module) {
326+
auto startIdx = allPaths.size();
327+
if (module->IsFramework) {
328+
// For framworks, the header import should start from the framework name.
329+
allPaths.append(module->getTopLevelModuleName());
330+
llvm::sys::path::append(allPaths, header.NameAsWritten);
331+
} else {
332+
// Otherwise, import the header directly.
333+
allPaths.append(header.NameAsWritten);
334+
}
335+
headerImports.insert(allPaths.str().substr(startIdx));
336+
};
322337
bool includeUnderlying = false;
323338
for (auto import : sortedImports) {
324339
if (auto *swiftModule = import.dyn_cast<ModuleDecl *>()) {
@@ -327,17 +342,43 @@ static void writeImports(raw_ostream &out,
327342
includeUnderlying = true;
328343
continue;
329344
}
330-
if (seenImports.insert(Name).second)
345+
if (seenImports.insert(Name).second) {
331346
out << "@import " << Name.str() << ";\n";
347+
if (auto *clangM = swiftModule->findUnderlyingClangModule()) {
348+
if (auto umbrella = clangM->getUmbrellaHeader()) {
349+
// If an umbrella header is available, use that.
350+
insertHeaderPath(umbrella, clangM);
351+
} else {
352+
// Collect all headers included in the module.
353+
for (auto headers: clangM->Headers) {
354+
for (auto header: headers) {
355+
insertHeaderPath(header, clangM);
356+
}
357+
}
358+
}
359+
}
360+
}
332361
} else {
333362
const auto *clangModule = import.get<const clang::Module *>();
334363
assert(clangModule->isSubModule() &&
335364
"top-level modules should use a normal swift::ModuleDecl");
336365
out << "@import ";
337366
ModuleDecl::ReverseFullNameIterator(clangModule).printForward(out);
338367
out << ";\n";
368+
// Collect all headers included in the submodule
369+
for (auto headers: clangModule->Headers) {
370+
for (auto header: headers) {
371+
insertHeaderPath(header, clangModule);
372+
}
373+
}
339374
}
340375
}
376+
out << "#else\n";
377+
378+
// We cannot use module import, so use header includes instead.
379+
for (auto header: headerImports) {
380+
out << "#import <" << header << ">\n";
381+
}
341382

342383
out << "#endif\n\n";
343384

test/Inputs/clang-importer-sdk/swift-modules/Foundation.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ public func _convertNSErrorToError(_ error: NSError?) -> Error {
238238
}
239239

240240
public func _convertErrorToNSError(_ x: Error) -> NSError {
241-
return x as NSError
241+
return unsafeDowncast(_bridgeErrorToNSError(x), to: NSError.self)
242242
}
243243

244244
extension _SwiftNewtypeWrapper where Self.RawValue == Error {

test/PrintAsObjC/classes.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
// RUN: %FileCheck %s < %t/classes.h
1818
// RUN: %FileCheck --check-prefix=NEGATIVE %s < %t/classes.h
1919
// RUN: %check-in-clang -I %S/Inputs/custom-modules/ %t/classes.h
20-
// RUN: not %check-in-clang -I %S/Inputs/custom-modules/ -fno-modules -Qunused-arguments %t/classes.h
20+
// RUN: %check-in-clang -I %S/Inputs/custom-modules/ -fno-modules -Qunused-arguments %t/classes.h
2121
// RUN: %check-in-clang -I %S/Inputs/custom-modules/ -fno-modules -Qunused-arguments %t/classes.h -include CoreFoundation.h -include objc_generics.h -include SingleGenericClass.h -include CompatibilityAlias.h
2222

2323
// CHECK-NOT: AppKit;

test/PrintAsObjC/empty.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
// CHECK-NEXT: #if __has_warning
3939
// CHECK-NEXT: #pragma clang diagnostic
4040
// CHECK-NEXT: #endif
41+
// CHECK-NEXT: #else
4142
// CHECK-NEXT: #endif
4243

4344

test/PrintAsObjC/imports.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@
2020
// CHECK-NEXT: @import ObjectiveC;
2121
// CHECK-NEXT: @import ctypes.bits;
2222

23+
// CHECK-NEXT: #else
24+
// CHECK-NEXT: #import <Base.ExplicitSub.h>
25+
// CHECK-NEXT: #import <Base.ExplicitSub.ExSub.h>
26+
// CHECK-NEXT: #import <Base.ImplicitSub.ExSub.h>
27+
// CHECK-NEXT: #import <Foundation.h>
28+
// CHECK-NEXT: #import <MostlyPrivate1/MostlyPrivate1.h>
29+
// CHECK-NEXT: #import <MostlyPrivate1_Private/MostlyPrivate1_Private.h>
30+
// CHECK-NEXT: #import <MostlyPrivate2_Private/MostlyPrivate2_Private.h>
31+
// CHECK-NEXT: #import <ctypes/bits.h>
32+
2333
// NEGATIVE-NOT: ctypes;
2434
// NEGATIVE-NOT: ImSub;
2535
// NEGATIVE-NOT: ImplicitSub;

test/PrintAsObjC/mixed-framework-fwd.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
// CHECK-NEXT: #pragma clang diagnostic
2323
// CHECK-NEXT: #endif
2424
// CHECK-NEXT: @import Foundation;
25+
// CHECK-NEXT: #else
26+
// CHECK-NEXT: #import <Foundation.h>
2527
// CHECK-NEXT: #endif
2628

2729
// NO-IMPORT-NOT: #import

test/PrintAsObjC/mixed-framework.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
// CHECK-NEXT: #pragma clang diagnostic ignored "-Watimport-in-framework-header"
1818
// CHECK-NEXT: #endif
1919
// CHECK-NEXT: @import Foundation;
20+
// CHECK-NEXT: #else
21+
// CHECK-NEXT: #import <Foundation.h>
2022
// CHECK-NEXT: #endif
2123

2224
// FRAMEWORK-LABEL: #import <Mixed/Mixed.h>

0 commit comments

Comments
 (0)