Merge pull request #79890 from swiftlang/egorzhdan/nsoptions-name-based

[cxx-interop] Remove workarounds for `CF_OPTIONS` default arguments
This commit is contained in:
Egor Zhdan
2025-03-11 18:18:27 +00:00
committed by GitHub
4 changed files with 53 additions and 49 deletions

View File

@@ -163,6 +163,14 @@ StringRef getCommonPluralPrefix(StringRef singular, StringRef plural);
/// Returns the underlying integer type of an enum. If clang treats the type as
/// an elaborated type, an unwrapped type is returned.
const clang::Type *getUnderlyingType(const clang::EnumDecl *decl);
inline bool isCFOptionsMacro(StringRef macroName) {
return llvm::StringSwitch<bool>(macroName)
.Case("CF_OPTIONS", true)
.Case("NS_OPTIONS", true)
.Default(false);
}
}
}

View File

@@ -1875,7 +1875,7 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
if (loc.isMacroID()) {
StringRef macroName =
clangSema.getPreprocessor().getImmediateMacroName(loc);
if (macroName == "CF_OPTIONS" || macroName == "NS_OPTIONS")
if (isCFOptionsMacro(macroName))
return ImportedName();
}
}

View File

@@ -2919,42 +2919,24 @@ ArgumentAttrs ClangImporter::Implementation::inferDefaultArgument(
} else if (const clang::TypedefType *typedefType =
type->getAs<clang::TypedefType>()) {
// Get the AvailabilityAttr that would be set from CF/NS_OPTIONS
if (importer::isUnavailableInSwift(typedefType->getDecl(), nullptr, true)) {
auto typedefDecl = typedefType->getDecl();
if (importer::isUnavailableInSwift(typedefDecl, nullptr, true)) {
// If we've taken this branch it means we have an enum type, and it is
// likely an integer or NSInteger that is being used by NS/CF_OPTIONS to
// behave like a C enum in the presence of C++.
auto enumName = typedefType->getDecl()->getName();
auto enumName = typedefDecl->getName();
ArgumentAttrs argumentAttrs(DefaultArgumentKind::None, true, enumName);
auto camelCaseWords = camel_case::getWords(enumName);
for (auto it = camelCaseWords.rbegin(); it != camelCaseWords.rend();
++it) {
auto word = *it;
auto next = std::next(it);
for (auto word : llvm::reverse(camel_case::getWords(enumName))) {
if (camel_case::sameWordIgnoreFirstCase(word, "options")) {
argumentAttrs.argumentKind = DefaultArgumentKind::EmptyArray;
return argumentAttrs;
}
if (camel_case::sameWordIgnoreFirstCase(word, "units"))
return argumentAttrs;
if (camel_case::sameWordIgnoreFirstCase(word, "domain"))
return argumentAttrs;
if (camel_case::sameWordIgnoreFirstCase(word, "action"))
return argumentAttrs;
if (camel_case::sameWordIgnoreFirstCase(word, "event"))
return argumentAttrs;
if (camel_case::sameWordIgnoreFirstCase(word, "events") &&
next != camelCaseWords.rend() &&
camel_case::sameWordIgnoreFirstCase(*next, "control"))
return argumentAttrs;
if (camel_case::sameWordIgnoreFirstCase(word, "state"))
return argumentAttrs;
if (camel_case::sameWordIgnoreFirstCase(word, "unit"))
return argumentAttrs;
if (camel_case::sameWordIgnoreFirstCase(word, "position") &&
next != camelCaseWords.rend() &&
camel_case::sameWordIgnoreFirstCase(*next, "scroll"))
return argumentAttrs;
if (camel_case::sameWordIgnoreFirstCase(word, "edge"))
}
auto loc = typedefDecl->getEndLoc();
if (loc.isMacroID()) {
StringRef macroName =
nameImporter.getClangPreprocessor().getImmediateMacroName(loc);
if (isCFOptionsMacro(macroName))
return argumentAttrs;
}
}

View File

@@ -1,43 +1,57 @@
#include "CFAvailability.h"
typedef unsigned long NSUInteger;
// Enum usage that is bitwise-able and assignable in C++, aka how CF_OPTIONS
// does things.
typedef int __attribute__((availability(swift, unavailable))) NSEnumerationOptions;
enum : NSEnumerationOptions { NSEnumerationConcurrent, NSEnumerationReverse };
typedef CF_OPTIONS(NSUInteger, NSEnumerationOptions) {
NSEnumerationConcurrent = (1UL << 0),
NSEnumerationReverse = (1UL << 1),
};
@interface NSSet
- (void)enumerateObjectsWithOptions:(NSEnumerationOptions)opts ;
@end
typedef int __attribute__((availability(swift, unavailable))) NSOrderedCollectionDifferenceCalculationOptions;
enum : NSOrderedCollectionDifferenceCalculationOptions {
typedef CF_OPTIONS(NSUInteger, NSOrderedCollectionDifferenceCalculationOptions) {
NSOrderedCollectionDifferenceCalculationOptions1,
NSOrderedCollectionDifferenceCalculationOptions2
};
typedef int __attribute__((availability(swift, unavailable))) NSCalendarUnit;
enum : NSCalendarUnit { NSCalendarUnit1, NSCalendarUnit2 };
typedef CF_OPTIONS(NSUInteger, NSCalendarUnit) {
NSCalendarUnit1,
NSCalendarUnit2
};
typedef int __attribute__((availability(swift, unavailable))) NSSearchPathDomainMask;
enum : NSSearchPathDomainMask { NSSearchPathDomainMask1, NSSearchPathDomainMask2 };
typedef CF_OPTIONS(NSUInteger, NSSearchPathDomainMask) {
NSSearchPathDomainMask1,
NSSearchPathDomainMask2
};
typedef int __attribute__((availability(swift, unavailable))) NSControlCharacterAction;
enum : NSControlCharacterAction { NSControlCharacterAction1, NSControlCharacterAction2 };
typedef CF_OPTIONS(NSUInteger, NSControlCharacterAction) {
NSControlCharacterAction1,
NSControlCharacterAction2
};
typedef int __attribute__((availability(swift, unavailable))) UIControlState;
enum : UIControlState { UIControlState1, UIControlState2 };
typedef CF_OPTIONS(NSUInteger, UIControlState) {
UIControlState1,
UIControlState2
};
typedef int __attribute__((availability(swift, unavailable))) UITableViewCellStateMask;
enum : UITableViewCellStateMask { UITableViewCellStateMask1, UITableViewCellStateMask2 };
typedef CF_OPTIONS(NSUInteger, UITableViewCellStateMask) {
UITableViewCellStateMask1,
UITableViewCellStateMask2
};
typedef int __attribute__((availability(swift, unavailable))) UIControlEvents;
enum : UIControlEvents { UIControlEvents1, UIControlEvents2 };
typedef CF_OPTIONS(NSUInteger, UIControlEvents) {
UIControlEvents1,
UIControlEvents2
};
typedef int __attribute__((availability(swift, unavailable)))
UITableViewScrollPosition;
enum : UITableViewScrollPosition {
typedef CF_OPTIONS(NSUInteger, UITableViewScrollPosition) {
UITableViewScrollPosition1,
UITableViewScrollPosition2
};
@interface NSIndexPath
@end