[cfe-commits] r143399 - in /cfe/trunk: lib/CodeGen/CGBlocks.cpp lib/CodeGen/CGExpr.cpp test/CodeGenCXX/block-rvalue-reference-capture.cpp

Douglas Gregor dgregor at apple.com
Mon Oct 31 18:01:59 PDT 2011


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?

	- 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) : &notNested);
> 
> -      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