summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaLambda.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/SemaLambda.cpp')
-rw-r--r--clang/lib/Sema/SemaLambda.cpp70
1 files changed, 55 insertions, 15 deletions
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index f6c9dee2a08..6d487cc8325 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -843,19 +843,10 @@ VarDecl *Sema::createLambdaInitCaptureVarDecl(SourceLocation Loc,
return NewVD;
}
-FieldDecl *Sema::buildInitCaptureField(LambdaScopeInfo *LSI, VarDecl *Var) {
- FieldDecl *Field = FieldDecl::Create(
- Context, LSI->Lambda, Var->getLocation(), Var->getLocation(),
- nullptr, Var->getType(), Var->getTypeSourceInfo(), nullptr, false,
- ICIS_NoInit);
- Field->setImplicit(true);
- Field->setAccess(AS_private);
- LSI->Lambda->addDecl(Field);
-
+void Sema::addInitCapture(LambdaScopeInfo *LSI, VarDecl *Var) {
LSI->addCapture(Var, /*isBlock*/false, Var->getType()->isReferenceType(),
/*isNested*/false, Var->getLocation(), SourceLocation(),
Var->getType(), Var->getInit(), /*Invalid*/false);
- return Field;
}
void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
@@ -1182,7 +1173,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
}
if (C->Init.isUsable()) {
- buildInitCaptureField(LSI, Var);
+ addInitCapture(LSI, Var);
} else {
TryCaptureKind Kind = C->Kind == LCK_ByRef ? TryCapture_ExplicitByRef :
TryCapture_ExplicitByVal;
@@ -1539,6 +1530,54 @@ bool Sema::DiagnoseUnusedLambdaCapture(SourceRange CaptureRange,
return true;
}
+/// Create a field within the lambda class or captured statement record for the
+/// given capture.
+FieldDecl *Sema::BuildCaptureField(RecordDecl *RD,
+ const sema::Capture &Capture) {
+ SourceLocation Loc = Capture.getLocation();
+ QualType FieldType = Capture.getCaptureType();
+
+ TypeSourceInfo *TSI = nullptr;
+ if (Capture.isVariableCapture()) {
+ auto *Var = Capture.getVariable();
+ if (Var->isInitCapture())
+ TSI = Capture.getVariable()->getTypeSourceInfo();
+ }
+
+ // FIXME: Should we really be doing this? A null TypeSourceInfo seems more
+ // appropriate, at least for an implicit capture.
+ if (!TSI)
+ TSI = Context.getTrivialTypeSourceInfo(FieldType, Loc);
+
+ // Build the non-static data member.
+ FieldDecl *Field =
+ FieldDecl::Create(Context, RD, Loc, Loc, nullptr, FieldType, TSI, nullptr,
+ false, ICIS_NoInit);
+ // If the variable being captured has an invalid type, mark the class as
+ // invalid as well.
+ if (!FieldType->isDependentType()) {
+ if (RequireCompleteType(Loc, FieldType, diag::err_field_incomplete)) {
+ RD->setInvalidDecl();
+ Field->setInvalidDecl();
+ } else {
+ NamedDecl *Def;
+ FieldType->isIncompleteType(&Def);
+ if (Def && Def->isInvalidDecl()) {
+ RD->setInvalidDecl();
+ Field->setInvalidDecl();
+ }
+ }
+ }
+ Field->setImplicit(true);
+ Field->setAccess(AS_private);
+ RD->addDecl(Field);
+
+ if (Capture.isVLATypeCapture())
+ Field->setCapturedVLAType(Capture.getCapturedVLAType());
+
+ return Field;
+}
+
ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
LambdaScopeInfo *LSI) {
// Collect information from the lambda scope.
@@ -1576,14 +1615,12 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
PopExpressionEvaluationContext();
- // Translate captures.
- auto CurField = Class->field_begin();
// True if the current capture has a used capture or default before it.
bool CurHasPreviousCapture = CaptureDefault != LCD_None;
SourceLocation PrevCaptureLoc = CurHasPreviousCapture ?
CaptureDefaultLoc : IntroducerRange.getBegin();
- for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I, ++CurField) {
+ for (unsigned I = 0, N = LSI->Captures.size(); I != N; ++I) {
const Capture &From = LSI->Captures[I];
if (From.isInvalid())
@@ -1626,6 +1663,9 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
PrevCaptureLoc = CaptureRange.getEnd();
}
+ // Add a FieldDecl for the capture.
+ FieldDecl *Field = BuildCaptureField(Class, From);
+
// Handle 'this' capture.
if (From.isThisCapture()) {
// Capturing 'this' implicitly with a default of '[=]' is deprecated,
@@ -1659,7 +1699,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc,
Expr *Init = From.getInitExpr();
if (!Init) {
auto InitResult = performLambdaVarCaptureInitialization(
- *this, From, *CurField, CaptureDefaultLoc, IsImplicit);
+ *this, From, Field, CaptureDefaultLoc, IsImplicit);
if (InitResult.isInvalid())
return ExprError();
Init = InitResult.get();
OpenPOWER on IntegriCloud