Skip to content

Commit 8b0b1bf

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 339d31f commit 8b0b1bf

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"
@@ -6981,9 +6982,23 @@ CustomRefCountingOperationResult CustomRefCountingOperation::evaluate(
69816982
auto *clangMod = swiftDecl->getClangDecl()->getOwningModule();
69826983
if (clangMod && clangMod->isSubModule())
69836984
clangMod = clangMod->getTopLevelModule();
6984-
auto parentModule = ctx.getClangModuleLoader()->getWrapperForModule(clangMod);
6985-
ctx.lookupInModule(parentModule, name, results);
6986-
6985+
if (clangMod) {
6986+
auto parentModule = ctx.getClangModuleLoader()->getWrapperForModule(clangMod);
6987+
ctx.lookupInModule(parentModule, name, results);
6988+
} else {
6989+
// There is no Clang module for this declaration, so perform lookup from
6990+
// the main module. This will find declarations from the bridging header.
6991+
namelookup::lookupInModule(
6992+
ctx.MainModule, ctx.getIdentifier(name), results,
6993+
NLKind::UnqualifiedLookup, namelookup::ResolutionKind::Overloadable,
6994+
ctx.MainModule, SourceLoc(), NL_UnqualifiedDefault);
6995+
6996+
// Filter out any declarations that didn't come from Clang.
6997+
auto newEnd = std::remove_if(results.begin(), results.end(), [&](ValueDecl *decl) {
6998+
return !decl->getClangDecl();
6999+
});
7000+
results.erase(newEnd, results.end());
7001+
}
69877002
if (results.size() == 1)
69887003
return {CustomRefCountingOperationResult::foundOperation, results.front(),
69897004
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)