[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
Tue Nov 1 07:57:38 PDT 2011
On Oct 31, 2011, at 6:01 PM, Douglas Gregor wrote:
>
> On Oct 31, 2011, at 4:44 PM, Fariborz Jahanian wrote:
>
>> 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
>
> This looks like it only handles the scalar case; what about class types, for which we may need to call a copy constructor to perform the copy?
I am using the same API used for any copying into the block descriptor. I will check it out, but it should work.
- Fariborz
>
> - Doug
>
>
>> 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]]
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
More information about the cfe-commits
mailing list