[cfe-commits] r143399 - in /cfe/trunk: lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGExpr.cpp test/CodeGenCXX/block-rvalue-reference-capture.cpp
Fariborz Jahanian
fjahanian at apple.com
Mon Oct 31 16:44:33 PDT 2011
Author: fjahanian
Date: Mon Oct 31 18:44:33 2011
New Revision: 143399
URL: http://llvm.org/viewvc/llvm-project?rev=143399&view=rev
Log:
Adds IRGen support for captured rvalue references in blocks.
In this case, temporary value is copied into block descriptor
as their own copy to work on. // rdar://9971124
Added:
cfe/trunk/test/CodeGenCXX/block-rvalue-reference-capture.cpp
Modified:
cfe/trunk/lib/CodeGen/CGBlocks.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
Modified: cfe/trunk/lib/CodeGen/CGBlocks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGBlocks.cpp?rev=143399&r1=143398&r2=143399&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGBlocks.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGBlocks.cpp Mon Oct 31 18:44:33 2011
@@ -380,13 +380,18 @@
}
}
- CharUnits size = C.getTypeSizeInChars(variable->getType());
- CharUnits align = C.getDeclAlign(variable);
+ bool IsRValReference = variable->getType()->isRValueReferenceType();
+ QualType VT =
+ IsRValReference ? variable->getType()->getPointeeType()
+ : variable->getType();
+ CharUnits size = C.getTypeSizeInChars(VT);
+ CharUnits align = C.getDeclAlign(variable, IsRValReference);
+
maxFieldAlign = std::max(maxFieldAlign, align);
llvm::Type *llvmType =
- CGM.getTypes().ConvertTypeForMem(variable->getType());
-
+ CGM.getTypes().ConvertTypeForMem(VT);
+
layout.push_back(BlockLayoutChunk(align, size, &*ci, llvmType));
}
@@ -594,30 +599,32 @@
EmitSynthesizedCXXCopyCtor(blockField, src, copyExpr);
// If it's a reference variable, copy the reference into the block field.
- } else if (type->isReferenceType()) {
+ } else if (type->isReferenceType() && !type->isRValueReferenceType()) {
Builder.CreateStore(Builder.CreateLoad(src, "ref.val"), blockField);
// Otherwise, fake up a POD copy into the block field.
} else {
+ QualType VT =
+ (!type->isRValueReferenceType()) ? type : type->getPointeeType();
// Fake up a new variable so that EmitScalarInit doesn't think
// we're referring to the variable in its own initializer.
ImplicitParamDecl blockFieldPseudoVar(/*DC*/ 0, SourceLocation(),
- /*name*/ 0, type);
+ /*name*/ 0, VT);
// We use one of these or the other depending on whether the
// reference is nested.
- DeclRefExpr notNested(const_cast<VarDecl*>(variable), type, VK_LValue,
+ DeclRefExpr notNested(const_cast<VarDecl*>(variable), VT, VK_LValue,
SourceLocation());
- BlockDeclRefExpr nested(const_cast<VarDecl*>(variable), type,
+ BlockDeclRefExpr nested(const_cast<VarDecl*>(variable), VT,
VK_LValue, SourceLocation(), /*byref*/ false);
Expr *declRef =
(ci->isNested() ? static_cast<Expr*>(&nested) : ¬Nested);
- ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, type, CK_LValueToRValue,
+ ImplicitCastExpr l2r(ImplicitCastExpr::OnStack, VT, CK_LValueToRValue,
declRef, VK_RValue);
EmitExprAsInit(&l2r, &blockFieldPseudoVar,
- MakeAddrLValue(blockField, type,
+ MakeAddrLValue(blockField, VT,
getContext().getDeclAlign(variable)
.getQuantity()),
/*captured by init*/ false);
@@ -789,7 +796,8 @@
variable->getNameAsString());
}
- if (variable->getType()->isReferenceType())
+ if (variable->getType()->isReferenceType() &&
+ !variable->getType()->isRValueReferenceType())
addr = Builder.CreateLoad(addr, "ref.tmp");
return addr;
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=143399&r1=143398&r2=143399&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Mon Oct 31 18:44:33 2011
@@ -1409,8 +1409,10 @@
}
LValue CodeGenFunction::EmitBlockDeclRefLValue(const BlockDeclRefExpr *E) {
+ bool RefAsPointee =
+ E->getDecl()->getType()->isRValueReferenceType() ? true : false;
unsigned Alignment =
- getContext().getDeclAlign(E->getDecl()).getQuantity();
+ getContext().getDeclAlign(E->getDecl(), RefAsPointee).getQuantity();
return MakeAddrLValue(GetAddrOfBlockDecl(E), E->getType(), Alignment);
}
Added: cfe/trunk/test/CodeGenCXX/block-rvalue-reference-capture.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/block-rvalue-reference-capture.cpp?rev=143399&view=auto
==============================================================================
--- cfe/trunk/test/CodeGenCXX/block-rvalue-reference-capture.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/block-rvalue-reference-capture.cpp Mon Oct 31 18:44:33 2011
@@ -0,0 +1,16 @@
+// RUN: %clang_cc1 %s -std=c++11 -fblocks -triple x86_64-apple-darwin -emit-llvm -o - | FileCheck %s
+// rdar://9971124
+
+int foo(int && i)
+{
+ return ^{ return i; }();
+}
+
+int main() {
+ return foo(100);
+}
+
+// CHECK: [[B:%.*]] = bitcast i8* [[BD:%.*]] to <{ {{.*}} i32 }>*
+// CHECK: [[C:%.*]] = getelementptr inbounds <{ {{.*}} i32 }>* [[B]]
+// CHECK: [[R:%.*]] = load i32* [[C]], align 4
+// CHECK: ret i32 [[R]]
More information about the cfe-commits
mailing list