Skip to content

Commit d65115d

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 d65115d

File tree

1 file changed

+29
-16
lines changed

1 file changed

+29
-16
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -3625,6 +3625,34 @@ namespace {
36253625
return method;
36263626
}
36273627

3628+
ImportedType
3629+
tryImportOptionsTypeForField(const clang::QualType type,
3630+
ClangImporter::Implementation &Impl) {
3631+
ImportedType importedType;
3632+
auto fieldType = type;
3633+
if (auto elaborated = dyn_cast<clang::ElaboratedType>(fieldType))
3634+
fieldType = elaborated->desugar();
3635+
if (auto typedefType = dyn_cast<clang::TypedefType>(fieldType)) {
3636+
if (Impl.isUnavailableInSwift(typedefType->getDecl())) {
3637+
if (auto clangEnum =
3638+
findAnonymousEnumForTypedef(Impl.SwiftContext, typedefType)) {
3639+
// If this fails, it means that we need a stronger predicate for
3640+
// determining the relationship between an enum and typedef.
3641+
assert(clangEnum.value()
3642+
->getIntegerType()
3643+
->getCanonicalTypeInternal() ==
3644+
typedefType->getCanonicalTypeInternal());
3645+
if (auto swiftEnum =
3646+
Impl.importDecl(*clangEnum, Impl.CurrentVersion)) {
3647+
importedType = {
3648+
cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(), false};
3649+
}
3650+
}
3651+
}
3652+
}
3653+
return importedType;
3654+
}
3655+
36283656
Decl *VisitFieldDecl(const clang::FieldDecl *decl) {
36293657
// Fields are imported as variables.
36303658
llvm::Optional<ImportedName> correctSwiftName;
@@ -3663,23 +3691,8 @@ namespace {
36633691
return nullptr;
36643692
}
36653693

3666-
ImportedType importedType;
36673694
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-
}
3695+
ImportedType importedType = tryImportOptionsTypeForField(fieldType, Impl);
36833696

36843697
if (!importedType)
36853698
importedType =

0 commit comments

Comments
 (0)