Skip to content

Commit 52b91b1

Browse files
committed
[NFC][cxx-interop] Refactor NS_OPTION type import handling code to be reusable.
Zoe did a nice fix on #66452 that I would like to reuse for ObjCPropertyDecl field types in importObjCPropertyDecl as well. This will fix cases such as: ``` import UIKit func f(gesture: UISwipeGestureRecognizer, direction: UISwipeGestureRecognizer.Direction) { gesture.direction = direction // error } ``` because it will make sure the field inside class UIGestureRecognizer is of the enum-struct type and not the typedef-rawValue type when importing an ObjC class. (cherry picked from commit ec5b7b0)
1 parent 6f1cf76 commit 52b91b1

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 26 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -818,6 +818,31 @@ static bool isPrintLikeMethod(DeclName name, const DeclContext *dc) {
818818
using MirroredMethodEntry =
819819
std::tuple<const clang::ObjCMethodDecl*, ProtocolDecl*, bool /*isAsync*/>;
820820

821+
ImportedType tryImportOptionsTypeForField(const clang::QualType type,
822+
ClangImporter::Implementation &Impl) {
823+
ImportedType importedType;
824+
auto fieldType = type;
825+
if (auto elaborated = dyn_cast<clang::ElaboratedType>(fieldType))
826+
fieldType = elaborated->desugar();
827+
if (auto typedefType = dyn_cast<clang::TypedefType>(fieldType)) {
828+
if (Impl.isUnavailableInSwift(typedefType->getDecl())) {
829+
if (auto clangEnum =
830+
findAnonymousEnumForTypedef(Impl.SwiftContext, typedefType)) {
831+
// If this fails, it means that we need a stronger predicate for
832+
// determining the relationship between an enum and typedef.
833+
assert(
834+
clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
835+
typedefType->getCanonicalTypeInternal());
836+
if (auto swiftEnum = Impl.importDecl(*clangEnum, Impl.CurrentVersion)) {
837+
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(),
838+
false};
839+
}
840+
}
841+
}
842+
}
843+
return importedType;
844+
}
845+
821846
namespace {
822847
/// Customized llvm::DenseMapInfo for storing borrowed APSInts.
823848
struct APSIntRefDenseMapInfo {
@@ -3650,23 +3675,8 @@ namespace {
36503675
return nullptr;
36513676
}
36523677

3653-
ImportedType importedType;
36543678
auto fieldType = decl->getType();
3655-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(fieldType))
3656-
fieldType = elaborated->desugar();
3657-
if (auto typedefType = dyn_cast<clang::TypedefType>(fieldType)) {
3658-
if (Impl.isUnavailableInSwift(typedefType->getDecl())) {
3659-
if (auto clangEnum = findAnonymousEnumForTypedef(Impl.SwiftContext, typedefType)) {
3660-
// If this fails, it means that we need a stronger predicate for
3661-
// determining the relationship between an enum and typedef.
3662-
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
3663-
typedefType->getCanonicalTypeInternal());
3664-
if (auto swiftEnum = Impl.importDecl(*clangEnum, Impl.CurrentVersion)) {
3665-
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(), false};
3666-
}
3667-
}
3668-
}
3669-
}
3679+
ImportedType importedType = tryImportOptionsTypeForField(fieldType, Impl);
36703680

36713681
if (!importedType)
36723682
importedType =

0 commit comments

Comments
 (0)