Skip to content

Commit c7070e7

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().
1 parent 2eceb29 commit c7070e7

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
@@ -847,13 +847,9 @@ static bool isPrintLikeMethod(DeclName name, const DeclContext *dc) {
847847
using MirroredMethodEntry =
848848
std::tuple<const clang::ObjCMethodDecl*, ProtocolDecl*, bool /*isAsync*/>;
849849

850-
ImportedType findOptionSetType(clang::QualType type,
851-
ClangImporter::Implementation &Impl) {
852-
ImportedType importedType;
853-
auto fieldType = type;
854-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(fieldType))
855-
fieldType = elaborated->desugar();
856-
if (auto typedefType = dyn_cast<clang::TypedefType>(fieldType)) {
850+
ImportedType importer::findOptionSetEnum(clang::QualType type,
851+
ClangImporter::Implementation &Impl) {
852+
if (auto typedefType = dyn_cast<clang::TypedefType>(type)) {
857853
if (Impl.isUnavailableInSwift(typedefType->getDecl())) {
858854
if (auto clangEnum =
859855
findAnonymousEnumForTypedef(Impl.SwiftContext, typedefType)) {
@@ -863,13 +859,12 @@ ImportedType findOptionSetType(clang::QualType type,
863859
clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
864860
typedefType->getCanonicalTypeInternal());
865861
if (auto swiftEnum = Impl.importDecl(*clangEnum, Impl.CurrentVersion)) {
866-
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(),
867-
false};
862+
return {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(), false};
868863
}
869864
}
870865
}
871866
}
872-
return importedType;
867+
return {};
873868
}
874869

875870
static bool areRecordFieldsComplete(const clang::CXXRecordDecl *decl) {
@@ -4511,8 +4506,8 @@ namespace {
45114506
return nullptr;
45124507
}
45134508

4514-
auto fieldType = decl->getType();
4515-
ImportedType importedType = findOptionSetType(fieldType, Impl);
4509+
auto fieldType = desugarIfElaborated(decl->getType());
4510+
ImportedType importedType = importer::findOptionSetEnum(fieldType, Impl);
45164511

45174512
if (!importedType)
45184513
importedType =
@@ -6155,8 +6150,8 @@ namespace {
61556150
}
61566151
}
61576152

6158-
auto fieldType = decl->getType();
6159-
ImportedType importedType = findOptionSetType(fieldType, Impl);
6153+
auto fieldType = desugarIfElaborated(decl->getType());
6154+
ImportedType importedType = importer::findOptionSetEnum(fieldType, Impl);
61606155

61616156
if (!importedType)
61626157
importedType = Impl.importPropertyType(decl, isInSystemModule(dc));
@@ -7120,8 +7115,7 @@ SwiftDeclConverter::getImplicitProperty(ImportedName importedName,
71207115
getAccessorPropertyType(getter, false, getterName.getSelfIndex());
71217116
if (propertyType.isNull())
71227117
return nullptr;
7123-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(propertyType))
7124-
propertyType = elaborated->desugar();
7118+
propertyType = desugarIfElaborated(propertyType);
71257119

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

7150-
ImportedType importedType;
7151-
7152-
// Sometimes we import unavailable typedefs as enums. If that's the case,
7153-
// use the enum, not the typedef here.
7154-
if (auto typedefType = dyn_cast<clang::TypedefType>(propertyType.getTypePtr())) {
7155-
if (Impl.isUnavailableInSwift(typedefType->getDecl())) {
7156-
if (auto clangEnum = findAnonymousEnumForTypedef(Impl.SwiftContext, typedefType)) {
7157-
// If this fails, it means that we need a stronger predicate for
7158-
// determining the relationship between an enum and typedef.
7159-
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
7160-
typedefType->getCanonicalTypeInternal());
7161-
if (auto swiftEnum = Impl.importDecl(*clangEnum, Impl.CurrentVersion)) {
7162-
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(),
7163-
false};
7164-
}
7165-
}
7166-
}
7167-
}
7144+
ImportedType importedType = importer::findOptionSetEnum(propertyType, Impl);
71687145

71697146
if (!importedType) {
71707147
// 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
@@ -2282,10 +2282,7 @@ ImportedType ClangImporter::Implementation::importFunctionReturnType(
22822282
OptionalityOfReturn = OTK_ImplicitlyUnwrappedOptional;
22832283
}
22842284

2285-
clang::QualType returnType = clangDecl->getReturnType();
2286-
if (auto elaborated =
2287-
dyn_cast<clang::ElaboratedType>(returnType))
2288-
returnType = elaborated->desugar();
2285+
clang::QualType returnType = desugarIfElaborated(clangDecl->getReturnType());
22892286
// In C interop mode, the return type of library builtin functions
22902287
// like 'memcpy' from headers like 'string.h' drops
22912288
// any nullability specifiers from their return type, and preserves it on the
@@ -2323,19 +2320,9 @@ ImportedType ClangImporter::Implementation::importFunctionReturnType(
23232320
->isTemplateTypeParmType())
23242321
OptionalityOfReturn = OTK_None;
23252322

2326-
if (auto typedefType = dyn_cast<clang::TypedefType>(returnType)) {
2327-
if (isUnavailableInSwift(typedefType->getDecl())) {
2328-
if (auto clangEnum = findAnonymousEnumForTypedef(SwiftContext, typedefType)) {
2329-
// If this fails, it means that we need a stronger predicate for
2330-
// determining the relationship between an enum and typedef.
2331-
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
2332-
typedefType->getCanonicalTypeInternal());
2333-
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
2334-
return {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(), false};
2335-
}
2336-
}
2337-
}
2338-
}
2323+
ImportedType optionSetEnum = importer::findOptionSetEnum(returnType, *this);
2324+
if (optionSetEnum)
2325+
return optionSetEnum;
23392326

23402327
// Import the underlying result type.
23412328
if (clangDecl) {
@@ -2399,27 +2386,11 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
23992386

24002387
// Only eagerly import the return type if it's not too expensive (the current
24012388
// heuristic for that is if it's not a record type).
2402-
ImportedType importedType;
24032389
ImportDiagnosticAdder addDiag(*this, clangDecl,
24042390
clangDecl->getSourceRange().getBegin());
2405-
clang::QualType returnType = clangDecl->getReturnType();
2406-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(returnType))
2407-
returnType = elaborated->desugar();
2408-
2409-
if (auto typedefType = dyn_cast<clang::TypedefType>(returnType)) {
2410-
if (isUnavailableInSwift(typedefType->getDecl())) {
2411-
if (auto clangEnum = findAnonymousEnumForTypedef(SwiftContext, typedefType)) {
2412-
// If this fails, it means that we need a stronger predicate for
2413-
// determining the relationship between an enum and typedef.
2414-
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
2415-
typedefType->getCanonicalTypeInternal());
2416-
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
2417-
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(),
2418-
false};
2419-
}
2420-
}
2421-
}
2422-
}
2391+
clang::QualType returnType = desugarIfElaborated(clangDecl->getReturnType());
2392+
2393+
ImportedType importedType = importer::findOptionSetEnum(returnType, *this);
24232394

24242395
if (auto templateType =
24252396
dyn_cast<clang::TemplateTypeParmType>(returnType)) {
@@ -2483,9 +2454,7 @@ ClangImporter::Implementation::importParameterType(
24832454
std::optional<unsigned> completionHandlerErrorParamIndex,
24842455
ArrayRef<GenericTypeParamDecl *> genericParams,
24852456
llvm::function_ref<void(Diagnostic &&)> addImportDiagnosticFn) {
2486-
auto paramTy = param->getType();
2487-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(paramTy))
2488-
paramTy = elaborated->desugar();
2457+
auto paramTy = desugarIfElaborated(param->getType());
24892458

24902459
ImportTypeKind importKind = paramIsCompletionHandler
24912460
? ImportTypeKind::CompletionHandlerParameter
@@ -2498,23 +2467,8 @@ ClangImporter::Implementation::importParameterType(
24982467
bool isConsuming = false;
24992468
bool isParamTypeImplicitlyUnwrapped = false;
25002469

2501-
// Sometimes we import unavailable typedefs as enums. If that's the case,
2502-
// use the enum, not the typedef here.
2503-
if (auto typedefType = dyn_cast<clang::TypedefType>(paramTy.getTypePtr())) {
2504-
if (isUnavailableInSwift(typedefType->getDecl())) {
2505-
if (auto clangEnum =
2506-
findAnonymousEnumForTypedef(SwiftContext, typedefType)) {
2507-
// If this fails, it means that we need a stronger predicate for
2508-
// determining the relationship between an enum and typedef.
2509-
assert(clangEnum.value()
2510-
->getIntegerType()
2511-
->getCanonicalTypeInternal() ==
2512-
typedefType->getCanonicalTypeInternal());
2513-
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
2514-
swiftParamTy = cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType();
2515-
}
2516-
}
2517-
}
2470+
if (auto optionSetEnum = importer::findOptionSetEnum(paramTy, *this)) {
2471+
swiftParamTy = optionSetEnum.getType();
25182472
} else if (isa<clang::PointerType>(paramTy) &&
25192473
isa<clang::TemplateTypeParmType>(paramTy->getPointeeType())) {
25202474
auto pointeeType = paramTy->getPointeeType();
@@ -3234,26 +3188,8 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
32343188

32353189
ImportDiagnosticAdder addImportDiag(*this, clangDecl,
32363190
clangDecl->getLocation());
3237-
clang::QualType resultType = clangDecl->getReturnType();
3238-
if (auto elaborated = dyn_cast<clang::ElaboratedType>(resultType))
3239-
resultType = elaborated->desugar();
3240-
3241-
ImportedType importedType;
3242-
if (auto typedefType = dyn_cast<clang::TypedefType>(resultType.getTypePtr())) {
3243-
if (isUnavailableInSwift(typedefType->getDecl())) {
3244-
if (auto clangEnum = findAnonymousEnumForTypedef(SwiftContext, typedefType)) {
3245-
// If this fails, it means that we need a stronger predicate for
3246-
// determining the relationship between an enum and typedef.
3247-
assert(clangEnum.value()->getIntegerType()->getCanonicalTypeInternal() ==
3248-
typedefType->getCanonicalTypeInternal());
3249-
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
3250-
importedType = {cast<TypeDecl>(swiftEnum)->getDeclaredInterfaceType(),
3251-
false};
3252-
}
3253-
}
3254-
}
3255-
}
3256-
3191+
clang::QualType resultType = desugarIfElaborated(clangDecl->getReturnType());
3192+
ImportedType importedType = importer::findOptionSetEnum(resultType, *this);
32573193
if (!importedType)
32583194
importedType = importType(resultType, resultKind, addImportDiag,
32593195
allowNSUIntegerAsIntInResult, Bridgeability::Full,
@@ -3501,9 +3437,6 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
35013437
importedType.isImplicitlyUnwrapped()};
35023438
}
35033439

3504-
ImportedType findOptionSetType(clang::QualType type,
3505-
ClangImporter::Implementation &Impl);
3506-
35073440
ImportedType ClangImporter::Implementation::importAccessorParamsAndReturnType(
35083441
const DeclContext *dc, const clang::ObjCPropertyDecl *property,
35093442
const clang::ObjCMethodDecl *clangDecl, bool isFromSystemModule,
@@ -3529,11 +3462,11 @@ ImportedType ClangImporter::Implementation::importAccessorParamsAndReturnType(
35293462
if (!origDC)
35303463
return {Type(), false};
35313464

3532-
auto fieldType = isGetter ? clangDecl->getReturnType()
3533-
: clangDecl->getParamDecl(0)->getType();
3534-
3465+
auto fieldType =
3466+
desugarIfElaborated(isGetter ? clangDecl->getReturnType()
3467+
: clangDecl->getParamDecl(0)->getType());
35353468
// Import the property type, independent of what kind of accessor this is.
3536-
ImportedType importedType = findOptionSetType(fieldType, *this);
3469+
ImportedType importedType = importer::findOptionSetEnum(fieldType, *this);
35373470
if (!importedType)
35383471
importedType = importPropertyType(property, isFromSystemModule);
35393472
if (!importedType)

lib/ClangImporter/ImporterImpl.h

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

20862086
bool isViewType(const clang::CXXRecordDecl *decl);
20872087

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

0 commit comments

Comments
 (0)