Skip to content

Commit ab5fc57

Browse files
authored
Merge pull request #83568 from egorzhdan/egorzhdan/nsfunctionkeys-workaround
[cxx-interop] Allow old spelling of AppKit constants
2 parents fa05c1e + 37c4182 commit ab5fc57

File tree

4 files changed

+33
-1
lines changed

4 files changed

+33
-1
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8656,6 +8656,26 @@ bool importer::isSpecialUIKitStructZeroProperty(const clang::NamedDecl *decl) {
86568656
return ident->isStr("UIEdgeInsetsZero") || ident->isStr("UIOffsetZero");
86578657
}
86588658

8659+
bool importer::isSpecialAppKitFunctionKeyProperty(
8660+
const clang::NamedDecl *decl) {
8661+
auto constant = dyn_cast<clang::EnumConstantDecl>(decl);
8662+
if (!constant)
8663+
return false;
8664+
8665+
auto module = constant->getOwningModule();
8666+
if (!module || module->getTopLevelModuleName() != "AppKit")
8667+
return false;
8668+
8669+
clang::DeclarationName name = constant->getDeclName();
8670+
const clang::IdentifierInfo *ident = name.getAsIdentifierInfo();
8671+
if (!ident)
8672+
return false;
8673+
auto rawName = ident->getName();
8674+
8675+
return rawName.starts_with("NS") &&
8676+
(rawName.ends_with("FunctionKey") || rawName.ends_with("Character"));
8677+
}
8678+
86598679
bool importer::hasSameUnderlyingType(const clang::Type *a,
86608680
const clang::TemplateTypeParmDecl *b) {
86618681
while (a->isPointerType() || a->isReferenceType())

lib/ClangImporter/ImportName.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -646,9 +646,12 @@ findSwiftNameAttr(const clang::Decl *decl, ImportNameVersion version) {
646646
if (version > ImportNameVersion::swift2()) {
647647
// FIXME: Until Apple gets a chance to update UIKit's API notes, always use
648648
// the new name for certain properties.
649-
if (auto *namedDecl = dyn_cast<clang::NamedDecl>(decl))
649+
if (auto *namedDecl = dyn_cast<clang::NamedDecl>(decl)) {
650650
if (importer::isSpecialUIKitStructZeroProperty(namedDecl))
651651
version = ImportNameVersion::swift4_2();
652+
if (importer::isSpecialAppKitFunctionKeyProperty(namedDecl))
653+
return std::nullopt;
654+
}
652655

653656
// Dig out the attribute that specifies the Swift name.
654657
std::optional<AnySwiftNameAttr> activeAttr;

lib/ClangImporter/ImporterImpl.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1980,6 +1980,12 @@ bool shouldSuppressDeclImport(const clang::Decl *decl);
19801980
/// but are now renamed using the swift_name attribute.
19811981
bool isSpecialUIKitStructZeroProperty(const clang::NamedDecl *decl);
19821982

1983+
/// Identifies certain AppKit constants that have overlay equivalents but are
1984+
/// also annotated with SwiftName API Notes attributes at the same time. Older
1985+
/// Clang versions were silently dropping the API Notes attribute on those
1986+
/// constants.
1987+
bool isSpecialAppKitFunctionKeyProperty(const clang::NamedDecl *decl);
1988+
19831989
/// \returns true if \p a has the same underlying type as \p b after removing
19841990
/// any pointer/reference specifiers. Note that this does not currently look through
19851991
/// nested types other than pointers or references.

test/Interop/Cxx/objc-correctness/appkit-uikit.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ import AppKit
1111
var _: AttributeScopes.AppKitAttributes.UnderlineStyleAttribute! = nil
1212

1313
var _ = NSEvent.SpecialKey.upArrow.rawValue
14+
var _ = NSEvent.SpecialKey.enter.rawValue
15+
var _ = NSUpArrowFunctionKey
16+
var _ = NSEnterCharacter
1417

1518
#elseif canImport(UIKit)
1619
import UIKit

0 commit comments

Comments
 (0)