summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/SemaDeclCXX.cpp
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2012-02-16 01:06:16 +0000
committerDouglas Gregor <dgregor@apple.com>2012-02-16 01:06:16 +0000
commitd3b672c38545de350a09d06fa19bd0f7589d9345 (patch)
treea36c3c7254e9210b3893f775752d255c5f6fea6b /clang/lib/Sema/SemaDeclCXX.cpp
parent515a60daff46d2a227f42d01da299b54aa232e84 (diff)
downloadbcm5719-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.cpp55
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,
OpenPOWER on IntegriCloud