[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) : &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