summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/TreeTransform.h
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
-rw-r--r--clang/lib/Sema/TreeTransform.h80
1 files changed, 53 insertions, 27 deletions
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index e9cb95006fe..aa25cbe163a 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -593,9 +593,11 @@ public:
StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
ExprResult TransformCXXNamedCastExpr(CXXNamedCastExpr *E);
-
+
+ typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
/// \brief Transform the captures and body of a lambda expression.
- ExprResult TransformLambdaScope(LambdaExpr *E, CXXMethodDecl *CallOperator);
+ ExprResult TransformLambdaScope(LambdaExpr *E, CXXMethodDecl *CallOperator,
+ ArrayRef<InitCaptureInfoTy> InitCaptureExprsAndTypes);
TemplateParameterList *TransformTemplateParameterList(
TemplateParameterList *TPL) {
@@ -8263,7 +8265,40 @@ TreeTransform<Derived>::TransformCXXTemporaryObjectExpr(
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
-
+
+ // Transform any init-capture expressions before entering the scope of the
+ // lambda body, because they are not semantically within that scope.
+ SmallVector<InitCaptureInfoTy, 8> InitCaptureExprsAndTypes;
+ InitCaptureExprsAndTypes.resize(E->explicit_capture_end() -
+ E->explicit_capture_begin());
+
+ for (LambdaExpr::capture_iterator C = E->capture_begin(),
+ CEnd = E->capture_end();
+ C != CEnd; ++C) {
+ if (!C->isInitCapture())
+ continue;
+ EnterExpressionEvaluationContext EEEC(getSema(),
+ Sema::PotentiallyEvaluated);
+ ExprResult NewExprInitResult = getDerived().TransformInitializer(
+ C->getCapturedVar()->getInit(),
+ C->getCapturedVar()->getInitStyle() == VarDecl::CallInit);
+
+ if (NewExprInitResult.isInvalid())
+ return ExprError();
+ Expr *NewExprInit = NewExprInitResult.get();
+
+ VarDecl *OldVD = C->getCapturedVar();
+ QualType NewInitCaptureType =
+ getSema().performLambdaInitCaptureInitialization(C->getLocation(),
+ OldVD->getType()->isReferenceType(), OldVD->getIdentifier(),
+ NewExprInit);
+ NewExprInitResult = NewExprInit;
+ VarDecl *NewVD = 0;
+ InitCaptureExprsAndTypes[C - E->capture_begin()] =
+ std::make_pair(NewExprInitResult, NewInitCaptureType);
+
+ }
+
LambdaScopeInfo *LSI = getSema().PushLambdaScope();
// Transform the template parameters, and add them to the current
// instantiation scope. The null case is handled correctly.
@@ -8358,31 +8393,17 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
- return getDerived().TransformLambdaScope(E, NewCallOperator);
+ return getDerived().TransformLambdaScope(E, NewCallOperator,
+ InitCaptureExprsAndTypes);
}
template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E,
- CXXMethodDecl *CallOperator) {
+ CXXMethodDecl *CallOperator,
+ ArrayRef<InitCaptureInfoTy> InitCaptureExprsAndTypes) {
bool Invalid = false;
- // Transform any init-capture expressions before entering the scope of the
- // lambda.
- SmallVector<ExprResult, 8> InitCaptureExprs;
- InitCaptureExprs.resize(E->explicit_capture_end() -
- E->explicit_capture_begin());
- for (LambdaExpr::capture_iterator C = E->capture_begin(),
- CEnd = E->capture_end();
- C != CEnd; ++C) {
- if (!C->isInitCapture())
- continue;
- InitCaptureExprs[C - E->capture_begin()] =
- getDerived().TransformInitializer(
- C->getCapturedVar()->getInit(),
- C->getCapturedVar()->getInitStyle() == VarDecl::CallInit);
- }
-
// Introduce the context of the call operator.
Sema::ContextRAII SavedContext(getSema(), CallOperator);
@@ -8415,19 +8436,24 @@ TreeTransform<Derived>::TransformLambdaScope(LambdaExpr *E,
// Rebuild init-captures, including the implied field declaration.
if (C->isInitCapture()) {
- ExprResult Init = InitCaptureExprs[C - E->capture_begin()];
- if (Init.isInvalid()) {
+
+ InitCaptureInfoTy InitExprTypePair =
+ InitCaptureExprsAndTypes[C - E->capture_begin()];
+ ExprResult Init = InitExprTypePair.first;
+ QualType InitQualType = InitExprTypePair.second;
+ if (Init.isInvalid() || InitQualType.isNull()) {
Invalid = true;
continue;
}
VarDecl *OldVD = C->getCapturedVar();
- VarDecl *NewVD = getSema().checkInitCapture(
- C->getLocation(), OldVD->getType()->isReferenceType(),
- OldVD->getIdentifier(), Init.take());
+ VarDecl *NewVD = getSema().createLambdaInitCaptureVarDecl(
+ OldVD->getLocation(), InitExprTypePair.second,
+ OldVD->getIdentifier(), Init.get());
if (!NewVD)
Invalid = true;
- else
+ else {
getDerived().transformedLocalDecl(OldVD, NewVD);
+ }
getSema().buildInitCaptureField(LSI, NewVD);
continue;
}
OpenPOWER on IntegriCloud