@@ -2125,6 +2125,20 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
2125
2125
ImportedType importedType;
2126
2126
ImportDiagnosticAdder addDiag (*this , clangDecl,
2127
2127
clangDecl->getSourceRange ().getBegin ());
2128
+ if (auto typedefType = dyn_cast<clang::TypedefType>(clangDecl->getReturnType ().getTypePtr ())) {
2129
+ if (isUnavailableInSwift (typedefType->getDecl ())) {
2130
+ if (auto clangEnum = findAnonymousEnumForTypedef (SwiftContext, typedefType)) {
2131
+ // If this fails, it means that we need a stronger predicate for
2132
+ // determining the relationship between an enum and typedef.
2133
+ assert (clangEnum.getValue ()->getIntegerType ()->getCanonicalTypeInternal () ==
2134
+ typedefType->getCanonicalTypeInternal ());
2135
+ if (auto swiftEnum = importDecl (*clangEnum, CurrentVersion)) {
2136
+ importedType = {cast<NominalTypeDecl>(swiftEnum)->getDeclaredType (), false };
2137
+ }
2138
+ }
2139
+ }
2140
+ }
2141
+
2128
2142
if (auto templateType =
2129
2143
dyn_cast<clang::TemplateTypeParmType>(clangDecl->getReturnType ())) {
2130
2144
importedType = {findGenericTypeInGenericDecls (
@@ -2150,11 +2164,15 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
2150
2164
clangDecl->isOverloadedOperator () ||
2151
2165
// Dependant types are trivially mapped as Any.
2152
2166
clangDecl->getReturnType ()->isDependentType ()) {
2153
- importedType =
2154
- importFunctionReturnType (dc, clangDecl, allowNSUIntegerAsInt);
2167
+ // If importedType is already initialized, it means we found the enum that
2168
+ // was supposed to be used (instead of the typedef type).
2155
2169
if (!importedType) {
2156
- addDiag (Diagnostic (diag::return_type_not_imported));
2157
- return {Type (), false };
2170
+ importedType =
2171
+ importFunctionReturnType (dc, clangDecl, allowNSUIntegerAsInt);
2172
+ if (!importedType) {
2173
+ addDiag (Diagnostic (diag::return_type_not_imported));
2174
+ return {Type (), false };
2175
+ }
2158
2176
}
2159
2177
}
2160
2178
@@ -2238,7 +2256,22 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
2238
2256
Type swiftParamTy;
2239
2257
bool isParamTypeImplicitlyUnwrapped = false ;
2240
2258
bool isInOut = false ;
2241
- if (isa<clang::PointerType>(paramTy) &&
2259
+
2260
+ // Sometimes we import unavailable typedefs as enums. If that's the case,
2261
+ // use the enum, not the typedef here.
2262
+ if (auto typedefType = dyn_cast<clang::TypedefType>(paramTy.getTypePtr ())) {
2263
+ if (isUnavailableInSwift (typedefType->getDecl ())) {
2264
+ if (auto clangEnum = findAnonymousEnumForTypedef (SwiftContext, typedefType)) {
2265
+ // If this fails, it means that we need a stronger predicate for
2266
+ // determining the relationship between an enum and typedef.
2267
+ assert (clangEnum.getValue ()->getIntegerType ()->getCanonicalTypeInternal () ==
2268
+ typedefType->getCanonicalTypeInternal ());
2269
+ if (auto swiftEnum = importDecl (*clangEnum, CurrentVersion)) {
2270
+ swiftParamTy = cast<NominalTypeDecl>(swiftEnum)->getDeclaredType ();
2271
+ }
2272
+ }
2273
+ }
2274
+ } else if (isa<clang::PointerType>(paramTy) &&
2242
2275
isa<clang::TemplateTypeParmType>(paramTy->getPointeeType ())) {
2243
2276
auto pointeeType = paramTy->getPointeeType ();
2244
2277
auto templateParamType = cast<clang::TemplateTypeParmType>(pointeeType);
@@ -2265,20 +2298,21 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
2265
2298
swiftParamTy =
2266
2299
findGenericTypeInGenericDecls (*this , templateParamType, genericParams,
2267
2300
attrs, paramAddDiag);
2268
- } else {
2269
- if (auto refType = dyn_cast<clang::ReferenceType>(paramTy)) {
2270
- // We don't support reference type to a dependent type, just bail.
2271
- if (refType->getPointeeType ()->isDependentType ()) {
2272
- addImportDiagnostic (
2273
- param, Diagnostic (diag::parameter_type_not_imported, param),
2274
- param->getSourceRange ().getBegin ());
2275
- return nullptr ;
2276
- }
2277
-
2278
- paramTy = refType->getPointeeType ();
2279
- if (!paramTy.isConstQualified ())
2280
- isInOut = true ;
2301
+ } else if (auto refType = dyn_cast<clang::ReferenceType>(paramTy)) {
2302
+ // We don't support reference type to a dependent type, just bail.
2303
+ if (refType->getPointeeType ()->isDependentType ()) {
2304
+ addImportDiagnostic (
2305
+ param, Diagnostic (diag::parameter_type_not_imported, param),
2306
+ param->getSourceRange ().getBegin ());
2307
+ return nullptr ;
2281
2308
}
2309
+
2310
+ paramTy = refType->getPointeeType ();
2311
+ if (!paramTy.isConstQualified ())
2312
+ isInOut = true ;
2313
+ }
2314
+
2315
+ if (!swiftParamTy) {
2282
2316
auto importedType = importType (paramTy, importKind, paramAddDiag,
2283
2317
allowNSUIntegerAsInt, Bridgeability::Full,
2284
2318
attrs, OptionalityOfParam);
0 commit comments