@@ -3352,6 +3352,7 @@ ExprResult Sema::BuildDeclarationNameExpr(
33523352 case Decl::VarTemplateSpecialization:
33533353 case Decl::VarTemplatePartialSpecialization:
33543354 case Decl::Decomposition:
3355+ case Decl::Binding:
33553356 case Decl::OMPCapturedExpr:
33563357 // In C, "extern void blah;" is valid and is an r-value.
33573358 if (!getLangOpts().CPlusPlus && !type.hasQualifiers() &&
@@ -3371,20 +3372,13 @@ ExprResult Sema::BuildDeclarationNameExpr(
33713372 // potentially-evaluated contexts? Since the variable isn't actually
33723373 // captured in an unevaluated context, it seems that the answer is no.
33733374 if (!isUnevaluatedContext()) {
3374- QualType CapturedType = getCapturedDeclRefType(cast<VarDecl >(VD), Loc);
3375+ QualType CapturedType = getCapturedDeclRefType(cast<ValueDecl >(VD), Loc);
33753376 if (!CapturedType.isNull())
33763377 type = CapturedType;
33773378 }
3378-
33793379 break;
33803380 }
33813381
3382- case Decl::Binding:
3383- // These are always lvalues.
3384- valueKind = VK_LValue;
3385- type = type.getNonReferenceType();
3386- break;
3387-
33883382 case Decl::Function: {
33893383 if (unsigned BID = cast<FunctionDecl>(VD)->getBuiltinID()) {
33903384 if (!Context.BuiltinInfo.isDirectlyAddressable(BID)) {
@@ -13297,11 +13291,24 @@ static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) {
1329713291 if (!DRE) return NCCK_None;
1329813292 if (!DRE->refersToEnclosingVariableOrCapture()) return NCCK_None;
1329913293
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?");
1330513312
1330613313 // Decide whether the first capture was for a block or a lambda.
1330713314 DeclContext *DC = S.CurContext, *Prev = nullptr;
@@ -13310,16 +13317,16 @@ static NonConstCaptureKind isReferenceToNonConstCapture(Sema &S, Expr *E) {
1331013317 // For init-capture, it is possible that the variable belongs to the
1331113318 // template pattern of the current context.
1331213319 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())
1331513322 break;
13316- if (DC == var ->getDeclContext())
13323+ if (DC == Var ->getDeclContext())
1331713324 break;
1331813325 Prev = DC;
1331913326 DC = DC->getParent();
1332013327 }
1332113328 // Unless we have an init-capture, we've gone one step too far.
13322- if (!var ->isInitCapture())
13329+ if (!Var ->isInitCapture())
1332313330 DC = Prev;
1332413331 return (isa<BlockDecl>(DC) ? NCCK_Block : NCCK_Lambda);
1332513332}
@@ -19247,6 +19254,8 @@ bool Sema::NeedToCaptureVariable(ValueDecl *Var, SourceLocation Loc) {
1924719254}
1924819255
1924919256QualType Sema::getCapturedDeclRefType(ValueDecl *Var, SourceLocation Loc) {
19257+ assert(Var && "Null value cannot be captured");
19258+
1925019259 QualType CaptureType;
1925119260 QualType DeclRefType;
1925219261
0 commit comments