Skip to content

Commit 94f30aa

Browse files
authored
Merge pull request #7705 from graydon/rdar-30615193-defer-module-import-from-bridging-header-until-finished-parse
[Clang Importer] Defer module imports to end of bridging-header parse.
2 parents 5c2fe34 + 416a12e commit 94f30aa

File tree

9 files changed

+114
-64
lines changed

9 files changed

+114
-64
lines changed

include/swift/ClangImporter/ClangModule.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#define SWIFT_CLANGIMPORTER_CLANGMODULE_H
1818

1919
#include "swift/AST/Module.h"
20+
#include "swift/ClangImporter/ClangImporter.h"
2021

2122
namespace clang {
2223
class ASTContext;
@@ -26,12 +27,11 @@ namespace clang {
2627
namespace swift {
2728

2829
class ASTContext;
29-
class ClangImporter;
3030
class ModuleLoader;
3131

3232
/// \brief Represents a Clang module that has been imported into Swift.
3333
class ClangModuleUnit final : public LoadedFile {
34-
ClangImporter &owner;
34+
ClangImporter::Implementation &owner;
3535
const clang::Module *clangModule;
3636
llvm::PointerIntPair<ModuleDecl *, 1, bool> adapterModule;
3737
mutable ArrayRef<ModuleDecl::ImportedModule> importedModulesForLookup;
@@ -42,7 +42,7 @@ class ClangModuleUnit final : public LoadedFile {
4242
/// True if the given Module contains an imported Clang module unit.
4343
static bool hasClangModule(ModuleDecl *M);
4444

45-
ClangModuleUnit(ModuleDecl &M, ClangImporter &owner,
45+
ClangModuleUnit(ModuleDecl &M, ClangImporter::Implementation &owner,
4646
const clang::Module *clangModule);
4747

4848
/// \brief Retrieve the underlying Clang module.

lib/ClangImporter/ClangImporter.cpp

Lines changed: 63 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,7 @@ namespace {
8383
void handleImport(const clang::Module *imported) {
8484
if (!imported)
8585
return;
86-
ModuleDecl *nativeImported = Impl.finishLoadingClangModule(Importer, imported,
87-
/*preferAdapter=*/true);
88-
Impl.ImportedHeaderExports.push_back({ /*filter=*/{}, nativeImported });
86+
Impl.DeferredHeaderImports.push_back(imported);
8987
}
9088

9189
void InclusionDirective(clang::SourceLocation HashLoc,
@@ -835,7 +833,7 @@ ClangImporter::create(ASTContext &ctx,
835833
// Set up the imported header module.
836834
auto *importedHeaderModule = ModuleDecl::create(ctx.getIdentifier("__ObjC"), ctx);
837835
importer->Impl.ImportedHeaderUnit =
838-
new (ctx) ClangModuleUnit(*importedHeaderModule, *importer, nullptr);
836+
new (ctx) ClangModuleUnit(*importedHeaderModule, importer->Impl, nullptr);
839837
importedHeaderModule->addFile(*importer->Impl.ImportedHeaderUnit);
840838

841839
importer->Impl.IsReadingBridgingPCH = false;
@@ -963,6 +961,9 @@ bool ClangImporter::Implementation::importHeader(
963961
// Add any defined macros to the bridging header lookup table.
964962
addMacrosToLookupTable(*BridgingHeaderLookupTable, getNameImporter());
965963

964+
// Finish loading any extra modules that were (transitively) imported.
965+
handleDeferredImports();
966+
966967
// Wrap all Clang imports under a Swift import decl.
967968
for (auto &Import : BridgeHeaderTopLevelImports) {
968969
if (auto *ClangImport = Import.dyn_cast<clang::ImportDecl*>()) {
@@ -1008,16 +1009,11 @@ bool ClangImporter::importBridgingHeader(StringRef header, ModuleDecl *adapter,
10081009
bool trackParsedSymbols,
10091010
bool implicitImport) {
10101011
if (llvm::sys::path::extension(header).endswith(PCH_EXTENSION)) {
1011-
// We already imported this with -include-pch above, so we should have
1012-
// collected a bunch of PCH-encoded module imports that we need to
1013-
// replay to the HeaderImportCallbacks for processing.
10141012
Impl.ImportedHeaderOwners.push_back(adapter);
1015-
clang::ASTReader &R = *Impl.Instance->getModuleManager();
1016-
HeaderImportCallbacks CB(*this, Impl);
1017-
for (auto ID : Impl.PCHImportedSubmodules) {
1018-
CB.handleImport(R.getSubmodule(ID));
1019-
}
1020-
Impl.PCHImportedSubmodules.clear();
1013+
// We already imported this with -include-pch above, so we should have
1014+
// collected a bunch of PCH-encoded module imports that we just need to
1015+
// replay in handleDeferredImports.
1016+
Impl.handleDeferredImports();
10211017
return false;
10221018
}
10231019
clang::FileManager &fileManager = Impl.Instance->getFileManager();
@@ -1037,7 +1033,6 @@ bool ClangImporter::importBridgingHeader(StringRef header, ModuleDecl *adapter,
10371033
llvm::MemoryBuffer::getMemBufferCopy(
10381034
importLine, Implementation::bridgingHeaderBufferName)
10391035
};
1040-
10411036
return Impl.importHeader(adapter, header, diagLoc, trackParsedSymbols,
10421037
std::move(sourceBuffer), implicitImport);
10431038
}
@@ -1234,12 +1229,11 @@ ModuleDecl *ClangImporter::loadModule(
12341229
if (!clangModule)
12351230
return nullptr;
12361231

1237-
return Impl.finishLoadingClangModule(*this, clangModule,
1232+
return Impl.finishLoadingClangModule(clangModule,
12381233
/*preferAdapter=*/false);
12391234
}
12401235

12411236
ModuleDecl *ClangImporter::Implementation::finishLoadingClangModule(
1242-
ClangImporter &owner,
12431237
const clang::Module *clangModule,
12441238
bool findAdapter) {
12451239
assert(clangModule);
@@ -1269,7 +1263,7 @@ ModuleDecl *ClangImporter::Implementation::finishLoadingClangModule(
12691263
result->setTestingEnabled();
12701264

12711265
wrapperUnit =
1272-
new (SwiftContext) ClangModuleUnit(*result, owner, clangModule);
1266+
new (SwiftContext) ClangModuleUnit(*result, *this, clangModule);
12731267
result->addFile(*wrapperUnit);
12741268
cacheEntry.setPointerAndInt(wrapperUnit, true);
12751269

@@ -1280,7 +1274,7 @@ ModuleDecl *ClangImporter::Implementation::finishLoadingClangModule(
12801274
}
12811275

12821276
if (clangModule->isSubModule()) {
1283-
finishLoadingClangModule(owner, clangModule->getTopLevelModule(), true);
1277+
finishLoadingClangModule(clangModule->getTopLevelModule(), true);
12841278
} else {
12851279
ModuleDecl *&loaded = SwiftContext.LoadedModules[result->getName()];
12861280
if (!loaded)
@@ -1294,6 +1288,25 @@ ModuleDecl *ClangImporter::Implementation::finishLoadingClangModule(
12941288
return result;
12951289
}
12961290

1291+
// Run through the set of deferred imports -- either those referenced by
1292+
// submodule ID from a bridging PCH, or those already loaded as clang::Modules
1293+
// in response to an import directive in a bridging header -- and call
1294+
// finishLoadingClangModule on each.
1295+
void ClangImporter::Implementation::handleDeferredImports()
1296+
{
1297+
clang::ASTReader &R = *Instance->getModuleManager();
1298+
for (clang::serialization::SubmoduleID ID : PCHImportedSubmodules) {
1299+
DeferredHeaderImports.push_back(R.getSubmodule(ID));
1300+
}
1301+
PCHImportedSubmodules.clear();
1302+
for (const clang::Module *M : DeferredHeaderImports) {
1303+
ModuleDecl *nativeImported =
1304+
finishLoadingClangModule(M, /*preferAdapter=*/true);
1305+
ImportedHeaderExports.push_back({ /*filter=*/{}, nativeImported });
1306+
}
1307+
DeferredHeaderImports.clear();
1308+
}
1309+
12971310
ModuleDecl *ClangImporter::getImportedHeaderModule() const {
12981311
return Impl.ImportedHeaderUnit->getParentModule();
12991312
}
@@ -1381,7 +1394,6 @@ ClangImporter::Implementation::~Implementation() {
13811394
}
13821395

13831396
ClangModuleUnit *ClangImporter::Implementation::getWrapperForModule(
1384-
ClangImporter &importer,
13851397
const clang::Module *underlying) {
13861398
auto &cacheEntry = ModuleWrappers[underlying];
13871399
if (ClangModuleUnit *cached = cacheEntry.getPointer())
@@ -1393,7 +1405,7 @@ ClangModuleUnit *ClangImporter::Implementation::getWrapperForModule(
13931405
// Silence error messages about testably importing a Clang module.
13941406
wrapper->setTestingEnabled();
13951407

1396-
auto file = new (SwiftContext) ClangModuleUnit(*wrapper, importer,
1408+
auto file = new (SwiftContext) ClangModuleUnit(*wrapper, *this,
13971409
underlying);
13981410
wrapper->addFile(*file);
13991411
cacheEntry.setPointer(file);
@@ -1414,9 +1426,7 @@ ClangModuleUnit *ClangImporter::Implementation::getClangModuleForDecl(
14141426
// ClangModuleUnit.
14151427
auto *M = maybeModule.getValue()->getTopLevelModule();
14161428

1417-
auto &importer =
1418-
static_cast<ClangImporter &>(*SwiftContext.getClangModuleLoader());
1419-
return getWrapperForModule(importer, M);
1429+
return getWrapperForModule(M);
14201430
}
14211431

14221432
#pragma mark Source locations
@@ -1988,9 +1998,9 @@ void ClangModuleUnit::lookupVisibleDecls(ModuleDecl::AccessPathTy accessPath,
19881998
}
19891999

19902000
// Find the corresponding lookup table.
1991-
if (auto lookupTable = owner.Impl.findLookupTable(clangModule)) {
2001+
if (auto lookupTable = owner.findLookupTable(clangModule)) {
19922002
// Search it.
1993-
owner.Impl.lookupVisibleDecls(*lookupTable, *actualConsumer);
2003+
owner.lookupVisibleDecls(*lookupTable, *actualConsumer);
19942004
}
19952005
}
19962006

@@ -2021,14 +2031,14 @@ void ClangModuleUnit::getTopLevelDecls(SmallVectorImpl<Decl*> &results) const {
20212031
actualConsumer = &blacklistConsumer;
20222032

20232033
// Find the corresponding lookup table.
2024-
if (auto lookupTable = owner.Impl.findLookupTable(topLevelModule)) {
2034+
if (auto lookupTable = owner.findLookupTable(topLevelModule)) {
20252035
// Search it.
2026-
owner.Impl.lookupVisibleDecls(*lookupTable, *actualConsumer);
2036+
owner.lookupVisibleDecls(*lookupTable, *actualConsumer);
20272037

20282038
// Add the extensions produced by importing categories.
20292039
for (auto category : lookupTable->categories()) {
20302040
if (auto extension = cast_or_null<ExtensionDecl>(
2031-
owner.Impl.importDecl(category, owner.Impl.CurrentVersion)))
2041+
owner.importDecl(category, owner.CurrentVersion)))
20322042
results.push_back(extension);
20332043
}
20342044

@@ -2040,7 +2050,7 @@ void ClangModuleUnit::getTopLevelDecls(SmallVectorImpl<Decl*> &results) const {
20402050
for (auto entry : lookupTable->allGlobalsAsMembers()) {
20412051
auto decl = entry.get<clang::NamedDecl *>();
20422052
auto importedDecl =
2043-
owner.Impl.importDecl(decl, owner.Impl.CurrentVersion);
2053+
owner.importDecl(decl, owner.CurrentVersion);
20442054
if (!importedDecl) continue;
20452055

20462056
auto ext = dyn_cast<ExtensionDecl>(importedDecl->getDeclContext());
@@ -2125,9 +2135,9 @@ void ClangModuleUnit::lookupValue(ModuleDecl::AccessPathTy accessPath,
21252135
}
21262136

21272137
// Find the corresponding lookup table.
2128-
if (auto lookupTable = owner.Impl.findLookupTable(clangModule)) {
2138+
if (auto lookupTable = owner.findLookupTable(clangModule)) {
21292139
// Search it.
2130-
owner.Impl.lookupValue(*lookupTable, name, *consumer);
2140+
owner.lookupValue(*lookupTable, name, *consumer);
21312141
}
21322142
}
21332143

@@ -2265,9 +2275,9 @@ ClangModuleUnit::lookupClassMember(ModuleDecl::AccessPathTy accessPath,
22652275
VectorDeclConsumer consumer(results);
22662276

22672277
// Find the corresponding lookup table.
2268-
if (auto lookupTable = owner.Impl.findLookupTable(clangModule)) {
2278+
if (auto lookupTable = owner.findLookupTable(clangModule)) {
22692279
// Search it.
2270-
owner.Impl.lookupObjCMembers(*lookupTable, name, consumer);
2280+
owner.lookupObjCMembers(*lookupTable, name, consumer);
22712281
}
22722282
}
22732283

@@ -2278,9 +2288,9 @@ void ClangModuleUnit::lookupClassMembers(ModuleDecl::AccessPathTy accessPath,
22782288
return;
22792289

22802290
// Find the corresponding lookup table.
2281-
if (auto lookupTable = owner.Impl.findLookupTable(clangModule)) {
2291+
if (auto lookupTable = owner.findLookupTable(clangModule)) {
22822292
// Search it.
2283-
owner.Impl.lookupAllObjCMembers(*lookupTable, consumer);
2293+
owner.lookupAllObjCMembers(*lookupTable, consumer);
22842294
}
22852295
}
22862296

@@ -2292,12 +2302,12 @@ void ClangModuleUnit::lookupObjCMethods(
22922302
return;
22932303

22942304
// Map the selector into a Clang selector.
2295-
auto clangSelector = owner.Impl.exportSelector(selector);
2305+
auto clangSelector = owner.exportSelector(selector);
22962306
if (clangSelector.isNull()) return;
22972307

22982308
// Collect all of the Objective-C methods with this selector.
22992309
SmallVector<clang::ObjCMethodDecl *, 8> objcMethods;
2300-
auto &clangSema = owner.Impl.getClangSema();
2310+
auto &clangSema = owner.getClangSema();
23012311
clangSema.CollectMultipleMethodsInGlobalPool(clangSelector,
23022312
objcMethods,
23032313
/*InstanceFirst=*/true,
@@ -2319,23 +2329,23 @@ void ClangModuleUnit::lookupObjCMethods(
23192329

23202330
// If we found a property accessor, import the property.
23212331
if (objcMethod->isPropertyAccessor())
2322-
(void)owner.Impl.importDecl(objcMethod->findPropertyDecl(true),
2323-
owner.Impl.CurrentVersion);
2332+
(void)owner.importDecl(objcMethod->findPropertyDecl(true),
2333+
owner.CurrentVersion);
23242334

23252335
// Import it.
23262336
// FIXME: Retrying a failed import works around recursion bugs in the Clang
23272337
// importer.
23282338
auto imported =
2329-
owner.Impl.importDecl(objcMethod, owner.Impl.CurrentVersion);
2339+
owner.importDecl(objcMethod, owner.CurrentVersion);
23302340
if (!imported)
2331-
imported = owner.Impl.importDecl(objcMethod, owner.Impl.CurrentVersion);
2341+
imported = owner.importDecl(objcMethod, owner.CurrentVersion);
23322342
if (!imported) continue;
23332343

23342344
if (auto func = dyn_cast<AbstractFunctionDecl>(imported))
23352345
results.push_back(func);
23362346

23372347
// If there is an alternate declaration, also look at it.
2338-
for (auto alternate : owner.Impl.getAlternateDecls(imported)) {
2348+
for (auto alternate : owner.getAlternateDecls(imported)) {
23392349
if (auto func = dyn_cast<AbstractFunctionDecl>(alternate))
23402350
results.push_back(func);
23412351
}
@@ -2435,7 +2445,8 @@ void ClangImporter::verifyAllModules() {
24352445
// ClangModule Implementation
24362446
//===----------------------------------------------------------------------===//
24372447

2438-
ClangModuleUnit::ClangModuleUnit(ModuleDecl &M, ClangImporter &owner,
2448+
ClangModuleUnit::ClangModuleUnit(ModuleDecl &M,
2449+
ClangImporter::Implementation &owner,
24392450
const clang::Module *clangModule)
24402451
: LoadedFile(FileUnitKind::ClangModule, M), owner(owner),
24412452
clangModule(clangModule) {
@@ -2468,7 +2479,7 @@ ModuleDecl *ClangModuleUnit::getAdapterModule() const {
24682479
if (!isTopLevel()) {
24692480
// FIXME: Is this correct for submodules?
24702481
auto topLevel = clangModule->getTopLevelModule();
2471-
auto wrapper = owner.Impl.getWrapperForModule(owner, topLevel);
2482+
auto wrapper = owner.getWrapperForModule(topLevel);
24722483
return wrapper->getAdapterModule();
24732484
}
24742485

@@ -2504,8 +2515,8 @@ void ClangModuleUnit::getImportedModules(
25042515
if (!clangModule) {
25052516
// This is the special "imported headers" module.
25062517
if (filter != ModuleDecl::ImportFilter::Private) {
2507-
imports.append(owner.Impl.ImportedHeaderExports.begin(),
2508-
owner.Impl.ImportedHeaderExports.end());
2518+
imports.append(owner.ImportedHeaderExports.begin(),
2519+
owner.ImportedHeaderExports.end());
25092520
}
25102521
return;
25112522
}
@@ -2541,7 +2552,7 @@ void ClangModuleUnit::getImportedModules(
25412552
}
25422553

25432554
for (auto importMod : imported) {
2544-
auto wrapper = owner.Impl.getWrapperForModule(owner, importMod);
2555+
auto wrapper = owner.getWrapperForModule(importMod);
25452556

25462557
auto actualMod = wrapper->getAdapterModule();
25472558
if (!actualMod) {
@@ -2550,8 +2561,7 @@ void ClangModuleUnit::getImportedModules(
25502561
auto importTopLevel = importMod->getTopLevelModule();
25512562
if (importTopLevel != importMod &&
25522563
importTopLevel != clangModule->getTopLevelModule()) {
2553-
auto topLevelWrapper = owner.Impl.getWrapperForModule(owner,
2554-
importTopLevel);
2564+
auto topLevelWrapper = owner.getWrapperForModule(importTopLevel);
25552565
imports.push_back({ ModuleDecl::AccessPathTy(),
25562566
topLevelWrapper->getParentModule() });
25572567
}
@@ -2570,8 +2580,8 @@ void ClangModuleUnit::getImportedModulesForLookup(
25702580

25712581
if (!clangModule) {
25722582
// This is the special "imported headers" module.
2573-
imports.append(owner.Impl.ImportedHeaderExports.begin(),
2574-
owner.Impl.ImportedHeaderExports.end());
2583+
imports.append(owner.ImportedHeaderExports.begin(),
2584+
owner.ImportedHeaderExports.end());
25752585
return;
25762586
}
25772587

@@ -2608,7 +2618,7 @@ void ClangModuleUnit::getImportedModulesForLookup(
26082618

26092619
// Don't continue looking through submodules of modules that have
26102620
// overlays. The overlay might shadow things.
2611-
auto wrapper = owner.Impl.getWrapperForModule(owner, nextTopLevel);
2621+
auto wrapper = owner.getWrapperForModule(nextTopLevel);
26122622
if (wrapper->getAdapterModule())
26132623
continue;
26142624
}
@@ -2626,7 +2636,7 @@ void ClangModuleUnit::getImportedModulesForLookup(
26262636
}
26272637

26282638
for (auto importMod : topLevelImported) {
2629-
auto wrapper = owner.Impl.getWrapperForModule(owner, importMod);
2639+
auto wrapper = owner.getWrapperForModule(importMod);
26302640

26312641
auto actualMod = wrapper->getAdapterModule();
26322642
if (!actualMod || actualMod == topLevelAdapter)

lib/ClangImporter/ImportMacro.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,7 @@ ClangModuleUnit *ClangImporter::Implementation::getClangModuleForMacro(
5151
// ClangModule.
5252
auto *M = maybeModule.getValue()->getTopLevelModule();
5353

54-
auto &importer =
55-
static_cast<ClangImporter &>(*SwiftContext.getClangModuleLoader());
56-
return getWrapperForModule(importer, M);
54+
return getWrapperForModule(M);
5755
}
5856

5957
template <typename T = clang::Expr>

0 commit comments

Comments
 (0)