Skip to content

Commit e5c5c6e

Browse files
committed
[ClangImporter] Add clang module imports to Swift wrapper module
When macros like _SwiftifyImport are added to a wrapper module for a clang module, they may need to refer to symbols declared in another clang module that the wrapped module imports (e.g. because they are used in the original signature). This adds all the imported clang modules as implicit imports to the wrapper module. rdar://151611573
1 parent cb3293b commit e5c5c6e

File tree

14 files changed

+195
-11
lines changed

14 files changed

+195
-11
lines changed

include/swift/Subsystems.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,9 +125,7 @@ namespace swift {
125125

126126
/// Resolve imports for a source file generated to adapt a given
127127
/// Clang module.
128-
void performImportResolutionForClangMacroBuffer(
129-
SourceFile &SF, ModuleDecl *clangModule
130-
);
128+
void performImportResolutionForClangMacroBuffer(SourceFile &SF);
131129

132130
/// Once type-checking is complete, this instruments code with calls to an
133131
/// intrinsic that record the expected values of local variables so they can

lib/ClangImporter/ClangImporter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2829,6 +2829,14 @@ ClangModuleUnit *ClangImporter::Implementation::getWrapperForModule(
28292829
if (auto mainModule = SwiftContext.MainModule) {
28302830
implicitImportInfo = mainModule->getImplicitImportInfo();
28312831
}
2832+
for (auto *I : underlying->Imports) {
2833+
// Make sure that synthesized Swift code in the clang module wrapper
2834+
// (e.g. _SwiftifyImport macro expansions) can access the same symbols as
2835+
// if it were actually in the clang module
2836+
ImportPath::Builder importPath(SwiftContext, I->getFullModuleName(), '.');
2837+
UnloadedImportedModule importedModule(importPath.copyTo(SwiftContext), ImportKind::Module);
2838+
implicitImportInfo.AdditionalUnloadedImports.push_back(importedModule);
2839+
}
28322840
ClangModuleUnit *file = nullptr;
28332841
auto wrapper = ModuleDecl::create(name, SwiftContext, implicitImportInfo,
28342842
[&](ModuleDecl *wrapper, auto addFile) {

lib/Sema/ImportResolution.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -319,15 +319,14 @@ void swift::performImportResolution(SourceFile &SF) {
319319
verify(SF);
320320
}
321321

322-
void swift::performImportResolutionForClangMacroBuffer(
323-
SourceFile &SF, ModuleDecl *clangModule
324-
) {
322+
void swift::performImportResolutionForClangMacroBuffer(SourceFile &SF) {
325323
// If we've already performed import resolution, bail.
326324
if (SF.ASTStage == SourceFile::ImportsResolved)
327325
return;
328326

327+
// `getWrapperForModule` has already declared all the implicit clang module
328+
// imports we need
329329
ImportResolver resolver(SF);
330-
resolver.addImplicitImport(clangModule);
331330

332331
// FIXME: This is a hack that we shouldn't need, but be sure that we can
333332
// see the Swift standard library.

lib/Sema/TypeCheckMacros.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1059,10 +1059,8 @@ createMacroSourceFile(std::unique_ptr<llvm::MemoryBuffer> buffer,
10591059
/*parsingOpts=*/{}, /*isPrimary=*/false);
10601060
if (auto parentSourceFile = dc->getParentSourceFile())
10611061
macroSourceFile->setImports(parentSourceFile->getImports());
1062-
else if (auto clangModuleUnit =
1063-
dyn_cast<ClangModuleUnit>(dc->getModuleScopeContext())) {
1064-
auto clangModule = clangModuleUnit->getParentModule();
1065-
performImportResolutionForClangMacroBuffer(*macroSourceFile, clangModule);
1062+
else if (isa<ClangModuleUnit>(dc->getModuleScopeContext())) {
1063+
performImportResolutionForClangMacroBuffer(*macroSourceFile);
10661064
}
10671065
return macroSourceFile;
10681066
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#pragma once
2+
3+
typedef int a_t;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#pragma once
2+
3+
typedef int b_t;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#pragma once
2+
typedef int c_t;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#pragma once
2+
typedef int d_t;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#pragma once
2+
typedef int e_t;
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
module ModuleA {
2+
header "module-a.h"
3+
export *
4+
}
5+
module ModuleB {
6+
header "module-b.h"
7+
}
8+
module ModuleOuter {
9+
module ModuleC {
10+
header "module-c.h"
11+
export *
12+
}
13+
explicit module ModuleD {
14+
header "module-d.h"
15+
export *
16+
}
17+
}
18+
module ModuleDeep {
19+
module ModuleDeepNested {
20+
module ModuleDeepNestedNested {
21+
header "module-e.h"
22+
}
23+
}
24+
}

0 commit comments

Comments
 (0)