Skip to content

Commit 9ccbca6

Browse files
committed
Revert "Revert "[cxx-interop] Import custom NS_OPTIONS correctly""
This reverts commit e1d70f0. (cherry picked from commit f7c2257)
1 parent bb0ff7f commit 9ccbca6

File tree

4 files changed

+41
-37
lines changed

4 files changed

+41
-37
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 24 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2642,44 +2642,31 @@ ArgumentAttrs ClangImporter::Implementation::inferDefaultArgument(
26422642
}
26432643
} else if (const clang::TypedefType *typedefType =
26442644
type->getAs<clang::TypedefType>()) {
2645-
// Get the AvailabilityAttr that would be set from CF/NS_OPTIONS
2646-
if (importer::isUnavailableInSwift(typedefType->getDecl(), nullptr, true)) {
2647-
// If we've taken this branch it means we have an enum type, and it is
2648-
// likely an integer or NSInteger that is being used by NS/CF_OPTIONS to
2649-
// behave like a C enum in the presence of C++.
2650-
auto enumName = typedefType->getDecl()->getName();
2651-
ArgumentAttrs argumentAttrs(DefaultArgumentKind::None, true, enumName);
2652-
auto camelCaseWords = camel_case::getWords(enumName);
2653-
for (auto it = camelCaseWords.rbegin(); it != camelCaseWords.rend();
2654-
++it) {
2655-
auto word = *it;
2656-
auto next = std::next(it);
2657-
if (camel_case::sameWordIgnoreFirstCase(word, "options")) {
2658-
argumentAttrs.argumentKind = DefaultArgumentKind::EmptyArray;
2659-
return argumentAttrs;
2645+
clang::TypedefNameDecl *typedefDecl = typedefType->getDecl();
2646+
// Find the next decl in the same context. If this typedef is a part of an
2647+
// NS/CF_OPTIONS declaration, the next decl will be an enum.
2648+
auto declsInContext = typedefDecl->getDeclContext()->decls();
2649+
auto declIter = llvm::find(declsInContext, typedefDecl);
2650+
if (declIter != declsInContext.end())
2651+
declIter++;
2652+
if (declIter != declsInContext.end()) {
2653+
if (auto enumDecl = dyn_cast<clang::EnumDecl>(*declIter)) {
2654+
if (auto cfOptionsTy =
2655+
nameImporter.getContext()
2656+
.getClangModuleLoader()
2657+
->getTypeDefForCXXCFOptionsDefinition(enumDecl)) {
2658+
if (cfOptionsTy->getDecl() == typedefDecl) {
2659+
auto enumName = typedefDecl->getName();
2660+
ArgumentAttrs argumentAttrs(DefaultArgumentKind::None, true,
2661+
enumName);
2662+
for (auto word : llvm::reverse(camel_case::getWords(enumName))) {
2663+
if (camel_case::sameWordIgnoreFirstCase(word, "options")) {
2664+
argumentAttrs.argumentKind = DefaultArgumentKind::EmptyArray;
2665+
}
2666+
}
2667+
return argumentAttrs;
2668+
}
26602669
}
2661-
if (camel_case::sameWordIgnoreFirstCase(word, "units"))
2662-
return argumentAttrs;
2663-
if (camel_case::sameWordIgnoreFirstCase(word, "domain"))
2664-
return argumentAttrs;
2665-
if (camel_case::sameWordIgnoreFirstCase(word, "action"))
2666-
return argumentAttrs;
2667-
if (camel_case::sameWordIgnoreFirstCase(word, "event"))
2668-
return argumentAttrs;
2669-
if (camel_case::sameWordIgnoreFirstCase(word, "events") &&
2670-
next != camelCaseWords.rend() &&
2671-
camel_case::sameWordIgnoreFirstCase(*next, "control"))
2672-
return argumentAttrs;
2673-
if (camel_case::sameWordIgnoreFirstCase(word, "state"))
2674-
return argumentAttrs;
2675-
if (camel_case::sameWordIgnoreFirstCase(word, "unit"))
2676-
return argumentAttrs;
2677-
if (camel_case::sameWordIgnoreFirstCase(word, "position") &&
2678-
next != camelCaseWords.rend() &&
2679-
camel_case::sameWordIgnoreFirstCase(*next, "scroll"))
2680-
return argumentAttrs;
2681-
if (camel_case::sameWordIgnoreFirstCase(word, "edge"))
2682-
return argumentAttrs;
26832670
}
26842671
}
26852672
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#include "CFOptions.h"
2+
3+
typedef CF_OPTIONS(unsigned, MyControlFlags) {
4+
MyControlFlagsNone = 0,
5+
MyControlFlagsFirst
6+
};

test/Interop/Cxx/objc-correctness/Inputs/module.modulemap

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@ module CxxClassWithNSStringInit {
99
requires cplusplus
1010
}
1111

12+
module CustomNSOptions {
13+
header "customNSOptions.h"
14+
}
15+
1216
module NSOptionsMangling {
1317
header "NSOptionsMangling.h"
1418
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// RUN: %target-typecheck-verify-swift -verify-ignore-unknown -I %S/Inputs -enable-objc-interop -enable-experimental-cxx-interop
2+
// REQUIRES: objc_interop
3+
4+
import CustomNSOptions
5+
6+
let flags1: MyControlFlags = []
7+
let flags2: MyControlFlags = [.first]

0 commit comments

Comments
 (0)