Skip to content

Commit 4517e63

Browse files
committed
[Bridging PCH] Add ClangImporter::importBridgingPCH, call for .pch files.
1 parent a2b1455 commit 4517e63

File tree

4 files changed

+55
-2
lines changed

4 files changed

+55
-2
lines changed

include/swift/ClangImporter/ClangImporter.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,19 @@ class ClangImporter final : public ClangModuleLoader {
209209
SourceLoc diagLoc = {},
210210
bool trackParsedSymbols = false);
211211

212+
/// Imports an Objective-C PCH file into the shared imported header module.
213+
///
214+
/// This is the "PCH variant" of importBridgingHeader; the provided PCH
215+
/// needs to have been previously generated by emitBridgingPCH.
216+
///
217+
/// \param pchFile The path of the PCH file to import.
218+
/// \param adapter The module that depends on the contents of this header.
219+
/// \param diagLoc A location to attach any diagnostics to if import fails.
220+
///
221+
/// \sa importBridgingHeader
222+
bool importBridgingPCH(StringRef pchFile, ModuleDecl *adapter,
223+
SourceLoc diagLoc = {});
224+
212225
/// Returns the module that contains imports and declarations from all loaded
213226
/// Objective-C header files.
214227
///

include/swift/ClangImporter/ClangImporterOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ class ClangImporterOptions {
3535
/// Equivalent to Clang's -mcpu=.
3636
std::string TargetCPU;
3737

38+
// The bridging header or PCH that will be imported.
39+
std::string BridgingHeader;
40+
3841
/// \see Mode
3942
enum class Modes {
4043
/// Set up Clang for importing modules into Swift and generating IR from

lib/ClangImporter/ClangImporter.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#include "swift/Parse/Lexer.h"
3636
#include "swift/Parse/Parser.h"
3737
#include "swift/Config.h"
38+
#include "swift/Strings.h"
3839
#include "clang/AST/ASTContext.h"
3940
#include "clang/AST/Mangle.h"
4041
#include "clang/Basic/CharInfo.h"
@@ -719,6 +720,15 @@ ClangImporter::create(ASTContext &ctx,
719720
auto ppTracker = llvm::make_unique<BridgingPPTracker>(importer->Impl);
720721
clangPP.addPPCallbacks(std::move(ppTracker));
721722

723+
// If we're going to load a bridging PCH, we need to know this now in order to
724+
// clobber clangPP's predefined-macros buffer, otherwise it will provide macro
725+
// definitions that collide with those in the PCH. This is actually simulating
726+
// something clang does when it attaches to a PCH ASTReader as well, it's just
727+
// interleaving the steps in an unusual order.
728+
if (llvm::sys::path::extension(importerOpts.BridgingHeader).endswith(
729+
PCH_EXTENSION))
730+
clangPP.setPredefines("");
731+
722732
instance.createModuleManager();
723733
instance.getModuleManager()->addListener(
724734
std::unique_ptr<clang::ASTReaderListener>(
@@ -926,6 +936,9 @@ bool ClangImporter::importHeader(StringRef header, Module *adapter,
926936
bool ClangImporter::importBridgingHeader(StringRef header, Module *adapter,
927937
SourceLoc diagLoc,
928938
bool trackParsedSymbols) {
939+
if (llvm::sys::path::extension(header).endswith(PCH_EXTENSION)) {
940+
return importBridgingPCH(header, adapter);
941+
}
929942
clang::FileManager &fileManager = Impl.Instance->getFileManager();
930943
const clang::FileEntry *headerFile = fileManager.getFile(header,
931944
/*OpenFile=*/true);
@@ -948,6 +961,29 @@ bool ClangImporter::importBridgingHeader(StringRef header, Module *adapter,
948961
std::move(sourceBuffer));
949962
}
950963

964+
bool ClangImporter::importBridgingPCH(StringRef pchFile, ModuleDecl *adapter,
965+
SourceLoc diagLoc)
966+
{
967+
clang::ASTReader &R = *Impl.Instance->getModuleManager();
968+
SmallVector<clang::ASTReader::ImportedSubmodule, 2> Imports;
969+
switch (R.ReadAST(pchFile, clang::serialization::MK_PCH,
970+
clang::SourceLocation(), 0, &Imports)) {
971+
case clang::ASTReader::Success:
972+
Impl.ImportedHeaderOwners.push_back(adapter);
973+
for (auto I : Imports) {
974+
clang::Module *CM = R.getSubmodule(I.ID);
975+
assert(CM);
976+
Impl.getClangPreprocessor().makeModuleVisible(CM, I.ImportLoc);
977+
R.makeModuleVisible(CM, clang::Module::AllVisible, I.ImportLoc);
978+
Module *M = Impl.finishLoadingClangModule(*this, CM, /*adapter=*/true);
979+
Impl.ImportedHeaderExports.push_back({ /*filter=*/{}, M });
980+
}
981+
return false;
982+
default:
983+
return true;
984+
}
985+
}
986+
951987
std::string ClangImporter::getBridgingHeaderContents(StringRef headerPath,
952988
off_t &fileSize,
953989
time_t &fileModTime) {

lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ static bool ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args,
766766
Opts.ImportUnderlyingModule |= Args.hasArg(OPT_import_underlying_module);
767767
Opts.SILSerializeAll |= Args.hasArg(OPT_sil_serialize_all);
768768

769-
if (const Arg *A = Args.getLastArg(OPT_import_objc_header)) {
769+
if (const Arg *A = Args.getLastArgNoClaim(OPT_import_objc_header)) {
770770
Opts.ImplicitObjCHeaderPath = A->getValue();
771771
Opts.SerializeBridgingHeader |=
772772
!Opts.PrimaryInput && !Opts.ModuleOutputPath.empty();
@@ -993,7 +993,8 @@ static bool ParseClangImporterArgs(ClangImporterOptions &Opts,
993993

994994
if (Args.hasArg(OPT_embed_bitcode))
995995
Opts.Mode = ClangImporterOptions::Modes::EmbedBitcode;
996-
996+
if (auto *A = Args.getLastArg(OPT_import_objc_header))
997+
Opts.BridgingHeader = A->getValue();
997998
Opts.DisableSwiftBridgeAttr |= Args.hasArg(OPT_disable_swift_bridge_attr);
998999

9991000
Opts.DisableModulesValidateSystemHeaders |= Args.hasArg(OPT_disable_modules_validate_system_headers);

0 commit comments

Comments
 (0)