Skip to content

Commit f014338

Browse files
committed
[NFCi] Extract importParameterType
Extract a helper method `importParameterType` from the `importFunctionParameterList` code. This new helper only deals with function parameters, but the final intention is that it will be shared code with the code that import method parameters. The only functional difference introduced is that before, some of the branches will not have added an extra diagnostic about parameters failing to import, while this version adds those diagnostics consistently for any case.
1 parent 585a3a1 commit f014338

File tree

2 files changed

+114
-74
lines changed

2 files changed

+114
-74
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 88 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -2241,6 +2241,85 @@ getImportTypeKindForParam(const clang::ParmVarDecl *param) {
22412241
return importKind;
22422242
}
22432243

2244+
Optional<swift::Type> ClangImporter::Implementation::importParameterType(
2245+
const clang::ParmVarDecl *param, OptionalTypeKind OptionalityOfParam,
2246+
bool allowNSUIntegerAsInt, ArrayRef<GenericTypeParamDecl *> genericParams,
2247+
llvm::function_ref<void(Diagnostic &&)> paramAddDiag, bool &isInOut,
2248+
bool &isParamTypeImplicitlyUnwrapped) {
2249+
auto paramTy = param->getType();
2250+
2251+
ImportTypeKind importKind = getImportTypeKindForParam(param);
2252+
2253+
// Import the parameter type into Swift.
2254+
auto attrs = getImportTypeAttrs(param, /*isParam=*/true);
2255+
Type swiftParamTy;
2256+
2257+
// Sometimes we import unavailable typedefs as enums. If that's the case,
2258+
// use the enum, not the typedef here.
2259+
if (auto typedefType = dyn_cast<clang::TypedefType>(paramTy.getTypePtr())) {
2260+
if (isUnavailableInSwift(typedefType->getDecl())) {
2261+
if (auto clangEnum =
2262+
findAnonymousEnumForTypedef(SwiftContext, typedefType)) {
2263+
// If this fails, it means that we need a stronger predicate for
2264+
// determining the relationship between an enum and typedef.
2265+
assert(clangEnum.getValue()
2266+
->getIntegerType()
2267+
->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) &&
2275+
isa<clang::TemplateTypeParmType>(paramTy->getPointeeType())) {
2276+
auto pointeeType = paramTy->getPointeeType();
2277+
auto templateParamType = cast<clang::TemplateTypeParmType>(pointeeType);
2278+
PointerTypeKind pointerKind = pointeeType.getQualifiers().hasConst()
2279+
? PTK_UnsafePointer
2280+
: PTK_UnsafeMutablePointer;
2281+
auto genericType = findGenericTypeInGenericDecls(
2282+
*this, templateParamType, genericParams, attrs, paramAddDiag);
2283+
swiftParamTy = genericType->wrapInPointer(pointerKind);
2284+
if (!swiftParamTy)
2285+
return None;
2286+
} else if (isa<clang::ReferenceType>(paramTy) &&
2287+
isa<clang::TemplateTypeParmType>(paramTy->getPointeeType())) {
2288+
auto templateParamType =
2289+
cast<clang::TemplateTypeParmType>(paramTy->getPointeeType());
2290+
swiftParamTy = findGenericTypeInGenericDecls(
2291+
*this, templateParamType, genericParams, attrs, paramAddDiag);
2292+
if (!paramTy->getPointeeType().isConstQualified())
2293+
isInOut = true;
2294+
} else if (auto *templateParamType =
2295+
dyn_cast<clang::TemplateTypeParmType>(paramTy)) {
2296+
swiftParamTy = findGenericTypeInGenericDecls(
2297+
*this, templateParamType, genericParams, attrs, paramAddDiag);
2298+
} else if (auto refType = dyn_cast<clang::ReferenceType>(paramTy)) {
2299+
// We don't support reference type to a dependent type, just bail.
2300+
if (refType->getPointeeType()->isDependentType()) {
2301+
return None;
2302+
}
2303+
2304+
paramTy = refType->getPointeeType();
2305+
if (!paramTy.isConstQualified())
2306+
isInOut = true;
2307+
}
2308+
2309+
if (!swiftParamTy) {
2310+
auto importedType =
2311+
importType(paramTy, importKind, paramAddDiag, allowNSUIntegerAsInt,
2312+
Bridgeability::Full, attrs, OptionalityOfParam);
2313+
if (!importedType)
2314+
return None;
2315+
2316+
isParamTypeImplicitlyUnwrapped = importedType.isImplicitlyUnwrapped();
2317+
swiftParamTy = importedType.getType();
2318+
}
2319+
2320+
return swiftParamTy;
2321+
}
2322+
22442323
static ParamDecl *getParameterInfo(ClangImporter::Implementation *impl,
22452324
const clang::ParmVarDecl *param,
22462325
const Identifier &name,
@@ -2293,86 +2372,21 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
22932372
// Check nullability of the parameter.
22942373
OptionalTypeKind OptionalityOfParam = getParamOptionality(param, knownNonNull);
22952374

2296-
ImportTypeKind importKind = getImportTypeKindForParam(param);
2297-
22982375
ImportDiagnosticAdder paramAddDiag(*this, clangDecl, param->getLocation());
22992376

23002377
bool isInOut = false;
23012378
bool isParamTypeImplicitlyUnwrapped = false;
23022379

2303-
// Import the parameter type into Swift.
2304-
auto attrs = getImportTypeAttrs(param, /*isParam=*/true);
2305-
Type swiftParamTy;
2306-
2307-
// Sometimes we import unavailable typedefs as enums. If that's the case,
2308-
// use the enum, not the typedef here.
2309-
if (auto typedefType = dyn_cast<clang::TypedefType>(paramTy.getTypePtr())) {
2310-
if (isUnavailableInSwift(typedefType->getDecl())) {
2311-
if (auto clangEnum = findAnonymousEnumForTypedef(SwiftContext, typedefType)) {
2312-
// If this fails, it means that we need a stronger predicate for
2313-
// determining the relationship between an enum and typedef.
2314-
assert(clangEnum.getValue()->getIntegerType()->getCanonicalTypeInternal() ==
2315-
typedefType->getCanonicalTypeInternal());
2316-
if (auto swiftEnum = importDecl(*clangEnum, CurrentVersion)) {
2317-
swiftParamTy = cast<NominalTypeDecl>(swiftEnum)->getDeclaredType();
2318-
}
2319-
}
2320-
}
2321-
} else if (isa<clang::PointerType>(paramTy) &&
2322-
isa<clang::TemplateTypeParmType>(paramTy->getPointeeType())) {
2323-
auto pointeeType = paramTy->getPointeeType();
2324-
auto templateParamType = cast<clang::TemplateTypeParmType>(pointeeType);
2325-
PointerTypeKind pointerKind = pointeeType.getQualifiers().hasConst()
2326-
? PTK_UnsafePointer
2327-
: PTK_UnsafeMutablePointer;
2328-
auto genericType =
2329-
findGenericTypeInGenericDecls(*this, templateParamType, genericParams,
2330-
attrs, paramAddDiag);
2331-
swiftParamTy = genericType->wrapInPointer(pointerKind);
2332-
if (!swiftParamTy)
2333-
return nullptr;
2334-
} else if (isa<clang::ReferenceType>(paramTy) &&
2335-
isa<clang::TemplateTypeParmType>(paramTy->getPointeeType())) {
2336-
auto templateParamType =
2337-
cast<clang::TemplateTypeParmType>(paramTy->getPointeeType());
2338-
swiftParamTy =
2339-
findGenericTypeInGenericDecls(*this, templateParamType, genericParams,
2340-
attrs, paramAddDiag);
2341-
if (!paramTy->getPointeeType().isConstQualified())
2342-
isInOut = true;
2343-
} else if (auto *templateParamType =
2344-
dyn_cast<clang::TemplateTypeParmType>(paramTy)) {
2345-
swiftParamTy =
2346-
findGenericTypeInGenericDecls(*this, templateParamType, genericParams,
2347-
attrs, paramAddDiag);
2348-
} else if (auto refType = dyn_cast<clang::ReferenceType>(paramTy)) {
2349-
// We don't support reference type to a dependent type, just bail.
2350-
if (refType->getPointeeType()->isDependentType()) {
2351-
addImportDiagnostic(
2352-
param, Diagnostic(diag::parameter_type_not_imported, param),
2353-
param->getSourceRange().getBegin());
2354-
return nullptr;
2355-
}
2356-
2357-
paramTy = refType->getPointeeType();
2358-
if (!paramTy.isConstQualified())
2359-
isInOut = true;
2360-
}
2361-
2362-
if (!swiftParamTy) {
2363-
auto importedType = importType(paramTy, importKind, paramAddDiag,
2364-
allowNSUIntegerAsInt, Bridgeability::Full,
2365-
attrs, OptionalityOfParam);
2366-
if (!importedType) {
2367-
addImportDiagnostic(
2368-
param, Diagnostic(diag::parameter_type_not_imported, param),
2369-
param->getSourceRange().getBegin());
2370-
return nullptr;
2371-
}
2372-
2373-
isParamTypeImplicitlyUnwrapped = importedType.isImplicitlyUnwrapped();
2374-
swiftParamTy = importedType.getType();
2380+
auto swiftParamTyOpt = importParameterType(
2381+
param, OptionalityOfParam, importKind, allowNSUIntegerAsInt,
2382+
genericParams, paramAddDiag, isInOut, isParamTypeImplicitlyUnwrapped);
2383+
if (!swiftParamTyOpt) {
2384+
addImportDiagnostic(param,
2385+
Diagnostic(diag::parameter_type_not_imported, param),
2386+
param->getSourceRange().getBegin());
2387+
return nullptr;
23752388
}
2389+
auto swiftParamTy = *swiftParamTyOpt;
23762390

23772391
// Retrieve the argument name.
23782392
Identifier name;

lib/ClangImporter/ImporterImpl.h

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1364,6 +1364,32 @@ class LLVM_LIBRARY_VISIBILITY ClangImporter::Implementation
13641364
bool allowNSUIntegerAsInt, ArrayRef<Identifier> argNames,
13651365
ArrayRef<GenericTypeParamDecl *> genericParams, Type resultType);
13661366

1367+
/// Import a parameter type
1368+
///
1369+
/// \param param The underlaying parameter declaraction.
1370+
/// \param optionalityOfParam The kind of optionality for the parameter
1371+
/// being imported.
1372+
/// \param allowNSUIntegerAsInt If true, NSUInteger will be import as Int
1373+
/// in certain contexts. If false, it will always be import as UInt.
1374+
/// \param genericParams For C++ functions, an array of the generic type
1375+
/// parameters of the function. For the rest of cases, an empty array
1376+
/// can be provided.
1377+
/// \param addImportDiagnosticFn A function that can be called to add import
1378+
/// diagnostics to the declaration being imported. This can be any
1379+
/// lambda or callable object, but it's designed to be compatible
1380+
/// with \c ImportDiagnosticAdder .
1381+
/// \param[out] isInOut On return, true if the parameter is inout. False,
1382+
/// otherwise.
1383+
/// \param[out] isParamTypeImplicitlyUnwrapped On return, true if the
1384+
/// parameter is implicitly unwrapped. False, otherwise.
1385+
///
1386+
/// \returns The imported parameter type on success, or None on failure.
1387+
Optional<swift::Type> importParameterType(
1388+
const clang::ParmVarDecl *param, OptionalTypeKind optionalityOfParam,
1389+
bool allowNSUIntegerAsInt, ArrayRef<GenericTypeParamDecl *> genericParams,
1390+
llvm::function_ref<void(Diagnostic &&)> addImportDiagnosticFn,
1391+
bool &isInOut, bool &isParamTypeImplicitlyUnwrapped);
1392+
13671393
ImportedType importPropertyType(const clang::ObjCPropertyDecl *clangDecl,
13681394
bool isFromSystemModule);
13691395

0 commit comments

Comments
 (0)