Skip to content

Commit f53bbc8

Browse files
committed
[Clang importer] Fix lookup of custom ref-counting ops in bridging headers
Lookup for custom reference counting operators into a precompiled bridging header was causing a crash because there is no "underlying module" in which to perform the lookup. Handle the lookup at the level of the main Swift module for such cases, filtering out declarations not coming from Clang. Fixes rdar://114495840.
1 parent 7544686 commit f53bbc8

File tree

2 files changed

+33
-3
lines changed

2 files changed

+33
-3
lines changed

lib/ClangImporter/ClangImporter.cpp

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "swift/AST/ImportCache.h"
3131
#include "swift/AST/LinkLibrary.h"
3232
#include "swift/AST/Module.h"
33+
#include "swift/AST/ModuleNameLookup.h"
3334
#include "swift/AST/NameLookup.h"
3435
#include "swift/AST/NameLookupRequests.h"
3536
#include "swift/AST/PrettyStackTrace.h"
@@ -6917,9 +6918,23 @@ CustomRefCountingOperationResult CustomRefCountingOperation::evaluate(
69176918
auto *clangMod = swiftDecl->getClangDecl()->getOwningModule();
69186919
if (clangMod && clangMod->isSubModule())
69196920
clangMod = clangMod->getTopLevelModule();
6920-
auto parentModule = ctx.getClangModuleLoader()->getWrapperForModule(clangMod);
6921-
ctx.lookupInModule(parentModule, name, results);
6922-
6921+
if (clangMod) {
6922+
auto parentModule = ctx.getClangModuleLoader()->getWrapperForModule(clangMod);
6923+
ctx.lookupInModule(parentModule, name, results);
6924+
} else {
6925+
// There is no Clang module for this declaration, so perform lookup from
6926+
// the main module. This will find declarations from the bridging header.
6927+
namelookup::lookupInModule(
6928+
ctx.MainModule, ctx.getIdentifier(name), results,
6929+
NLKind::UnqualifiedLookup, namelookup::ResolutionKind::Overloadable,
6930+
ctx.MainModule, SourceLoc(), NL_UnqualifiedDefault);
6931+
6932+
// Filter out any declarations that didn't come from Clang.
6933+
auto newEnd = std::remove_if(results.begin(), results.end(), [&](ValueDecl *decl) {
6934+
return !decl->getClangDecl();
6935+
});
6936+
results.erase(newEnd, results.end());
6937+
}
69236938
if (results.size() == 1)
69246939
return {CustomRefCountingOperationResult::foundOperation, results.front(),
69256940
name};

test/Interop/Cxx/ergonomics/swift-bridging-annotations.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,32 @@
11
// RUN: rm -rf %t
22
// RUN: split-file %s %t
3+
// RUN: mkdir -p %t/pch
34

45
// RUN: %target-swift-frontend %t/SwiftMod.swift -module-name SwiftMod -emit-module -o %t/SwiftMod.swiftmodule -I %t -enable-experimental-cxx-interop -Xcc -DFIRSTPASS
56

67
// RUN: %target-swift-ide-test -print-module -module-to-print=SwiftMod -module-to-print=CxxModule -I %t -I %t/Inputs -I %swift_src_root/lib/ClangImporter -source-filename=x -enable-experimental-cxx-interop | %FileCheck %s
78

89
// RUN: %target-swift-ide-test -print-module -module-to-print=SwiftMod -module-to-print=CxxModule -I %t -I %t/Inputs -I %swift_src_root/lib/ClangImporter -source-filename=x -enable-experimental-cxx-interop -Xcc -DINCMOD | %FileCheck %s
910

11+
// Test through the use of the bridging header
12+
// RUN: %target-swift-frontend -emit-ir -I %t -import-objc-header %t/Inputs/header.h -I %swift_src_root/lib/ClangImporter -enable-experimental-cxx-interop -DBRIDGING_HEADER_TEST -disable-availability-checking %t/SwiftMod.swift
13+
14+
// Precompile the bridging header and test the use of that.
15+
// RUN: %target-swift-frontend -emit-pch -I %t -pch-output-dir %t/pch %t/Inputs/header.h -I %swift_src_root/lib/ClangImporter -enable-experimental-cxx-interop
16+
// RUN: %target-swift-frontend -emit-ir -I %t -pch-output-dir %t/pch -import-objc-header %t/Inputs/header.h -I %swift_src_root/lib/ClangImporter -enable-experimental-cxx-interop -DBRIDGING_HEADER_TEST -disable-availability-checking %t/SwiftMod.swift
17+
18+
1019
//--- SwiftMod.swift
1120

1221
public protocol Proto {
1322
}
1423

24+
#if BRIDGING_HEADER_TEST
25+
func f() -> SharedObject { return SharedObject.create() }
26+
27+
func releaseSharedObject(_: SharedObject) { }
28+
#endif
29+
1530
//--- Inputs/module.modulemap
1631
module CxxModule {
1732
header "header.h"

0 commit comments

Comments
 (0)