diff options
author | Douglas Gregor <dgregor@apple.com> | 2012-02-16 01:06:16 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2012-02-16 01:06:16 +0000 |
commit | d3b672c38545de350a09d06fa19bd0f7589d9345 (patch) | |
tree | a36c3c7254e9210b3893f775752d255c5f6fea6b /clang/lib/Sema/SemaDeclCXX.cpp | |
parent | 515a60daff46d2a227f42d01da299b54aa232e84 (diff) | |
download | bcm5719-llvm-d3b672c38545de350a09d06fa19bd0f7589d9345.tar.gz bcm5719-llvm-d3b672c38545de350a09d06fa19bd0f7589d9345.zip |
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
Diffstat (limited to 'clang/lib/Sema/SemaDeclCXX.cpp')
-rw-r--r-- | clang/lib/Sema/SemaDeclCXX.cpp | 55 |
1 files changed, 54 insertions, 1 deletions
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<CXXMethodDecl>(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, |