@@ -1196,29 +1196,47 @@ void Sema::ActOnLambdaExpressionAfterIntroducer(LambdaIntroducer &Intro,
11961196 // for e.g., [n{0}] { }; <-- if no <initializer_list> is included.
11971197 // FIXME: we should create the init capture variable and mark it invalid
11981198 // in this case.
1199- if (C->InitCaptureType .get ().isNull () && !C->Init .isUsable ()) {
1200- Diag (C->Loc , diag::err_invalid_lambda_capture_initializer_type); //
1201- continue ; //
1202- }
1199+ // Check if the initializer type is invalid or unusable
1200+ if (C->InitCaptureType .get ().isNull () && !C->Init .isUsable ()) {
1201+ Diag (C->Loc , diag::err_invalid_lambda_capture_initializer_type)
1202+ << C->Id ; // Provide more context by including the capture name
1203+ continue ;
1204+ }
12031205
1204- if (C->Init .get ()->containsUnexpandedParameterPack () &&
1205- !C->InitCaptureType .get ()->getAs <PackExpansionType>())
1206- DiagnoseUnexpandedParameterPack (C->Init .get (), UPPC_Initializer);
1207-
1208- unsigned InitStyle;
1209- switch (C->InitKind ) {
1210- case LambdaCaptureInitKind::NoInit:
1211- llvm_unreachable (" not an init-capture?" );
1212- case LambdaCaptureInitKind::CopyInit:
1213- InitStyle = VarDecl::CInit;
1214- break ;
1215- case LambdaCaptureInitKind::DirectInit:
1216- InitStyle = VarDecl::CallInit;
1217- break ;
1218- case LambdaCaptureInitKind::ListInit:
1219- InitStyle = VarDecl::ListInit;
1220- break ;
1221- }
1206+ // Check if there are unexpanded parameter packs
1207+ if (C->Init .get ()->containsUnexpandedParameterPack () &&
1208+ !C->InitCaptureType .get ()->getAs <PackExpansionType>()) {
1209+ Diag (C->Loc , diag::err_pack_expansion_mismatch)
1210+ << C->Id ; // Include the problematic capture for context
1211+ DiagnoseUnexpandedParameterPack (C->Init .get (), UPPC_Initializer);
1212+ }
1213+
1214+ // Determine the appropriate initialization style
1215+ unsigned InitStyle;
1216+ switch (C->InitKind ) {
1217+ case LambdaCaptureInitKind::NoInit:
1218+ Diag (C->Loc , diag::err_unsupported_lambda_capture_no_init)
1219+ << C->Id ; // Mention the capture name causing the issue
1220+ llvm_unreachable (" not an init-capture?" );
1221+
1222+ case LambdaCaptureInitKind::CopyInit:
1223+ InitStyle = VarDecl::CInit;
1224+ Diag (C->Loc , diag::note_lambda_capture_copy_init)
1225+ << C->Id ; // Note about using copy initialization
1226+ break ;
1227+
1228+ case LambdaCaptureInitKind::DirectInit:
1229+ InitStyle = VarDecl::CallInit;
1230+ Diag (C->Loc , diag::note_lambda_capture_direct_init)
1231+ << C->Id ; // Note about using direct initialization
1232+ break ;
1233+
1234+ case LambdaCaptureInitKind::ListInit:
1235+ InitStyle = VarDecl::ListInit;
1236+ Diag (C->Loc , diag::note_lambda_capture_list_init)
1237+ << C->Id ; // Note about using list initialization
1238+ break ;
1239+ }
12221240 Var = createLambdaInitCaptureVarDecl (C->Loc , C->InitCaptureType .get (),
12231241 C->EllipsisLoc , C->Id , InitStyle,
12241242 C->Init .get (), Method);
@@ -2146,32 +2164,35 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
21462164 SourceRange CaptureRange = LSI->ExplicitCaptureRanges [I];
21472165
21482166 // Warn about unused explicit captures.
2167+
21492168 bool IsCaptureUsed = true ;
2150- if (!CurContext->isDependentContext () && !IsImplicit &&
2151- !From.isODRUsed ()) {
2152- // Initialized captures that are non-ODR used may not be eliminated.
2153- // FIXME: Where did the IsGenericLambda here come from?
2154- bool NonODRUsedInitCapture =
2155- IsGenericLambda && From.isNonODRUsed () && From.isInitCapture ();
2156- if (!NonODRUsedInitCapture) {
2157- bool IsLast = (I + 1 ) == LSI->NumExplicitCaptures ;
2158- SourceRange FixItRange;
2159- if (CaptureRange.isValid ()) {
2160- if (!CurHasPreviousCapture && !IsLast) {
2161- // If there are no captures preceding this capture, remove the
2162- // following comma.
2163- FixItRange = SourceRange (CaptureRange.getBegin (),
2164- getLocForEndOfToken (CaptureRange.getEnd ()));
2165- } else {
2166- // Otherwise, remove the comma since the last used capture.
2167- FixItRange = SourceRange (getLocForEndOfToken (PrevCaptureLoc),
2168- CaptureRange.getEnd ());
2169- }
2170- }
21712169
2172- IsCaptureUsed = !DiagnoseUnusedLambdaCapture (FixItRange, From);
2173- }
2170+ if (!CurContext->isDependentContext () && !IsImplicit && !From.isODRUsed ()) {
2171+ // Handle non-ODR used init captures separately.
2172+ bool NonODRUsedInitCapture = IsGenericLambda && From.isNonODRUsed () && From.isInitCapture ();
2173+
2174+ if (!NonODRUsedInitCapture) {
2175+ bool IsLast = (I + 1 ) == LSI->NumExplicitCaptures ;
2176+ SourceRange FixItRange;
2177+
2178+ if (CaptureRange.isValid ()) {
2179+ if (!CurHasPreviousCapture && !IsLast) {
2180+ // No previous capture and not the last capture: remove current and next comma.
2181+ FixItRange = SourceRange (
2182+ CaptureRange.getBegin (), getLocForEndOfToken (CaptureRange.getEnd ()));
2183+ } else if (CurHasPreviousCapture && !IsLast) {
2184+ // Previous capture exists and not the last: remove current and preceding comma.
2185+ FixItRange = SourceRange (
2186+ getLocForEndOfToken (PrevCaptureLoc), CaptureRange.getEnd ());
2187+ } else if (CurHasPreviousCapture && IsLast) {
2188+ // Last capture: remove only the current capture.
2189+ FixItRange = CaptureRange;
21742190 }
2191+ }
2192+
2193+ IsCaptureUsed = !DiagnoseUnusedLambdaCapture (FixItRange, From);
2194+ }
2195+ }
21752196
21762197 if (CaptureRange.isValid ()) {
21772198 CurHasPreviousCapture |= IsCaptureUsed;
0 commit comments