aboutsummaryrefslogtreecommitdiff
path: root/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Sema')
-rw-r--r--lib/Sema/Sema.cpp2
-rw-r--r--lib/Sema/SemaExpr.cpp6
-rw-r--r--lib/Sema/SemaLambda.cpp33
-rw-r--r--lib/Sema/TreeTransform.h6
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);
}