diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaDecl.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExprCXX.cpp | 32 |
4 files changed, 25 insertions, 18 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 9c5bdbea6a..22d2a20d45 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -831,8 +831,10 @@ void Sema::PushBlockScope(Scope *BlockScope, BlockDecl *Block) { BlockScope, Block)); } -void Sema::PushLambdaScope(CXXRecordDecl *Lambda) { - FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda)); +void Sema::PushLambdaScope(CXXRecordDecl *Lambda, + CXXMethodDecl *CallOperator) { + FunctionScopes.push_back(new LambdaScopeInfo(getDiagnostics(), Lambda, + CallOperator)); } void Sema::PopFunctionScopeInfo(const AnalysisBasedWarnings::Policy *WP, diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index ffc7c61872..ed8d8a5d71 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -7236,7 +7236,8 @@ Decl *Sema::ActOnFinishFunctionBody(Decl *dcl, Stmt *Body, computeNRVO(Body, getCurFunction()); } - assert(FD == getCurFunctionDecl() && "Function parsing confused"); + assert((FD == getCurFunctionDecl() || getCurLambda()->CallOperator == FD) && + "Function parsing confused"); } else if (ObjCMethodDecl *MD = dyn_cast_or_null<ObjCMethodDecl>(dcl)) { assert(MD == getCurMethodDecl() && "Method parsing confused"); MD->setBody(Body); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 1829565238..bbf992c219 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9722,8 +9722,6 @@ void Sema::TryCaptureVar(VarDecl *var, SourceLocation loc, // of the copy/move done to move a __block variable to the heap. type.addConst(); - // FIXME: Add an initialized entity for lambda capture. - // FIXME: Won't work for arrays, although we do need this behavior. Expr *declRef = new (Context) DeclRefExpr(var, type, VK_LValue, loc); ExprResult result = PerformCopyInitialization( diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp index cd2c210a39..98ab97808c 100644 --- a/lib/Sema/SemaExprCXX.cpp +++ b/lib/Sema/SemaExprCXX.cpp @@ -4896,6 +4896,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, QualType MethodTy; TypeSourceInfo *MethodTyInfo; bool ExplicitParams = true; + SourceLocation EndLoc; if (ParamInfo.getNumTypeObjects() == 0) { // C++11 [expr.prim.lambda]p4: // If a lambda-expression does not include a lambda-declarator, it is as @@ -4906,6 +4907,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, /*Args=*/0, /*NumArgs=*/0, EPI); MethodTyInfo = Context.getTrivialTypeSourceInfo(MethodTy); ExplicitParams = false; + EndLoc = Intro.Range.getEnd(); } else { assert(ParamInfo.isFunctionDeclarator() && "lambda-declarator is a function"); @@ -4928,6 +4930,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, assert(MethodTyInfo && "no type from lambda-declarator"); MethodTy = MethodTyInfo->getType(); assert(!MethodTy.isNull() && "no type from lambda declarator"); + EndLoc = ParamInfo.getSourceRange().getEnd(); } // C++11 [expr.prim.lambda]p5: @@ -4937,19 +4940,22 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, // trailing-return-type respectively. DeclarationName MethodName = Context.DeclarationNames.getCXXOperatorName(OO_Call); + DeclarationNameLoc MethodNameLoc; + MethodNameLoc.CXXOperatorName.BeginOpNameLoc + = Intro.Range.getBegin().getRawEncoding(); + MethodNameLoc.CXXOperatorName.EndOpNameLoc + = Intro.Range.getEnd().getRawEncoding(); CXXMethodDecl *Method - = CXXMethodDecl::Create(Context, - Class, - ParamInfo.getSourceRange().getEnd(), - DeclarationNameInfo(MethodName, - /*NameLoc=*/SourceLocation()), - MethodTy, - MethodTyInfo, + = CXXMethodDecl::Create(Context, Class, EndLoc, + DeclarationNameInfo(MethodName, + Intro.Range.getBegin(), + MethodNameLoc), + MethodTy, MethodTyInfo, /*isStatic=*/false, SC_None, /*isInline=*/true, /*isConstExpr=*/false, - ParamInfo.getSourceRange().getEnd()); + EndLoc); Method->setAccess(AS_public); Class->addDecl(Method); Method->setLexicalDeclContext(DC); // FIXME: Minor hack. @@ -4963,7 +4969,7 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, PushDeclContext(CurScope, Method); // Introduce the lambda scope. - PushLambdaScope(Class); + PushLambdaScope(Class, Method); LambdaScopeInfo *LSI = getCurLambda(); if (Intro.Default == LCD_ByCopy) LSI->ImpCaptureStyle = LambdaScopeInfo::ImpCap_LambdaByval; @@ -5123,9 +5129,6 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, DiscardCleanupsInEvaluationContext(); PopExpressionEvaluationContext(); - // Leave the context of the lambda. - PopDeclContext(); - // FIXME: End-of-lambda checking // Collect information from the lambda scope. @@ -5184,7 +5187,10 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, break; } - PopFunctionScopeInfo(); + // C++ [expr.prim.lambda]p7: + // The lambda-expression’s compound-statement yields the + // function-body (8.4) of the function call operator [...]. + ActOnFinishFunctionBody(LSI->CallOperator, Body, /*IsInstantation=*/false); } Expr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange, |