@@ -2415,6 +2415,7 @@ ClangImporter::Implementation::importParameterType(
2415
2415
auto attrs = getImportTypeAttrs (param, /* isParam=*/ true );
2416
2416
Type swiftParamTy;
2417
2417
bool isInOut = false ;
2418
+ bool isConsuming = false ;
2418
2419
bool isParamTypeImplicitlyUnwrapped = false ;
2419
2420
2420
2421
// Sometimes we import unavailable typedefs as enums. If that's the case,
@@ -2448,7 +2449,7 @@ ClangImporter::Implementation::importParameterType(
2448
2449
return std::nullopt ;
2449
2450
} else if (isa<clang::ReferenceType>(paramTy) &&
2450
2451
isa<clang::TemplateTypeParmType>(paramTy->getPointeeType ())) {
2451
- // We don't support rvalue reference / universal perfect ref , bail.
2452
+ // We don't support universal reference , bail.
2452
2453
if (paramTy->isRValueReferenceType ()) {
2453
2454
addImportDiagnosticFn (Diagnostic (diag::rvalue_ref_params_not_imported));
2454
2455
return std::nullopt ;
@@ -2469,26 +2470,25 @@ ClangImporter::Implementation::importParameterType(
2469
2470
if (!swiftParamTy) {
2470
2471
// C++ reference types are brought in as direct
2471
2472
// types most commonly.
2472
- auto refPointeeType =
2473
- importer::getCxxReferencePointeeTypeOrNone (paramTy.getTypePtr ());
2474
- if (refPointeeType) {
2473
+ if (auto refPointeeType =
2474
+ getCxxReferencePointeeTypeOrNone (paramTy.getTypePtr ())) {
2475
2475
// We don't support reference type to a dependent type, just bail.
2476
2476
if ((*refPointeeType)->isDependentType ()) {
2477
2477
return std::nullopt ;
2478
2478
}
2479
2479
2480
- // We don't support rvalue reference types, just bail.
2481
- if (paramTy->isRValueReferenceType ()) {
2482
- addImportDiagnosticFn (Diagnostic (diag::rvalue_ref_params_not_imported));
2483
- return std::nullopt ;
2484
- }
2485
-
2480
+ bool isRvalueRef = paramTy->isRValueReferenceType ();
2486
2481
// A C++ parameter of type `const <type> &` or `<type> &` becomes `<type>`
2487
- // or `inout <type>` in Swift. Note that SILGen will use the indirect
2488
- // parameter convention for such a type.
2482
+ // or `inout <type>`. Moreover, `const <type> &&` or `<type> &&`
2483
+ // becomes `<type>` or `consuming <type>`. Note that SILGen will use the
2484
+ // indirect parameter convention for such a type.
2489
2485
paramTy = *refPointeeType;
2490
- if (!paramTy.isConstQualified ())
2491
- isInOut = true ;
2486
+ if (!paramTy.isConstQualified ()) {
2487
+ if (isRvalueRef)
2488
+ isConsuming = true ;
2489
+ else
2490
+ isInOut = true ;
2491
+ }
2492
2492
}
2493
2493
}
2494
2494
@@ -2552,7 +2552,7 @@ ClangImporter::Implementation::importParameterType(
2552
2552
if (isInOut && isDirectUseOfForeignReferenceType (paramTy, swiftParamTy))
2553
2553
isInOut = false ;
2554
2554
2555
- return ImportParameterTypeResult{swiftParamTy, isInOut,
2555
+ return ImportParameterTypeResult{swiftParamTy, isInOut, isConsuming,
2556
2556
isParamTypeImplicitlyUnwrapped};
2557
2557
}
2558
2558
@@ -2606,7 +2606,7 @@ static ParamDecl *getParameterInfo(ClangImporter::Implementation *impl,
2606
2606
const clang::ParmVarDecl *param,
2607
2607
const Identifier &name,
2608
2608
const swift::Type &swiftParamTy,
2609
- const bool isInOut,
2609
+ const bool isInOut, const bool isConsuming,
2610
2610
const bool isParamTypeImplicitlyUnwrapped) {
2611
2611
// Figure out the name for this parameter.
2612
2612
Identifier bodyName = impl->importFullName (param, impl->CurrentVersion )
@@ -2632,10 +2632,12 @@ static ParamDecl *getParameterInfo(ClangImporter::Implementation *impl,
2632
2632
2633
2633
// Foreign references are already references so they don't need to be passed
2634
2634
// as inout.
2635
- paramInfo->setSpecifier (isInOut ? ParamSpecifier::InOut
2636
- : (param->getAttr <clang::LifetimeBoundAttr>()
2637
- ? ParamSpecifier::Borrowing
2638
- : ParamSpecifier::Default));
2635
+ paramInfo->setSpecifier (
2636
+ isConsuming ? ParamSpecifier::Consuming
2637
+ : (isInOut ? ParamSpecifier::InOut
2638
+ : (param->getAttr <clang::LifetimeBoundAttr>()
2639
+ ? ParamSpecifier::Borrowing
2640
+ : ParamSpecifier::Default)));
2639
2641
paramInfo->setInterfaceType (swiftParamTy);
2640
2642
impl->recordImplicitUnwrapForDecl (paramInfo, isParamTypeImplicitlyUnwrapped);
2641
2643
@@ -2702,6 +2704,7 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
2702
2704
}
2703
2705
auto swiftParamTy = swiftParamTyOpt->swiftTy ;
2704
2706
bool isInOut = swiftParamTyOpt->isInOut ;
2707
+ bool isConsuming = swiftParamTyOpt->isConsuming ;
2705
2708
bool isParamTypeImplicitlyUnwrapped =
2706
2709
swiftParamTyOpt->isParamTypeImplicitlyUnwrapped ;
2707
2710
@@ -2710,8 +2713,9 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
2710
2713
if (index < argNames.size ())
2711
2714
name = argNames[index];
2712
2715
2713
- auto paramInfo = getParameterInfo (this , param, name, swiftParamTy, isInOut,
2714
- isParamTypeImplicitlyUnwrapped);
2716
+ auto paramInfo =
2717
+ getParameterInfo (this , param, name, swiftParamTy, isInOut, isConsuming,
2718
+ isParamTypeImplicitlyUnwrapped);
2715
2719
parameters.push_back (paramInfo);
2716
2720
++index;
2717
2721
}
@@ -3296,6 +3300,7 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
3296
3300
}
3297
3301
auto swiftParamTy = swiftParamTyOpt->swiftTy ;
3298
3302
bool isInOut = swiftParamTyOpt->isInOut ;
3303
+ bool isConsuming = swiftParamTyOpt->isConsuming ;
3299
3304
bool isParamTypeImplicitlyUnwrapped =
3300
3305
swiftParamTyOpt->isParamTypeImplicitlyUnwrapped ;
3301
3306
@@ -3345,8 +3350,9 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
3345
3350
++nameIndex;
3346
3351
3347
3352
// Set up the parameter info
3348
- auto paramInfo = getParameterInfo (this , param, name, swiftParamTy, isInOut,
3349
- isParamTypeImplicitlyUnwrapped);
3353
+ auto paramInfo =
3354
+ getParameterInfo (this , param, name, swiftParamTy, isInOut, isConsuming,
3355
+ isParamTypeImplicitlyUnwrapped);
3350
3356
3351
3357
// Determine whether we have a default argument.
3352
3358
if (kind == SpecialMethodKind::Regular ||
0 commit comments