r362336 - Transform lambda expression captures when transforming an expression to
Richard Smith via cfe-commits
cfe-commits at lists.llvm.org
Sun Jun 2 11:53:44 PDT 2019
Author: rsmith
Date: Sun Jun 2 11:53:44 2019
New Revision: 362336
URL: http://llvm.org/viewvc/llvm-project?rev=362336&view=rev
Log:
Transform lambda expression captures when transforming an expression to
potentially-evaluated.
This ensures that every potentially-evaluated expression is built in a
potentially-evaluated context. No functionality change intended.
Modified:
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaLambda.cpp
cfe/trunk/lib/Sema/TreeTransform.h
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=362336&r1=362335&r2=362336&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sun Jun 2 11:53:44 2019
@@ -5710,12 +5710,12 @@ public:
LambdaCaptureDefault CaptureDefault);
/// Start the definition of a lambda expression.
- CXXMethodDecl *startLambdaDefinition(CXXRecordDecl *Class,
- SourceRange IntroducerRange,
- TypeSourceInfo *MethodType,
- SourceLocation EndLoc,
- ArrayRef<ParmVarDecl *> Params,
- bool IsConstexprSpecified);
+ CXXMethodDecl *
+ startLambdaDefinition(CXXRecordDecl *Class, SourceRange IntroducerRange,
+ TypeSourceInfo *MethodType, SourceLocation EndLoc,
+ ArrayRef<ParmVarDecl *> Params,
+ bool IsConstexprSpecified,
+ Optional<std::pair<unsigned, Decl *>> Mangling = None);
/// Endow the lambda scope info with the relevant properties.
void buildLambdaScope(sema::LambdaScopeInfo *LSI,
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=362336&r1=362335&r2=362336&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Sun Jun 2 11:53:44 2019
@@ -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::PopExpressionEvaluationContex
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);
- }
}
}
Modified: cfe/trunk/lib/Sema/SemaLambda.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLambda.cpp?rev=362336&r1=362335&r2=362336&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLambda.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLambda.cpp Sun Jun 2 11:53:44 2019
@@ -367,12 +367,11 @@ Sema::ExpressionEvaluationContextRecord:
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::startLambdaDefiniti
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;
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=362336&r1=362335&r2=362336&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Sun Jun 2 11:53:44 2019
@@ -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>::TransformLambdaE
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>::TransformLambdaE
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>::TransformLambdaE
// 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>::TransformLambdaE
}
template<typename Derived>
+StmtResult
+TreeTransform<Derived>::TransformLambdaBody(Stmt *S) {
+ return TransformStmt(S);
+}
+
+template<typename Derived>
ExprResult
TreeTransform<Derived>::TransformCXXUnresolvedConstructExpr(
CXXUnresolvedConstructExpr *E) {
More information about the cfe-commits
mailing list