Skip to content

Commit b0222c3

Browse files
committed
[Bridging PCH] Warn on non-redundant implicit bridging-header imports.
We're trying to get rid of implicit bridging-header imports, as a feature. These are IMPORTED_HEADER blocks left in modules built with bridging headers, that trigger re-importing the bridging header into any client that imports the module. As a half-way measure to deprecating them, we add a warning here that triggers when an implicit bridging-header import occurs that is _not_ suppressed as redundant by clang.
1 parent 114e63a commit b0222c3

File tree

7 files changed

+42
-10
lines changed

7 files changed

+42
-10
lines changed

include/swift/AST/DiagnosticsClangImporter.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,11 @@ WARNING(unresolvable_clang_decl,none,
7979
"imported declaration '%0' could not be mapped to '%1'",
8080
(StringRef, StringRef))
8181

82+
WARNING(implicit_bridging_header_imported_from_module,none,
83+
"implicit import of bridging header '%0' via module %1 "
84+
"is deprecated and will be removed in a later version of Swift",
85+
(StringRef, Identifier))
86+
8287
#ifndef DIAG_NO_UNDEF
8388
# if defined(DIAG)
8489
# undef DIAG

include/swift/ClangImporter/ClangImporter.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,13 +201,16 @@ class ClangImporter final : public ClangModuleLoader {
201201
/// \param diagLoc A location to attach any diagnostics to if import fails.
202202
/// \param trackParsedSymbols If true, tracks decls and macros that were
203203
/// parsed from the bridging header.
204+
/// \param implicitImport If true, indicates that this import was implicit
205+
/// from a reference in a module file (deprecated behaviour).
204206
///
205207
/// \returns true if there was an error importing the header.
206208
///
207209
/// \sa getImportedHeaderModule
208210
bool importBridgingHeader(StringRef header, ModuleDecl *adapter,
209211
SourceLoc diagLoc = {},
210-
bool trackParsedSymbols = false);
212+
bool trackParsedSymbols = false,
213+
bool implicitImport = false);
211214

212215
/// Imports an Objective-C PCH file into the shared imported header module.
213216
///

lib/ClangImporter/ClangImporter.cpp

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -827,7 +827,8 @@ bool ClangImporter::addSearchPath(StringRef newSearchPath, bool isFramework) {
827827
bool ClangImporter::Implementation::importHeader(
828828
Module *adapter, StringRef headerName, SourceLoc diagLoc,
829829
bool trackParsedSymbols,
830-
std::unique_ptr<llvm::MemoryBuffer> sourceBuffer) {
830+
std::unique_ptr<llvm::MemoryBuffer> sourceBuffer,
831+
bool implicitImport) {
831832
// Don't even try to load the bridging header if the Clang AST is in a bad
832833
// state. It could cause a crash.
833834
auto &clangDiags = getClangASTContext().getDiagnostics();
@@ -879,6 +880,27 @@ bool ClangImporter::Implementation::importHeader(
879880
consumer.reset();
880881
}
881882

883+
// We're trying to discourage (and eventually deprecate) the use of implicit
884+
// bridging-header imports triggered by IMPORTED_HEADER blocks in
885+
// modules. There are two sub-cases to consider:
886+
//
887+
// #1 The implicit import actually occurred.
888+
//
889+
// #2 The user explicitly -import-objc-header'ed some header or PCH that
890+
// makes the implicit import redundant.
891+
//
892+
// It's not obvious how to exactly differentiate these cases given the
893+
// interface clang gives us, but we only want to warn on case #1, and the
894+
// non-emptiness of allParsedDecls is a _definite_ sign that we're in case
895+
// #1. So we treat that as an approximation of the condition we're after, and
896+
// accept that we might fail to warn in the odd case where "the import
897+
// occurred" but didn't introduce any new decls.
898+
if (implicitImport && !allParsedDecls.empty()) {
899+
SwiftContext.Diags.diagnose(
900+
diagLoc, diag::implicit_bridging_header_imported_from_module,
901+
llvm::sys::path::filename(headerName), adapter->getName());
902+
}
903+
882904
// We can't do this as we're parsing because we may want to resolve naming
883905
// conflicts between the things we've parsed.
884906
for (auto group : allParsedDecls)
@@ -921,7 +943,7 @@ bool ClangImporter::importHeader(StringRef header, Module *adapter,
921943
/*OpenFile=*/true);
922944
if (headerFile && headerFile->getSize() == expectedSize &&
923945
headerFile->getModificationTime() == expectedModTime) {
924-
return importBridgingHeader(header, adapter, diagLoc);
946+
return importBridgingHeader(header, adapter, diagLoc, false, true);
925947
}
926948

927949
if (!cachedContents.empty() && cachedContents.back() == '\0')
@@ -930,12 +952,13 @@ bool ClangImporter::importHeader(StringRef header, Module *adapter,
930952
llvm::MemoryBuffer::getMemBuffer(cachedContents, header)
931953
};
932954
return Impl.importHeader(adapter, header, diagLoc, /*trackParsedSymbols=*/false,
933-
std::move(sourceBuffer));
955+
std::move(sourceBuffer), true);
934956
}
935957

936958
bool ClangImporter::importBridgingHeader(StringRef header, Module *adapter,
937959
SourceLoc diagLoc,
938-
bool trackParsedSymbols) {
960+
bool trackParsedSymbols,
961+
bool implicitImport) {
939962
if (llvm::sys::path::extension(header).endswith(PCH_EXTENSION)) {
940963
return importBridgingPCH(header, adapter);
941964
}
@@ -958,7 +981,7 @@ bool ClangImporter::importBridgingHeader(StringRef header, Module *adapter,
958981
};
959982

960983
return Impl.importHeader(adapter, header, diagLoc, trackParsedSymbols,
961-
std::move(sourceBuffer));
984+
std::move(sourceBuffer), implicitImport);
962985
}
963986

964987
bool ClangImporter::importBridgingPCH(StringRef pchFile, ModuleDecl *adapter,

lib/ClangImporter/ImporterImpl.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,8 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
596596
/// Imports the given header contents into the Clang context.
597597
bool importHeader(Module *adapter, StringRef headerName, SourceLoc diagLoc,
598598
bool trackParsedSymbols,
599-
std::unique_ptr<llvm::MemoryBuffer> contents);
599+
std::unique_ptr<llvm::MemoryBuffer> contents,
600+
bool implicitImport);
600601

601602
/// \brief Retrieve the imported module that should contain the given
602603
/// Clang decl.

test/ClangImporter/MixedSource/broken-bridging-header.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919

2020
// REQUIRES: objc_interop
2121

22-
import HasBridgingHeader // expected-error {{failed to import bridging header}} expected-error {{failed to load module 'HasBridgingHeader'}}
22+
import HasBridgingHeader // expected-error {{failed to import bridging header}} expected-error {{failed to load module 'HasBridgingHeader'}} expected-warning {{implicit import of bridging header}}
2323

2424
// MISSING-HEADER: error: bridging header '{{.*}}/fake.h' does not exist
2525
// MISSING-HEADER-NOT: error:

test/ClangImporter/MixedSource/import-mixed-with-header-twice.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
// USE-SERIALIZED-HEADER: redefinition of 'Point2D'
1414
// USE-SERIALIZED-HEADER: previous definition is here
1515

16-
import MixedWithHeaderAgain
16+
import MixedWithHeaderAgain // expected-warning {{implicit import of bridging header 'header-again.h' via module 'MixedWithHeaderAgain' is deprecated and will be removed in a later version of Swift}}
1717

1818
func testLine(line: Line) {
1919
testLineImpl(line)

test/ClangImporter/MixedSource/import-mixed-with-header.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
// XFAIL: linux
1616

17-
import MixedWithHeader
17+
import MixedWithHeader // expected-warning {{implicit import of bridging header 'header.h' via module 'MixedWithHeader' is deprecated and will be removed in a later version of Swift}}
1818

1919
func testReexportedClangModules(_ foo : FooProto) {
2020
_ = foo.bar as CInt

0 commit comments

Comments
 (0)