@@ -2356,15 +2356,32 @@ ClangImporter::Implementation::importParameterType(
23562356 dyn_cast<clang::TemplateTypeParmType>(paramTy)) {
23572357 swiftParamTy = findGenericTypeInGenericDecls (
23582358 *this , templateParamType, genericParams, attrs, addImportDiagnosticFn);
2359- } else if (auto refType = dyn_cast<clang::ReferenceType>(paramTy)) {
2360- // We don't support reference type to a dependent type, just bail.
2361- if (refType->getPointeeType ()->isDependentType ()) {
2362- return None;
2363- }
2359+ }
23642360
2365- paramTy = refType->getPointeeType ();
2366- if (!paramTy.isConstQualified ())
2367- isInOut = true ;
2361+ if (!swiftParamTy) {
2362+ // C++ reference types are brought in as direct
2363+ // types most commonly.
2364+ auto refPointeeType =
2365+ importer::getCxxReferencePointeeTypeOrNone (paramTy.getTypePtr ());
2366+ if (refPointeeType) {
2367+ // We don't support reference type to a dependent type, just bail.
2368+ if ((*refPointeeType)->isDependentType ()) {
2369+ return None;
2370+ }
2371+
2372+ // We don't support rvalue reference types, just bail.
2373+ if (paramTy->isRValueReferenceType ()) {
2374+ addImportDiagnosticFn (Diagnostic (diag::rvalue_ref_params_not_imported));
2375+ return None;
2376+ }
2377+
2378+ // A C++ parameter of type `const <type> &` or `<type> &` becomes `<type>`
2379+ // or `inout <type>` in Swift. Note that SILGen will use the indirect
2380+ // parameter convention for such a type.
2381+ paramTy = *refPointeeType;
2382+ if (!paramTy.isConstQualified ())
2383+ isInOut = true ;
2384+ }
23682385 }
23692386
23702387 // Special case for NSDictionary's subscript.
0 commit comments