diff options
Diffstat (limited to 'clang/lib/Sema/TreeTransform.h')
-rw-r--r-- | clang/lib/Sema/TreeTransform.h | 80 |
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; } |