@@ -2415,6 +2415,7 @@ ClangImporter::Implementation::importParameterType(
24152415 auto attrs = getImportTypeAttrs (param, /* isParam=*/ true );
24162416 Type swiftParamTy;
24172417 bool isInOut = false ;
2418+ bool isConsuming = false ;
24182419 bool isParamTypeImplicitlyUnwrapped = false ;
24192420
24202421 // Sometimes we import unavailable typedefs as enums. If that's the case,
@@ -2448,7 +2449,7 @@ ClangImporter::Implementation::importParameterType(
24482449 return std::nullopt ;
24492450 } else if (isa<clang::ReferenceType>(paramTy) &&
24502451 isa<clang::TemplateTypeParmType>(paramTy->getPointeeType ())) {
2451- // We don't support rvalue reference / universal perfect ref , bail.
2452+ // We don't support universal reference , bail.
24522453 if (paramTy->isRValueReferenceType ()) {
24532454 addImportDiagnosticFn (Diagnostic (diag::rvalue_ref_params_not_imported));
24542455 return std::nullopt ;
@@ -2469,26 +2470,25 @@ ClangImporter::Implementation::importParameterType(
24692470 if (!swiftParamTy) {
24702471 // C++ reference types are brought in as direct
24712472 // types most commonly.
2472- auto refPointeeType =
2473- importer::getCxxReferencePointeeTypeOrNone (paramTy.getTypePtr ());
2474- if (refPointeeType) {
2473+ if (auto refPointeeType =
2474+ getCxxReferencePointeeTypeOrNone (paramTy.getTypePtr ())) {
24752475 // We don't support reference type to a dependent type, just bail.
24762476 if ((*refPointeeType)->isDependentType ()) {
24772477 return std::nullopt ;
24782478 }
24792479
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 ();
24862481 // 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.
24892485 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+ }
24922492 }
24932493 }
24942494
@@ -2552,7 +2552,7 @@ ClangImporter::Implementation::importParameterType(
25522552 if (isInOut && isDirectUseOfForeignReferenceType (paramTy, swiftParamTy))
25532553 isInOut = false ;
25542554
2555- return ImportParameterTypeResult{swiftParamTy, isInOut,
2555+ return ImportParameterTypeResult{swiftParamTy, isInOut, isConsuming,
25562556 isParamTypeImplicitlyUnwrapped};
25572557}
25582558
@@ -2606,7 +2606,7 @@ static ParamDecl *getParameterInfo(ClangImporter::Implementation *impl,
26062606 const clang::ParmVarDecl *param,
26072607 const Identifier &name,
26082608 const swift::Type &swiftParamTy,
2609- const bool isInOut,
2609+ const bool isInOut, const bool isConsuming,
26102610 const bool isParamTypeImplicitlyUnwrapped) {
26112611 // Figure out the name for this parameter.
26122612 Identifier bodyName = impl->importFullName (param, impl->CurrentVersion )
@@ -2632,10 +2632,12 @@ static ParamDecl *getParameterInfo(ClangImporter::Implementation *impl,
26322632
26332633 // Foreign references are already references so they don't need to be passed
26342634 // 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)));
26392641 paramInfo->setInterfaceType (swiftParamTy);
26402642 impl->recordImplicitUnwrapForDecl (paramInfo, isParamTypeImplicitlyUnwrapped);
26412643
@@ -2702,6 +2704,7 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
27022704 }
27032705 auto swiftParamTy = swiftParamTyOpt->swiftTy ;
27042706 bool isInOut = swiftParamTyOpt->isInOut ;
2707+ bool isConsuming = swiftParamTyOpt->isConsuming ;
27052708 bool isParamTypeImplicitlyUnwrapped =
27062709 swiftParamTyOpt->isParamTypeImplicitlyUnwrapped ;
27072710
@@ -2710,8 +2713,9 @@ ParameterList *ClangImporter::Implementation::importFunctionParameterList(
27102713 if (index < argNames.size ())
27112714 name = argNames[index];
27122715
2713- auto paramInfo = getParameterInfo (this , param, name, swiftParamTy, isInOut,
2714- isParamTypeImplicitlyUnwrapped);
2716+ auto paramInfo =
2717+ getParameterInfo (this , param, name, swiftParamTy, isInOut, isConsuming,
2718+ isParamTypeImplicitlyUnwrapped);
27152719 parameters.push_back (paramInfo);
27162720 ++index;
27172721 }
@@ -3296,6 +3300,7 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
32963300 }
32973301 auto swiftParamTy = swiftParamTyOpt->swiftTy ;
32983302 bool isInOut = swiftParamTyOpt->isInOut ;
3303+ bool isConsuming = swiftParamTyOpt->isConsuming ;
32993304 bool isParamTypeImplicitlyUnwrapped =
33003305 swiftParamTyOpt->isParamTypeImplicitlyUnwrapped ;
33013306
@@ -3345,8 +3350,9 @@ ImportedType ClangImporter::Implementation::importMethodParamsAndReturnType(
33453350 ++nameIndex;
33463351
33473352 // 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);
33503356
33513357 // Determine whether we have a default argument.
33523358 if (kind == SpecialMethodKind::Regular ||
0 commit comments