diff --git a/include/swift/AST/ImportCache.h b/include/swift/AST/ImportCache.h index b60d8adf24f..2ac7c200146 100644 --- a/include/swift/AST/ImportCache.h +++ b/include/swift/AST/ImportCache.h @@ -53,10 +53,12 @@ class ImportSet final : friend TrailingObjects; friend ImportCache; - unsigned NumTopLevelImports; + unsigned HasHeaderImportModule : 1; + unsigned NumTopLevelImports : 31; unsigned NumTransitiveImports; - ImportSet(ArrayRef topLevelImports, + ImportSet(bool hasHeaderImportModule, + ArrayRef topLevelImports, ArrayRef transitiveImports); ImportSet(const ImportSet &) = delete; @@ -74,6 +76,13 @@ public: return NumTopLevelImports + NumTransitiveImports; } + /// This is a bit of a hack to make module name lookup work properly. + /// If our import set includes the ClangImporter's special header import + /// module, we have to check it first, before any other imported module. + bool hasHeaderImportModule() const { + return HasHeaderImportModule; + } + ArrayRef getTopLevelImports() const { return {getTrailingObjects(), NumTopLevelImports}; diff --git a/lib/AST/ImportCache.cpp b/lib/AST/ImportCache.cpp index 6762472fae4..65292efd2a1 100644 --- a/lib/AST/ImportCache.cpp +++ b/lib/AST/ImportCache.cpp @@ -23,9 +23,11 @@ using namespace swift; using namespace namelookup; -ImportSet::ImportSet(ArrayRef topLevelImports, +ImportSet::ImportSet(bool hasHeaderImportModule, + ArrayRef topLevelImports, ArrayRef transitiveImports) - : NumTopLevelImports(topLevelImports.size()), + : HasHeaderImportModule(hasHeaderImportModule), + NumTopLevelImports(topLevelImports.size()), NumTransitiveImports(transitiveImports.size()) { auto buffer = getTrailingObjects(); std::uninitialized_copy(topLevelImports.begin(), topLevelImports.end(), @@ -78,6 +80,11 @@ static void collectExports(ModuleDecl::ImportedModule next, ImportSet & ImportCache::getImportSet(ASTContext &ctx, ArrayRef imports) { + bool hasHeaderImportModule = false; + ModuleDecl *headerImportModule = nullptr; + if (auto *loader = ctx.getClangModuleLoader()) + headerImportModule = loader->getImportedHeaderModule(); + SmallVector topLevelImports; SmallVector transitiveImports; @@ -88,6 +95,8 @@ ImportCache::getImportSet(ASTContext &ctx, continue; topLevelImports.push_back(next); + if (next.second == headerImportModule) + hasHeaderImportModule = true; } void *InsertPos = nullptr; @@ -116,6 +125,9 @@ ImportCache::getImportSet(ASTContext &ctx, continue; transitiveImports.push_back(next); + if (next.second == headerImportModule) + hasHeaderImportModule = true; + collectExports(next, stack); } @@ -131,7 +143,9 @@ ImportCache::getImportSet(ASTContext &ctx, sizeof(ModuleDecl::ImportedModule) * transitiveImports.size(), alignof(ImportSet), AllocationArena::Permanent); - auto *result = new (mem) ImportSet(topLevelImports, transitiveImports); + auto *result = new (mem) ImportSet(hasHeaderImportModule, + topLevelImports, + transitiveImports); ImportSets.InsertNode(result, InsertPos); return *result;