Skip to content

Commit ba232be

Browse files
committed
Fix effective context construction for NS_OPTIONS in linkage spec
When the ClangImporter imports a name, it associates it with a an EffectiveClangContext. An EffectiveClangContext can be thought of as the Clang scope the declaration will reside in, as far as importing into Swift is concerned. This helps API notes and NS_SWIFT_NAME to manipulate the SDK interface presented to Swift users. When a entry is added to the Swift lookup table, it is associated with a context. This context is a type and a name, used to effectively namespace entries in the table. This context is derived from the EffectiveClangContext associated with the name. This translation is handled by SwiftLookupTable::translateContextDecl among other machinery. This method in particular, understands only how to translate a set of Clang nodes, and fails to create a context in other cases. Prior to this patch, the EffectiveClangContext of declarations annotated with UIKIT_EXTERN, with cxx-interop turned on, was a LinkageSpecDecl. This results in context translation failure, and warnings produced in SwiftLookupTable::finalizeLookupTable. This patch corrects name import behavior to skip over the LinkageSpecDecl, and use the enclosing TranslationUnit instead. This is appropriate and performed by `determineEffectiveContext` as a LinkageSpecDecl is a so called "transparent" context. That is its members are semantically declared and accessible outside the context without additional qualification. This patch tests using API notes, as that is the method UIKit uses. The issue could just as easily be surface with a NS_SWIFT_NAME annotation. Even without any annotation at all, the we would still fail to translate, though there would likely be no corresponding warnings.
1 parent 1f3e159 commit ba232be

File tree

4 files changed

+40
-1
lines changed

4 files changed

+40
-1
lines changed

lib/ClangImporter/ImportName.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1811,7 +1811,8 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
18111811
}
18121812

18131813
result.setDeclName(swiftCtx.getIdentifier(baseName));
1814-
result.setEffectiveContext(D->getDeclContext());
1814+
result.setEffectiveContext(
1815+
determineEffectiveContext(D, D->getDeclContext(), version));
18151816
return result;
18161817
}
18171818
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
Name: CenumsNSOptions
2+
Tags:
3+
- Name: UIPrinterJobTypes
4+
SwiftName: UIPrinter.JobTypes
5+
SwiftVersions:
6+
- Version: 4
7+
Tags:
8+
- Name: UIPrinterJobTypes
9+
SwiftName: UIPrinterJobTypes
10+

test/Interop/Cxx/enum/Inputs/c-enums-NS_OPTIONS.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ extern "C" {
1818
#define CF_OPTIONS(_type, _name) _type __attribute__((availability(swift, unavailable))) _name; enum __CF_OPTIONS_ATTRIBUTES : _name
1919
#define NS_OPTIONS(_type, _name) CF_OPTIONS(_type, _name)
2020
#define NS_REFINED_FOR_SWIFT __attribute__((swift_private))
21+
#define UIKIT_EXTERN extern "C" __attribute__((visibility("default")))
2122

2223
typedef unsigned long NSUInteger;
24+
typedef long NSInteger;
2325

2426
typedef NS_OPTIONS(NSUInteger, NSBinarySearchingOptions) {
2527
NSBinarySearchingFirstEqual = (1UL << 8),
@@ -38,5 +40,21 @@ typedef NS_OPTIONS(NSUInteger, NSAttributedStringFormattingOptions) {
3840
@interface NSAttributedString (NSAttributedStringFormatting)
3941
- (instancetype)initWithOptions:(NSAttributedStringFormattingOptions)options
4042
NS_REFINED_FOR_SWIFT;
43+
44+
UIKIT_EXTERN
45+
@interface UIPrinter
46+
47+
typedef NS_OPTIONS(NSInteger, UIPrinterJobTypes) {
48+
UIPrinterJobTypeUnknown = 0,
49+
UIPrinterJobTypeDocument = 1 << 0,
50+
UIPrinterJobTypeEnvelope = 1 << 1,
51+
UIPrinterJobTypeLabel = 1 << 2,
52+
UIPrinterJobTypePhoto = 1 << 3,
53+
UIPrinterJobTypeReceipt = 1 << 4,
54+
UIPrinterJobTypeRoll = 1 << 5,
55+
UIPrinterJobTypeLargeFormat = 1 << 6,
56+
UIPrinterJobTypePostcard = 1 << 7
57+
};
58+
4159
@end
4260
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %empty-directory(%t/cache)
2+
// RUN: %target-swift-frontend %s -swift-version 5 -I %S/Inputs -typecheck -module-cache-path %t/cache -enable-cxx-interop 2>&1 | %FileCheck --allow-empty %s
3+
4+
// REQUIRES: objc_interop
5+
6+
import CenumsNSOptions
7+
8+
// CHECK-NOT: warning: imported declaration '' could not be mapped to 'UIPrinter.JobTypes'
9+
// CHECK-NOT: note: please report this issue to the owners of 'CenumsNSOptions'
10+

0 commit comments

Comments
 (0)