@@ -2022,6 +2022,7 @@ bool Sema::CaptureHasSideEffects(const Capture &From) {
20222022}
20232023
20242024bool Sema::DiagnoseUnusedLambdaCapture (SourceRange CaptureRange,
2025+ SourceRange FixItRange,
20252026 const Capture &From) {
20262027 if (CaptureHasSideEffects (From))
20272028 return false ;
@@ -2041,7 +2042,12 @@ bool Sema::DiagnoseUnusedLambdaCapture(SourceRange CaptureRange,
20412042 else
20422043 diag << From.getVariable ();
20432044 diag << From.isNonODRUsed ();
2044- diag << FixItHint::CreateRemoval (CaptureRange);
2045+ // If we were able to resolve the fixit range we'll create a fixit,
2046+ // otherwise we just use the raw capture range for the diagnostic.
2047+ if (FixItRange.isValid ())
2048+ diag << FixItHint::CreateRemoval (FixItRange);
2049+ else
2050+ diag << CaptureRange;
20452051 return true ;
20462052}
20472053
@@ -2095,6 +2101,39 @@ FieldDecl *Sema::BuildCaptureField(RecordDecl *RD,
20952101 return Field;
20962102}
20972103
2104+ static SourceRange
2105+ ConstructFixItRangeForUnusedCapture (Sema &S, SourceRange CaptureRange,
2106+ SourceLocation PrevCaptureLoc,
2107+ bool CurHasPreviousCapture, bool IsLast) {
2108+ if (!CaptureRange.isValid ())
2109+ return SourceRange ();
2110+
2111+ auto GetTrailingEndLocation = [&](SourceLocation StartPoint) {
2112+ SourceRange NextToken = S.getRangeForNextToken (
2113+ StartPoint, /* IncludeMacros=*/ false , /* IncludeComments=*/ true );
2114+ if (!NextToken.isValid ())
2115+ return SourceLocation ();
2116+ // Return the last location preceding the next token
2117+ return NextToken.getBegin ().getLocWithOffset (-1 );
2118+ };
2119+
2120+ if (!CurHasPreviousCapture && !IsLast) {
2121+ // If there are no captures preceding this capture, remove the
2122+ // trailing comma and anything up to the next token
2123+ SourceRange CommaRange =
2124+ S.getRangeForNextToken (CaptureRange.getEnd (), /* IncludeMacros=*/ false ,
2125+ /* IncludeComments=*/ false , tok::comma);
2126+ SourceLocation FixItEnd = GetTrailingEndLocation (CommaRange.getBegin ());
2127+ return SourceRange (CaptureRange.getBegin (), FixItEnd);
2128+ }
2129+
2130+ // Otherwise, remove the comma since the last used capture, and
2131+ // anything up to the next token
2132+ SourceLocation FixItStart = S.getLocForEndOfToken (PrevCaptureLoc);
2133+ SourceLocation FixItEnd = GetTrailingEndLocation (CaptureRange.getEnd ());
2134+ return SourceRange (FixItStart, FixItEnd);
2135+ }
2136+
20982137ExprResult Sema::BuildLambdaExpr (SourceLocation StartLoc, SourceLocation EndLoc,
20992138 LambdaScopeInfo *LSI) {
21002139 // Collect information from the lambda scope.
@@ -2162,21 +2201,11 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
21622201 IsGenericLambda && From.isNonODRUsed () && From.isInitCapture ();
21632202 if (!NonODRUsedInitCapture) {
21642203 bool IsLast = (I + 1 ) == LSI->NumExplicitCaptures ;
2165- SourceRange FixItRange;
2166- if (CaptureRange.isValid ()) {
2167- if (!CurHasPreviousCapture && !IsLast) {
2168- // If there are no captures preceding this capture, remove the
2169- // following comma.
2170- FixItRange = SourceRange (CaptureRange.getBegin (),
2171- getLocForEndOfToken (CaptureRange.getEnd ()));
2172- } else {
2173- // Otherwise, remove the comma since the last used capture.
2174- FixItRange = SourceRange (getLocForEndOfToken (PrevCaptureLoc),
2175- CaptureRange.getEnd ());
2176- }
2177- }
2178-
2179- IsCaptureUsed = !DiagnoseUnusedLambdaCapture (FixItRange, From);
2204+ SourceRange FixItRange = ConstructFixItRangeForUnusedCapture (
2205+ *this , CaptureRange, PrevCaptureLoc, CurHasPreviousCapture,
2206+ IsLast);
2207+ IsCaptureUsed =
2208+ !DiagnoseUnusedLambdaCapture (CaptureRange, FixItRange, From);
21802209 }
21812210 }
21822211
0 commit comments