@@ -3352,6 +3352,7 @@ ExprResult Sema::BuildDeclarationNameExpr(
3352
3352
case Decl::VarTemplateSpecialization:
3353
3353
case Decl::VarTemplatePartialSpecialization:
3354
3354
case Decl::Decomposition:
3355
+ case Decl::Binding:
3355
3356
case Decl::OMPCapturedExpr:
3356
3357
// In C, "extern void blah;" is valid and is an r-value.
3357
3358
if (!getLangOpts().CPlusPlus && !type.hasQualifiers() &&
@@ -3371,20 +3372,13 @@ ExprResult Sema::BuildDeclarationNameExpr(
3371
3372
// potentially-evaluated contexts? Since the variable isn't actually
3372
3373
// captured in an unevaluated context, it seems that the answer is no.
3373
3374
if (!isUnevaluatedContext()) {
3374
- QualType CapturedType = getCapturedDeclRefType(cast<VarDecl >(VD), Loc);
3375
+ QualType CapturedType = getCapturedDeclRefType(cast<ValueDecl >(VD), Loc);
3375
3376
if (!CapturedType.isNull())
3376
3377
type = CapturedType;
3377
3378
}
3378
-
3379
3379
break;
3380
3380
}
3381
3381
3382
- case Decl::Binding:
3383
- // These are always lvalues.
3384
- valueKind = VK_LValue;
3385
- type = type.getNonReferenceType();
3386
- break;
3387
-
3388
3382
case Decl::Function: {
3389
3383
if (unsigned BID = cast<FunctionDecl>(VD)->getBuiltinID()) {
3390
3384
if (!Context.BuiltinInfo.isDirectlyAddressable(BID)) {
@@ -13297,11 +13291,24 @@ static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) {
13297
13291
if (!DRE) return NCCK_None;
13298
13292
if (!DRE->refersToEnclosingVariableOrCapture()) return NCCK_None;
13299
13293
13300
- // The declaration must be a variable which is not declared 'const'.
13301
- VarDecl *var = dyn_cast<VarDecl>(DRE->getDecl());
13302
- if (!var) return NCCK_None;
13303
- if (var->getType().isConstQualified()) return NCCK_None;
13304
- assert(var->hasLocalStorage() && "capture added 'const' to non-local?");
13294
+ ValueDecl *Value = dyn_cast<ValueDecl>(DRE->getDecl());
13295
+
13296
+ // The declaration must be a value which is not declared 'const'.
13297
+ if (!Value || Value->getType().isConstQualified())
13298
+ return NCCK_None;
13299
+
13300
+ BindingDecl *Binding = dyn_cast<BindingDecl>(Value);
13301
+ if (Binding) {
13302
+ assert(S.getLangOpts().CPlusPlus && "BindingDecl outside of C++?");
13303
+ assert(!isa<BlockDecl>(Binding->getDeclContext()));
13304
+ return NCCK_Lambda;
13305
+ }
13306
+
13307
+ VarDecl *Var = dyn_cast<VarDecl>(Value);
13308
+ if (!Var)
13309
+ return NCCK_None;
13310
+
13311
+ assert(Var->hasLocalStorage() && "capture added 'const' to non-local?");
13305
13312
13306
13313
// Decide whether the first capture was for a block or a lambda.
13307
13314
DeclContext *DC = S.CurContext, *Prev = nullptr;
@@ -13310,16 +13317,16 @@ static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) {
13310
13317
// For init-capture, it is possible that the variable belongs to the
13311
13318
// template pattern of the current context.
13312
13319
if (auto *FD = dyn_cast<FunctionDecl>(DC))
13313
- if (var ->isInitCapture() &&
13314
- FD->getTemplateInstantiationPattern() == var ->getDeclContext())
13320
+ if (Var ->isInitCapture() &&
13321
+ FD->getTemplateInstantiationPattern() == Var ->getDeclContext())
13315
13322
break;
13316
- if (DC == var ->getDeclContext())
13323
+ if (DC == Var ->getDeclContext())
13317
13324
break;
13318
13325
Prev = DC;
13319
13326
DC = DC->getParent();
13320
13327
}
13321
13328
// Unless we have an init-capture, we've gone one step too far.
13322
- if (!var ->isInitCapture())
13329
+ if (!Var ->isInitCapture())
13323
13330
DC = Prev;
13324
13331
return (isa<BlockDecl>(DC) ? NCCK_Block : NCCK_Lambda);
13325
13332
}
@@ -19247,6 +19254,8 @@ bool Sema::NeedToCaptureVariable(ValueDecl *Var, SourceLocation Loc) {
19247
19254
}
19248
19255
19249
19256
QualType Sema::getCapturedDeclRefType(ValueDecl *Var, SourceLocation Loc) {
19257
+ assert(Var && "Null value cannot be captured");
19258
+
19250
19259
QualType CaptureType;
19251
19260
QualType DeclRefType;
19252
19261
0 commit comments