summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/Sema/SemaExpr.cpp17
-rw-r--r--clang/lib/Sema/SemaLambda.cpp27
-rw-r--r--clang/lib/Sema/TreeTransform.h28
3 files changed, 44 insertions, 28 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5746a102b71..72b61b8e584 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -14579,6 +14579,7 @@ namespace {
// Make sure we redo semantic analysis
bool AlwaysRebuild() { return true; }
+ bool ReplacingOriginal() { return true; }
// We need to special-case DeclRefExprs referring to FieldDecls which
// are not part of a member pointer formation; normal TreeTransforming
@@ -14605,10 +14606,11 @@ namespace {
return BaseTransform::TransformUnaryOperator(E);
}
- ExprResult TransformLambdaExpr(LambdaExpr *E) {
- // Lambdas never need to be transformed.
- return E;
- }
+ // The body of a lambda-expression is in a separate expression evaluation
+ // context so never needs to be transformed.
+ // FIXME: Ideally we wouldn't transform the closure type either, and would
+ // just recreate the capture expressions and lambda expression.
+ StmtResult TransformLambdaBody(Stmt *Body) { return Body; }
};
}
@@ -14715,13 +14717,6 @@ void Sema::PopExpressionEvaluationContext() {
for (const auto *L : Rec.Lambdas)
Diag(L->getBeginLoc(), D);
- } else {
- // Mark the capture expressions odr-used. This was deferred
- // during lambda expression creation.
- for (auto *Lambda : Rec.Lambdas) {
- for (auto *C : Lambda->capture_inits())
- MarkDeclarationsReferencedInExpr(C);
- }
}
}
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 4b832f56530..ccc8f6f42a5 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -367,12 +367,11 @@ Sema::ExpressionEvaluationContextRecord::getMangleNumberingContext(
return *MangleNumbering;
}
-CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
- SourceRange IntroducerRange,
- TypeSourceInfo *MethodTypeInfo,
- SourceLocation EndLoc,
- ArrayRef<ParmVarDecl *> Params,
- const bool IsConstexprSpecified) {
+CXXMethodDecl *Sema::startLambdaDefinition(
+ CXXRecordDecl *Class, SourceRange IntroducerRange,
+ TypeSourceInfo *MethodTypeInfo, SourceLocation EndLoc,
+ ArrayRef<ParmVarDecl *> Params, const bool IsConstexprSpecified,
+ Optional<std::pair<unsigned, Decl *>> Mangling) {
QualType MethodType = MethodTypeInfo->getType();
TemplateParameterList *TemplateParams =
getGenericLambdaTemplateParameterList(getCurLambda(), *this);
@@ -438,12 +437,16 @@ CXXMethodDecl *Sema::startLambdaDefinition(CXXRecordDecl *Class,
P->setOwningFunction(Method);
}
- Decl *ManglingContextDecl;
- if (MangleNumberingContext *MCtx =
- getCurrentMangleNumberContext(Class->getDeclContext(),
- ManglingContextDecl)) {
- unsigned ManglingNumber = MCtx->getManglingNumber(Method);
- Class->setLambdaMangling(ManglingNumber, ManglingContextDecl);
+ if (Mangling) {
+ Class->setLambdaMangling(Mangling->first, Mangling->second);
+ } else {
+ Decl *ManglingContextDecl;
+ if (MangleNumberingContext *MCtx =
+ getCurrentMangleNumberContext(Class->getDeclContext(),
+ ManglingContextDecl)) {
+ unsigned ManglingNumber = MCtx->getManglingNumber(Method);
+ Class->setLambdaMangling(ManglingNumber, ManglingContextDecl);
+ }
}
return Method;
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 6620885f239..f46193502b6 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -148,6 +148,11 @@ public:
/// statement node appears at most once in its containing declaration.
bool AlwaysRebuild() { return SemaRef.ArgumentPackSubstitutionIndex != -1; }
+ /// Whether the transformation is forming an expression or statement that
+ /// replaces the original. In this case, we'll reuse mangling numbers from
+ /// existing lambdas.
+ bool ReplacingOriginal() { return false; }
+
/// Returns the location of the entity being transformed, if that
/// information was not available elsewhere in the AST.
///
@@ -654,6 +659,9 @@ public:
Optional<unsigned> NumExpansions,
bool ExpectParameterPack);
+ /// Transform the body of a lambda-expression.
+ StmtResult TransformLambdaBody(Stmt *Body);
+
QualType TransformReferenceType(TypeLocBuilder &TLB, ReferenceTypeLoc TL);
StmtResult TransformCompoundStmt(CompoundStmt *S, bool IsStmtExpr);
@@ -11197,8 +11205,6 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
auto SubstInitCapture = [&](SourceLocation EllipsisLoc,
Optional<unsigned> NumExpansions) {
- EnterExpressionEvaluationContext EEEC(
- getSema(), Sema::ExpressionEvaluationContext::PotentiallyEvaluated);
ExprResult NewExprInitResult = getDerived().TransformInitializer(
OldVD->getInit(), OldVD->getInitStyle() == VarDecl::CallInit);
@@ -11289,19 +11295,25 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
LSI->GLTemplateParameterList = TPL;
// Create the local class that will describe the lambda.
+ CXXRecordDecl *OldClass = E->getLambdaClass();
CXXRecordDecl *Class
= getSema().createLambdaClosureType(E->getIntroducerRange(),
NewCallOpTSI,
/*KnownDependent=*/false,
E->getCaptureDefault());
- getDerived().transformedLocalDecl(E->getLambdaClass(), {Class});
+ getDerived().transformedLocalDecl(OldClass, {Class});
+
+ Optional<std::pair<unsigned, Decl*>> Mangling;
+ if (getDerived().ReplacingOriginal())
+ Mangling = std::make_pair(OldClass->getLambdaManglingNumber(),
+ OldClass->getLambdaContextDecl());
// Build the call operator.
CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition(
Class, E->getIntroducerRange(), NewCallOpTSI,
E->getCallOperator()->getEndLoc(),
NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
- E->getCallOperator()->isConstexpr());
+ E->getCallOperator()->isConstexpr(), Mangling);
LSI->CallOperator = NewCallOperator;
@@ -11465,7 +11477,7 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
// Instantiate the body of the lambda expression.
StmtResult Body =
- Invalid ? StmtError() : getDerived().TransformStmt(E->getBody());
+ Invalid ? StmtError() : getDerived().TransformLambdaBody(E->getBody());
// ActOnLambda* will pop the function scope for us.
FuncScopeCleanup.disable();
@@ -11490,6 +11502,12 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
}
template<typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformLambdaBody(Stmt *S) {
+ return TransformStmt(S);
+}
+
+template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
CXXUnresolvedConstructExpr *E) {
OpenPOWER on IntegriCloud