From d3b672c38545de350a09d06fa19bd0f7589d9345 Mon Sep 17 00:00:00 2001 From: Douglas Gregor Date: Thu, 16 Feb 2012 01:06:16 +0000 Subject: Implicitly define a lambda's conversion functions (to function pointers and block pointers). We use dummy definitions to keep the invariant that an implicit, used definition has a body; IR generation will substitute the actual contents, since they can't be represented as C++. For the block pointer case, compute the copy-initialization needed to capture the lambda object in the block, which IR generation will need later. llvm-svn: 150645 --- clang/lib/Sema/SemaDeclCXX.cpp | 55 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) (limited to 'clang/lib/Sema/SemaDeclCXX.cpp') diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp index 447a4b42572..66ec800c726 100644 --- a/clang/lib/Sema/SemaDeclCXX.cpp +++ b/clang/lib/Sema/SemaDeclCXX.cpp @@ -9050,7 +9050,60 @@ bool Sema::isImplicitlyDeleted(FunctionDecl *FD) { (FD->isDefaulted() || FD->isImplicit()) && isa(FD); } - + +void Sema::DefineImplicitLambdaToFunctionPointerConversion( + SourceLocation CurrentLocation, + CXXConversionDecl *Conv) +{ + Conv->setUsed(); + + ImplicitlyDefinedFunctionScope Scope(*this, Conv); + DiagnosticErrorTrap Trap(Diags); + + // Introduce a bogus body, which IR generation will override anyway. + Conv->setBody(new (Context) CompoundStmt(Context, 0, 0, Conv->getLocation(), + Conv->getLocation())); + + if (ASTMutationListener *L = getASTMutationListener()) { + L->CompletedImplicitDefinition(Conv); + } +} + +void Sema::DefineImplicitLambdaToBlockPointerConversion( + SourceLocation CurrentLocation, + CXXConversionDecl *Conv) +{ + Conv->setUsed(); + + ImplicitlyDefinedFunctionScope Scope(*this, Conv); + DiagnosticErrorTrap Trap(Diags); + + // Copy-initialize the lambda object as needed to capture + Expr *This = ActOnCXXThis(CurrentLocation).take(); + Expr *DerefThis =CreateBuiltinUnaryOp(CurrentLocation, UO_Deref, This).take(); + ExprResult Init = PerformCopyInitialization( + InitializedEntity::InitializeBlock(CurrentLocation, + DerefThis->getType(), + /*NRVO=*/false), + CurrentLocation, DerefThis); + if (!Init.isInvalid()) + Init = ActOnFinishFullExpr(Init.take()); + + if (!Init.isInvalid()) + Conv->setLambdaToBlockPointerCopyInit(Init.take()); + else { + Diag(CurrentLocation, diag::note_lambda_to_block_conv); + } + + // Introduce a bogus body, which IR generation will override anyway. + Conv->setBody(new (Context) CompoundStmt(Context, 0, 0, Conv->getLocation(), + Conv->getLocation())); + + if (ASTMutationListener *L = getASTMutationListener()) { + L->CompletedImplicitDefinition(Conv); + } +} + ExprResult Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, CXXConstructorDecl *Constructor, -- cgit v1.2.3