Skip to content

Commit 1f4ce61

Browse files
committed
[NFC] [cxx-interop] Consolidate uses of findOptionSetType() helper function
Also renames it to findOptionSetEnum() to make it a bit clearer at face value that the returned ImportedType will contain a Swift enum. Also refactors some nearby instances of if (auto e = dyn_cast<ElaboratedType>(t)) t = e->desugar(); into a helper function, desugarIfElaborated(). (cherry picked from commit c7070e7)
1 parent ee3aca2 commit 1f4ce61

File tree

4 files changed

+49
-121
lines changed

4 files changed

+49
-121
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -846,13 +846,9 @@ static bool isPrintLikeMethod(DeclName name, const DeclContext *dc) {
846846
using MirroredMethodEntry =
847847
std::tuple<const clang::ObjCMethodDecl*, ProtocolDecl*, bool /*isAsync*/>;
848848

849-
ImportedType findOptionSetType(clang::QualType type,
850-
ClangImporter::Implementation &Impl) {
851-
ImportedType importedType;
852-
auto fieldType = type;
853-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(fieldType))
854-
fieldType = elaborated->desugar();
855-
if (auto typedefType = dyn_cast<clang::TypedefType>(fieldType)) {
849+
ImportedType importer::findOptionSetEnum(clang::QualType type,
850+
ClangImporter::Implementation &Impl) {
851+
if (auto typedefType = dyn_cast<clang::TypedefType>(type)) {
856852
if (Impl.isUnavailableInSwift(typedefType->getDecl())) {
857853
if (auto clangEnum =
858854
findAnonymousEnumForTypedef(Impl.SwiftContext, typedefType)) {
@@ -862,13 +858,12 @@ ImportedType findOptionSetType(clang::QualType type,
862858
clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
863859
typedefType->getCanonicalTypeInternal());
864860
if (auto swiftEnum = Impl.importDecl(*clangEnum, Impl.CurrentVersion)) {
865-
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(),
866-
false};
861+
return {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(), false};
867862
}
868863
}
869864
}
870865
}
871-
return importedType;
866+
return {};
872867
}
873868

874869
static bool areRecordFieldsComplete(const clang::CXXRecordDecl *decl) {
@@ -4540,8 +4535,8 @@ namespace {
45404535
return nullptr;
45414536
}
45424537

4543-
auto fieldType = decl->getType();
4544-
ImportedType importedType = findOptionSetType(fieldType, Impl);
4538+
auto fieldType = desugarIfElaborated(decl->getType());
4539+
ImportedType importedType = importer::findOptionSetEnum(fieldType, Impl);
45454540

45464541
if (!importedType)
45474542
importedType =
@@ -6133,8 +6128,8 @@ namespace {
61336128
}
61346129
}
61356130

6136-
auto fieldType = decl->getType();
6137-
ImportedType importedType = findOptionSetType(fieldType, Impl);
6131+
auto fieldType = desugarIfElaborated(decl->getType());
6132+
ImportedType importedType = importer::findOptionSetEnum(fieldType, Impl);
61386133

61396134
if (!importedType)
61406135
importedType = Impl.importPropertyType(decl, isInSystemModule(dc));
@@ -7098,8 +7093,7 @@ SwiftDeclConverter::getImplicitProperty(ImportedName importedName,
70987093
getAccessorPropertyType(getter, false, getterName.getSelfIndex());
70997094
if (propertyType.isNull())
71007095
return nullptr;
7101-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(propertyType))
7102-
propertyType = elaborated->desugar();
7096+
propertyType = desugarIfElaborated(propertyType);
71037097

71047098
// If there is a setter, check that the property it implies
71057099
// matches that of the getter.
@@ -7125,24 +7119,7 @@ SwiftDeclConverter::getImplicitProperty(ImportedName importedName,
71257119
if (dc->isTypeContext() && !getterName.getSelfIndex())
71267120
isStatic = true;
71277121

7128-
ImportedType importedType;
7129-
7130-
// Sometimes we import unavailable typedefs as enums. If that's the case,
7131-
// use the enum, not the typedef here.
7132-
if (auto typedefType = dyn_cast<clang::TypedefType>(propertyType.getTypePtr())) {
7133-
if (Impl.isUnavailableInSwift(typedefType->getDecl())) {
7134-
if (auto clangEnum = findAnonymousEnumForTypedef(Impl.SwiftContext, typedefType)) {
7135-
// If this fails, it means that we need a stronger predicate for
7136-
// determining the relationship between an enum and typedef.
7137-
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
7138-
typedefType->getCanonicalTypeInternal());
7139-
if (auto swiftEnum = Impl.importDecl(*clangEnum, Impl.CurrentVersion)) {
7140-
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(),
7141-
false};
7142-
}
7143-
}
7144-
}
7145-
}
7122+
ImportedType importedType = importer::findOptionSetEnum(propertyType, Impl);
71467123

71477124
if (!importedType) {
71487125
// Compute the property type.

lib/ClangImporter/ImportEnumInfo.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,10 +244,7 @@ StringRef importer::getCommonPluralPrefix(StringRef singular,
244244
}
245245

246246
const clang::Type *importer::getUnderlyingType(const clang::EnumDecl *decl) {
247-
const clang::Type *underlyingType = decl->getIntegerType().getTypePtr();
248-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(underlyingType))
249-
underlyingType = elaborated->desugar().getTypePtr();
250-
return underlyingType;
247+
return importer::desugarIfElaborated(decl->getIntegerType().getTypePtr());
251248
}
252249

253250
/// Determine the prefix to be stripped from the names of the enum constants

lib/ClangImporter/ImportType.cpp

Lines changed: 16 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -2255,10 +2255,7 @@ ImportedType ClangImporter::Implementation::importFunctionReturnType(
22552255
OptionalityOfReturn = OTK_ImplicitlyUnwrappedOptional;
22562256
}
22572257

2258-
clang::QualType returnType = clangDecl->getReturnType();
2259-
if (auto elaborated =
2260-
dyn_cast<clang::ElaboratedType>(returnType))
2261-
returnType = elaborated->desugar();
2258+
clang::QualType returnType = desugarIfElaborated(clangDecl->getReturnType());
22622259
// In C interop mode, the return type of library builtin functions
22632260
// like 'memcpy' from headers like 'string.h' drops
22642261
// any nullability specifiers from their return type, and preserves it on the
@@ -2296,19 +2293,9 @@ ImportedType ClangImporter::Implementation::importFunctionReturnType(
22962293
->isTemplateTypeParmType())
22972294
OptionalityOfReturn = OTK_None;
22982295

2299-
if (auto typedefType = dyn_cast<clang::TypedefType>(returnType)) {
2300-
if (isUnavailableInSwift(typedefType->getDecl())) {
2301-
if (auto clangEnum = findAnonymousEnumForTypedef(SwiftContext, typedefType)) {
2302-
// If this fails, it means that we need a stronger predicate for
2303-
// determining the relationship between an enum and typedef.
2304-
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
2305-
typedefType->getCanonicalTypeInternal());
2306-
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
2307-
return {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(), false};
2308-
}
2309-
}
2310-
}
2311-
}
2296+
ImportedType optionSetEnum = importer::findOptionSetEnum(returnType, *this);
2297+
if (optionSetEnum)
2298+
return optionSetEnum;
23122299

23132300
// Import the underlying result type.
23142301
if (clangDecl) {
@@ -2376,27 +2363,11 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
23762363

23772364
// Only eagerly import the return type if it's not too expensive (the current
23782365
// heuristic for that is if it's not a record type).
2379-
ImportedType importedType;
23802366
ImportDiagnosticAdder addDiag(*this, clangDecl,
23812367
clangDecl->getSourceRange().getBegin());
2382-
clang::QualType returnType = clangDecl->getReturnType();
2383-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(returnType))
2384-
returnType = elaborated->desugar();
2385-
2386-
if (auto typedefType = dyn_cast<clang::TypedefType>(returnType)) {
2387-
if (isUnavailableInSwift(typedefType->getDecl())) {
2388-
if (auto clangEnum = findAnonymousEnumForTypedef(SwiftContext, typedefType)) {
2389-
// If this fails, it means that we need a stronger predicate for
2390-
// determining the relationship between an enum and typedef.
2391-
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
2392-
typedefType->getCanonicalTypeInternal());
2393-
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
2394-
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(),
2395-
false};
2396-
}
2397-
}
2398-
}
2399-
}
2368+
clang::QualType returnType = desugarIfElaborated(clangDecl->getReturnType());
2369+
2370+
ImportedType importedType = importer::findOptionSetEnum(returnType, *this);
24002371

24012372
if (auto templateType =
24022373
dyn_cast<clang::TemplateTypeParmType>(returnType)) {
@@ -2460,9 +2431,7 @@ ClangImporter::Implementation::importParameterType(
24602431
std::optional<unsigned> completionHandlerErrorParamIndex,
24612432
ArrayRef<GenericTypeParamDecl *> genericParams,
24622433
llvm::function_ref<void(Diagnostic &&)> addImportDiagnosticFn) {
2463-
auto paramTy = param->getType();
2464-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(paramTy))
2465-
paramTy = elaborated->desugar();
2434+
auto paramTy = desugarIfElaborated(param->getType());
24662435

24672436
ImportTypeKind importKind = paramIsCompletionHandler
24682437
? ImportTypeKind::CompletionHandlerParameter
@@ -2475,23 +2444,8 @@ ClangImporter::Implementation::importParameterType(
24752444
bool isConsuming = false;
24762445
bool isParamTypeImplicitlyUnwrapped = false;
24772446

2478-
// Sometimes we import unavailable typedefs as enums. If that's the case,
2479-
// use the enum, not the typedef here.
2480-
if (auto typedefType = dyn_cast<clang::TypedefType>(paramTy.getTypePtr())) {
2481-
if (isUnavailableInSwift(typedefType->getDecl())) {
2482-
if (auto clangEnum =
2483-
findAnonymousEnumForTypedef(SwiftContext, typedefType)) {
2484-
// If this fails, it means that we need a stronger predicate for
2485-
// determining the relationship between an enum and typedef.
2486-
assert(clangEnum.value()
2487-
->getIntegerType()
2488-
->getCanonicalTypeInternal() ==
2489-
typedefType->getCanonicalTypeInternal());
2490-
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
2491-
swiftParamTy = cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType();
2492-
}
2493-
}
2494-
}
2447+
if (auto optionSetEnum = importer::findOptionSetEnum(paramTy, *this)) {
2448+
swiftParamTy = optionSetEnum.getType();
24952449
} else if (isa<clang::PointerType>(paramTy) &&
24962450
isa<clang::TemplateTypeParmType>(paramTy->getPointeeType())) {
24972451
auto pointeeType = paramTy->getPointeeType();
@@ -3211,26 +3165,8 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
32113165

32123166
ImportDiagnosticAdder addImportDiag(*this, clangDecl,
32133167
clangDecl->getLocation());
3214-
clang::QualType resultType = clangDecl->getReturnType();
3215-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(resultType))
3216-
resultType = elaborated->desugar();
3217-
3218-
ImportedType importedType;
3219-
if (auto typedefType = dyn_cast<clang::TypedefType>(resultType.getTypePtr())) {
3220-
if (isUnavailableInSwift(typedefType->getDecl())) {
3221-
if (auto clangEnum = findAnonymousEnumForTypedef(SwiftContext, typedefType)) {
3222-
// If this fails, it means that we need a stronger predicate for
3223-
// determining the relationship between an enum and typedef.
3224-
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
3225-
typedefType->getCanonicalTypeInternal());
3226-
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
3227-
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(),
3228-
false};
3229-
}
3230-
}
3231-
}
3232-
}
3233-
3168+
clang::QualType resultType = desugarIfElaborated(clangDecl->getReturnType());
3169+
ImportedType importedType = importer::findOptionSetEnum(resultType, *this);
32343170
if (!importedType)
32353171
importedType = importType(resultType, resultKind, addImportDiag,
32363172
allowNSUIntegerAsIntInResult, Bridgeability::Full,
@@ -3478,9 +3414,6 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
34783414
importedType.isImplicitlyUnwrapped()};
34793415
}
34803416

3481-
ImportedType findOptionSetType(clang::QualType type,
3482-
ClangImporter::Implementation &Impl);
3483-
34843417
ImportedType ClangImporter::Implementation::importAccessorParamsAndReturnType(
34853418
const DeclContext *dc, const clang::ObjCPropertyDecl *property,
34863419
const clang::ObjCMethodDecl *clangDecl, bool isFromSystemModule,
@@ -3506,11 +3439,11 @@ ImportedType ClangImporter::Implementation::importAccessorParamsAndReturnType(
35063439
if (!origDC)
35073440
return {Type(), false};
35083441

3509-
auto fieldType = isGetter ? clangDecl->getReturnType()
3510-
: clangDecl->getParamDecl(0)->getType();
3511-
3442+
auto fieldType =
3443+
desugarIfElaborated(isGetter ? clangDecl->getReturnType()
3444+
: clangDecl->getParamDecl(0)->getType());
35123445
// Import the property type, independent of what kind of accessor this is.
3513-
ImportedType importedType = findOptionSetType(fieldType, *this);
3446+
ImportedType importedType = importer::findOptionSetEnum(fieldType, *this);
35143447
if (!importedType)
35153448
importedType = importPropertyType(property, isFromSystemModule);
35163449
if (!importedType)

lib/ClangImporter/ImporterImpl.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2083,6 +2083,27 @@ bool hasEscapableAttr(const clang::RecordDecl *decl);
20832083

20842084
bool isViewType(const clang::CXXRecordDecl *decl);
20852085

2086+
inline const clang::Type *desugarIfElaborated(const clang::Type *type) {
2087+
if (auto elaborated = dyn_cast<clang::ElaboratedType>(type))
2088+
return elaborated->desugar().getTypePtr();
2089+
return type;
2090+
}
2091+
2092+
inline clang::QualType desugarIfElaborated(clang::QualType type) {
2093+
if (auto elaborated = dyn_cast<clang::ElaboratedType>(type))
2094+
return elaborated->desugar();
2095+
return type;
2096+
}
2097+
2098+
/// Option set enums are sometimes imported as typedefs which assign a name to
2099+
/// the type, but are unavailable in Swift.
2100+
///
2101+
/// If given such a typedef, this helper function retrieves and imports the
2102+
/// underlying enum type. Returns an empty ImportedType otherwise.
2103+
///
2104+
/// If \a type is an elaborated type, it should be desugared first.
2105+
ImportedType findOptionSetEnum(clang::QualType type,
2106+
ClangImporter::Implementation &Impl);
20862107
} // end namespace importer
20872108
} // end namespace swift
20882109

0 commit comments

Comments
 (0)