@@ -2125,6 +2125,20 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
21252125 ImportedType importedType;
21262126 ImportDiagnosticAdder addDiag (*this , clangDecl,
21272127 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+
21282142 if (auto templateType =
21292143 dyn_cast<clang::TemplateTypeParmType>(clangDecl->getReturnType ())) {
21302144 importedType = {findGenericTypeInGenericDecls (
@@ -2150,11 +2164,15 @@ ImportedType ClangImporter::Implementation::importFunctionParamsAndReturnType(
21502164 clangDecl->isOverloadedOperator () ||
21512165 // Dependant types are trivially mapped as Any.
21522166 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).
21552169 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+ }
21582176 }
21592177 }
21602178
@@ -2238,7 +2256,22 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
22382256 Type swiftParamTy;
22392257 bool isParamTypeImplicitlyUnwrapped = false ;
22402258 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) &&
22422275 isa<clang::TemplateTypeParmType>(paramTy->getPointeeType ())) {
22432276 auto pointeeType = paramTy->getPointeeType ();
22442277 auto templateParamType = cast<clang::TemplateTypeParmType>(pointeeType);
@@ -2265,20 +2298,21 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
22652298 swiftParamTy =
22662299 findGenericTypeInGenericDecls (*this , templateParamType, genericParams,
22672300 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 ;
22812308 }
2309+
2310+ paramTy = refType->getPointeeType ();
2311+ if (!paramTy.isConstQualified ())
2312+ isInOut = true ;
2313+ }
2314+
2315+ if (!swiftParamTy) {
22822316 auto importedType = importType (paramTy, importKind, paramAddDiag,
22832317 allowNSUIntegerAsInt, Bridgeability::Full,
22842318 attrs, OptionalityOfParam);
0 commit comments