Skip to content

Commit ff42abb

Browse files
authored
Update SemaLambda.cpp
1 parent c355082 commit ff42abb

File tree

1 file changed

+66
-45
lines changed

1 file changed

+66
-45
lines changed

clang/lib/Sema/SemaLambda.cpp

Lines changed: 66 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)