PrintAsObjc: expand module @imports to header #imports if modules are not supported

rdar://58284119
This commit is contained in:
Xi Ge
2020-03-02 18:08:37 -08:00
parent b58ea4bb37
commit a2534fa234
7 changed files with 59 additions and 3 deletions

View File

@@ -319,6 +319,21 @@ static void writeImports(raw_ostream &out,
// Track printed names to handle overlay modules.
llvm::SmallPtrSet<Identifier, 8> seenImports;
llvm::SmallString<256> allPaths;
llvm::SmallSetVector<StringRef, 8> headerImports;
auto insertHeaderPath = [&](clang::Module::Header header,
const clang::Module *module) {
auto startIdx = allPaths.size();
if (module->IsFramework) {
// For framworks, the header import should start from the framework name.
allPaths.append(module->getTopLevelModuleName());
llvm::sys::path::append(allPaths, header.NameAsWritten);
} else {
// Otherwise, import the header directly.
allPaths.append(header.NameAsWritten);
}
headerImports.insert(allPaths.str().substr(startIdx));
};
bool includeUnderlying = false;
for (auto import : sortedImports) {
if (auto *swiftModule = import.dyn_cast<ModuleDecl *>()) {
@@ -327,8 +342,22 @@ static void writeImports(raw_ostream &out,
includeUnderlying = true;
continue;
}
if (seenImports.insert(Name).second)
if (seenImports.insert(Name).second) {
out << "@import " << Name.str() << ";\n";
if (auto *clangM = swiftModule->findUnderlyingClangModule()) {
if (auto umbrella = clangM->getUmbrellaHeader()) {
// If an umbrella header is available, use that.
insertHeaderPath(umbrella, clangM);
} else {
// Collect all headers included in the module.
for (auto headers: clangM->Headers) {
for (auto header: headers) {
insertHeaderPath(header, clangM);
}
}
}
}
}
} else {
const auto *clangModule = import.get<const clang::Module *>();
assert(clangModule->isSubModule() &&
@@ -336,8 +365,20 @@ static void writeImports(raw_ostream &out,
out << "@import ";
ModuleDecl::ReverseFullNameIterator(clangModule).printForward(out);
out << ";\n";
// Collect all headers included in the submodule
for (auto headers: clangModule->Headers) {
for (auto header: headers) {
insertHeaderPath(header, clangModule);
}
}
}
}
out << "#else\n";
// We cannot use module import, so use header includes instead.
for (auto header: headerImports) {
out << "#import <" << header << ">\n";
}
out << "#endif\n\n";

View File

@@ -238,7 +238,7 @@ public func _convertNSErrorToError(_ error: NSError?) -> Error {
}
public func _convertErrorToNSError(_ x: Error) -> NSError {
return x as NSError
return unsafeDowncast(_bridgeErrorToNSError(x), to: NSError.self)
}
extension _SwiftNewtypeWrapper where Self.RawValue == Error {

View File

@@ -17,7 +17,7 @@
// RUN: %FileCheck %s < %t/classes.h
// RUN: %FileCheck --check-prefix=NEGATIVE %s < %t/classes.h
// RUN: %check-in-clang -I %S/Inputs/custom-modules/ %t/classes.h
// RUN: not %check-in-clang -I %S/Inputs/custom-modules/ -fno-modules -Qunused-arguments %t/classes.h
// RUN: %check-in-clang -I %S/Inputs/custom-modules/ -fno-modules -Qunused-arguments %t/classes.h
// 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
// CHECK-NOT: AppKit;

View File

@@ -38,6 +38,7 @@
// CHECK-NEXT: #if __has_warning
// CHECK-NEXT: #pragma clang diagnostic
// CHECK-NEXT: #endif
// CHECK-NEXT: #else
// CHECK-NEXT: #endif

View File

@@ -20,6 +20,16 @@
// CHECK-NEXT: @import ObjectiveC;
// CHECK-NEXT: @import ctypes.bits;
// CHECK-NEXT: #else
// CHECK-NEXT: #import <Base.ExplicitSub.h>
// CHECK-NEXT: #import <Base.ExplicitSub.ExSub.h>
// CHECK-NEXT: #import <Base.ImplicitSub.ExSub.h>
// CHECK-NEXT: #import <Foundation.h>
// CHECK-NEXT: #import <MostlyPrivate1/MostlyPrivate1.h>
// CHECK-NEXT: #import <MostlyPrivate1_Private/MostlyPrivate1_Private.h>
// CHECK-NEXT: #import <MostlyPrivate2_Private/MostlyPrivate2_Private.h>
// CHECK-NEXT: #import <ctypes/bits.h>
// NEGATIVE-NOT: ctypes;
// NEGATIVE-NOT: ImSub;
// NEGATIVE-NOT: ImplicitSub;

View File

@@ -22,6 +22,8 @@
// CHECK-NEXT: #pragma clang diagnostic
// CHECK-NEXT: #endif
// CHECK-NEXT: @import Foundation;
// CHECK-NEXT: #else
// CHECK-NEXT: #import <Foundation.h>
// CHECK-NEXT: #endif
// NO-IMPORT-NOT: #import

View File

@@ -17,6 +17,8 @@
// CHECK-NEXT: #pragma clang diagnostic ignored "-Watimport-in-framework-header"
// CHECK-NEXT: #endif
// CHECK-NEXT: @import Foundation;
// CHECK-NEXT: #else
// CHECK-NEXT: #import <Foundation.h>
// CHECK-NEXT: #endif
// FRAMEWORK-LABEL: #import <Mixed/Mixed.h>