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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits