Skip to content

Commit 56e3a3b

Browse files
committed
[c++-interop] Teach APINotes to handle DeclContexts that are extern "C"
In order for APINotes to behave correctly in the presense of Swift's C++-Interop, it needs to not assume the top-level DeclContext of a file (ie isFileConext) is only either a TU-Decl or a Namespace: it can be a LinkageSpecDecl (ie an extern "C"). This change simply allows for APINotes do follow its usual behavior if the context of the Decl is within an extern "C". A real world application of this is something like NSURLSession which resides in a module.modulemap that has a leading `module Foundation [extern_c] {` and because of this all of the types inside have a LinkageSpecDecl context. When APINotes is unable to apply the mapping then a type like NSURLSession misses it's mapping to URLSession and everything that may refer to it in the module will fail to compile due to a missing type.
1 parent 7967957 commit 56e3a3b

File tree

5 files changed

+24
-1
lines changed

5 files changed

+24
-1
lines changed

clang/lib/Sema/SemaAPINotes.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,7 +810,8 @@ void Sema::ProcessAPINotes(Decl *D) {
810810
return;
811811

812812
// Globals.
813-
if (D->getDeclContext()->isFileContext()) {
813+
if (D->getDeclContext()->isFileContext() ||
814+
D->getDeclContext()->isExternCContext()) {
814815
// Global variables.
815816
if (auto VD = dyn_cast<VarDecl>(D)) {
816817
for (auto Reader : APINotes.findAPINotes(D->getLocation())) {
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
Name: CxxInterop
3+
Classes:
4+
- Name: NSSomeClass
5+
SwiftName: SomeClass
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@interface NSSomeClass
2+
-(instancetype)init;
3+
@end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
framework module CxxInteropKit [extern_c] {
2+
umbrella header "CxxInteropKit.h"
3+
export *
4+
module * { export * }
5+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: rm -rf %t && mkdir -p %t
2+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -x objective-c++
3+
// RUN: %clang_cc1 -fmodules -fblocks -fimplicit-module-maps -fmodules-cache-path=%t/ModulesCache/CxxInterop -fdisable-module-hash -fapinotes-modules -fsyntax-only -I %S/Inputs/Headers -F %S/Inputs/Frameworks %s -ast-dump -ast-dump-filter SomeClass -x objective-c++ | FileCheck %s
4+
5+
#import <CxxInteropKit/CxxInteropKit.h>
6+
7+
// CHECK: Dumping NSSomeClass:
8+
// CHECK-NEXT: ObjCInterfaceDecl {{.+}} imported in CxxInteropKit <undeserialized declarations> NSSomeClass
9+
// CHECK-NEXT: SwiftNameAttr {{.+}} <<invalid sloc>> "SomeClass"

0 commit comments

Comments
 (0)