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 >> [email protected] >> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits > _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
