Skip to content

Commit ec5b7b0

Browse files
committed
[NFC][cxx-interop] Refactor NS_OPTION type import handling code to be reusable.
Zoe did a nice fix on swiftlang#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.
1 parent c50263c commit ec5b7b0

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
@@ -816,6 +816,31 @@ static bool isPrintLikeMethod(DeclName name, const DeclContext *dc) {
816816
using MirroredMethodEntry =
817817
std::tuple<const clang::ObjCMethodDecl*, ProtocolDecl*, bool /*isAsync*/>;
818818

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

3666-
ImportedType importedType;
36673691
auto fieldType = decl->getType();
3668-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(fieldType))
3669-
fieldType = elaborated->desugar();
3670-
if (auto typedefType = dyn_cast<clang::TypedefType>(fieldType)) {
3671-
if (Impl.isUnavailableInSwift(typedefType->getDecl())) {
3672-
if (auto clangEnum = findAnonymousEnumForTypedef(Impl.SwiftContext, typedefType)) {
3673-
// If this fails, it means that we need a stronger predicate for
3674-
// determining the relationship between an enum and typedef.
3675-
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
3676-
typedefType->getCanonicalTypeInternal());
3677-
if (auto swiftEnum = Impl.importDecl(*clangEnum, Impl.CurrentVersion)) {
3678-
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(), false};
3679-
}
3680-
}
3681-
}
3682-
}
3692+
ImportedType importedType = tryImportOptionsTypeForField(fieldType, Impl);
36833693

36843694
if (!importedType)
36853695
importedType =

0 commit comments

Comments
 (0)