diff options
Diffstat (limited to 'lib/Sema')
-rw-r--r-- | lib/Sema/Sema.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 6 | ||||
-rw-r--r-- | lib/Sema/SemaLambda.cpp | 33 | ||||
-rw-r--r-- | lib/Sema/TreeTransform.h | 6 |
4 files changed, 40 insertions, 7 deletions
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp index 716ffd131b..6a83518bc0 100644 --- a/lib/Sema/Sema.cpp +++ b/lib/Sema/Sema.cpp @@ -111,7 +111,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, &Context); ExprEvalContexts.push_back( - ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0, false)); + ExpressionEvaluationContextRecord(PotentiallyEvaluated, 0, false, 0)); FunctionScopes.push_back(new FunctionScopeInfo(Diags)); } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 3f1fabcaa3..1008a3ab43 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -9275,11 +9275,13 @@ ExprResult Sema::TranformToPotentiallyEvaluated(Expr *E) { } void -Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext) { +Sema::PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, + Decl *LambdaContextDecl) { ExprEvalContexts.push_back( ExpressionEvaluationContextRecord(NewContext, ExprCleanupObjects.size(), - ExprNeedsCleanups)); + ExprNeedsCleanups, + LambdaContextDecl)); ExprNeedsCleanups = false; if (!MaybeODRUseExprs.empty()) std::swap(MaybeODRUseExprs, ExprEvalContexts.back().SavedMaybeODRUseExprs); diff --git a/lib/Sema/SemaLambda.cpp b/lib/Sema/SemaLambda.cpp index 6d54d403aa..047a28436f 100644 --- a/lib/Sema/SemaLambda.cpp +++ b/lib/Sema/SemaLambda.cpp @@ -485,6 +485,7 @@ static void addBlockPointerConversion(Sema &S, ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, Scope *CurScope, llvm::Optional<unsigned> ManglingNumber, + Decl *ContextDecl, bool IsInstantiation) { // Leave the expression-evaluation context. DiscardCleanupsInEvaluationContext(); @@ -638,8 +639,34 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, // If we don't already have a mangling number for this lambda expression, // allocate one now. if (!ManglingNumber) { - // FIXME: Default arguments, data member initializers are special. - ManglingNumber = Context.getLambdaManglingNumber(CallOperator); + ContextDecl = ExprEvalContexts.back().LambdaContextDecl; + + // FIXME: Data member initializers. + enum ContextKind { + Normal, + DefaultArgument + } Kind = Normal; + + // Default arguments of member function parameters that appear in a class + // definition receive special treatment. Identify them. + if (ParmVarDecl *Param = dyn_cast_or_null<ParmVarDecl>(ContextDecl)) { + if (const DeclContext *LexicalDC + = Param->getDeclContext()->getLexicalParent()) + if (LexicalDC->isRecord()) + Kind = DefaultArgument; + } + + switch (Kind) { + case Normal: + ManglingNumber = Context.getLambdaManglingNumber(CallOperator); + ContextDecl = 0; + break; + + case DefaultArgument: + ManglingNumber = ExprEvalContexts.back().getLambdaMangleContext() + .getManglingNumber(CallOperator); + break; + } } LambdaExpr *Lambda = LambdaExpr::Create(Context, Class, IntroducerRange, @@ -647,7 +674,7 @@ ExprResult Sema::ActOnLambdaExpr(SourceLocation StartLoc, Stmt *Body, ExplicitParams, ExplicitResultType, CaptureInits, ArrayIndexVars, ArrayIndexStarts, Body->getLocEnd(), - *ManglingNumber); + *ManglingNumber, ContextDecl); // C++11 [expr.prim.lambda]p2: // A lambda-expression shall not appear in an unevaluated operand diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h index 7e095f7336..7e775f55e0 100644 --- a/lib/Sema/TreeTransform.h +++ b/lib/Sema/TreeTransform.h @@ -7768,10 +7768,14 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) { /*IsInstantiation=*/true); return ExprError(); } - + + // Note: Once a lambda mangling number and context declaration have been + // assigned, they never change. unsigned ManglingNumber = E->getLambdaClass()->getLambdaManglingNumber(); + Decl *ContextDecl = E->getLambdaClass()->getLambdaContextDecl(); return getSema().ActOnLambdaExpr(E->getLocStart(), Body.take(), /*CurScope=*/0, ManglingNumber, + ContextDecl, /*IsInstantiation=*/true); } |