@@ -2022,6 +2022,7 @@ bool Sema::CaptureHasSideEffects(const Capture &From) {
2022
2022
}
2023
2023
2024
2024
bool Sema::DiagnoseUnusedLambdaCapture (SourceRange CaptureRange,
2025
+ SourceRange FixItRange,
2025
2026
const Capture &From) {
2026
2027
if (CaptureHasSideEffects (From))
2027
2028
return false ;
@@ -2041,7 +2042,12 @@ bool Sema::DiagnoseUnusedLambdaCapture(SourceRange CaptureRange,
2041
2042
else
2042
2043
diag << From.getVariable ();
2043
2044
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;
2045
2051
return true ;
2046
2052
}
2047
2053
@@ -2095,6 +2101,39 @@ FieldDecl *Sema::BuildCaptureField(RecordDecl *RD,
2095
2101
return Field;
2096
2102
}
2097
2103
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
+
2098
2137
ExprResult Sema::BuildLambdaExpr (SourceLocation StartLoc, SourceLocation EndLoc,
2099
2138
LambdaScopeInfo *LSI) {
2100
2139
// Collect information from the lambda scope.
@@ -2162,21 +2201,11 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
2162
2201
IsGenericLambda && From.isNonODRUsed () && From.isInitCapture ();
2163
2202
if (!NonODRUsedInitCapture) {
2164
2203
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);
2180
2209
}
2181
2210
}
2182
2211
0 commit comments