From: Fariborz Jahanian Date: Thu, 11 Nov 2010 00:11:38 +0000 (+0000) Subject: Adding couple of Block API, a bug fix and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e27e9d673346056e6ff7dca1d7fb1d75dfd42956;p=clang Adding couple of Block API, a bug fix and a test change, all for blocks. wip. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@118745 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 44e0833daf..33646871e0 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -311,11 +311,10 @@ llvm::Value *CodeGenFunction::BuildBlockLiteralTmp(const BlockExpr *BE) { } const BlockDeclRefExpr *BDRE = cast(E); + Note.RequiresCopying = BlockRequiresCopying(BDRE); + const ValueDecl *VD = BDRE->getDecl(); QualType T = VD->getType(); - - Note.RequiresCopying = BlockRequiresCopying(T); - if (BDRE->isByRef()) { Note.flag = BLOCK_FIELD_IS_BYREF; if (T.isObjCGCWeak()) @@ -563,7 +562,7 @@ void CodeGenFunction::AllocateBlockDecl(const BlockDeclRefExpr *E) { // Don't run the expensive check, unless we have to. if (!BlockHasCopyDispose) if (E->isByRef() - || BlockRequiresCopying(E->getType())) + || BlockRequiresCopying(E)) BlockHasCopyDispose = true; const ValueDecl *D = cast(E->getDecl()); diff --git a/lib/CodeGen/CGBlocks.h b/lib/CodeGen/CGBlocks.h index 743e3c83be..ce721a4640 100644 --- a/lib/CodeGen/CGBlocks.h +++ b/lib/CodeGen/CGBlocks.h @@ -103,6 +103,9 @@ public: bool BlockRequiresCopying(QualType Ty) { return getContext().BlockRequiresCopying(Ty); } + bool BlockRequiresCopying(const BlockDeclRefExpr *E) + { return E->getCopyConstructorExpr() != 0 || + getContext().BlockRequiresCopying(E->getType()); } }; class BlockFunction : public BlockBase { @@ -197,6 +200,9 @@ public: bool BlockRequiresCopying(QualType Ty) { return getContext().BlockRequiresCopying(Ty); } + bool BlockRequiresCopying(const BlockDeclRefExpr *E) + { return E->getCopyConstructorExpr() != 0 || + getContext().BlockRequiresCopying(E->getType()); } }; } // end namespace CodeGen diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 790f8831d2..8da3846f69 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1911,16 +1911,18 @@ Sema::BuildDeclarationNameExpr(const CXXScopeSpec &SS, Expr *E = new (Context) DeclRefExpr(const_cast(BDRE->getDecl()), T, SourceLocation()); - - ExprResult Res = PerformCopyInitialization( + if (T->getAs()) + if (!T->isUnionType()) { + ExprResult Res = PerformCopyInitialization( InitializedEntity::InitializeBlock(VD->getLocation(), T, false), SourceLocation(), Owned(E)); - if (!Res.isInvalid()) { - Res = MaybeCreateCXXExprWithTemporaries(Res.get()); - Expr *Init = Res.takeAs(); - BDRE->setCopyConstructorExpr(Init); + if (!Res.isInvalid()) { + Res = MaybeCreateCXXExprWithTemporaries(Res.get()); + Expr *Init = Res.takeAs(); + BDRE->setCopyConstructorExpr(Init); + } } } } diff --git a/test/CodeGenObjC/block-var-layout.m b/test/CodeGenObjC/block-var-layout.m index 7031224d06..fa131f63be 100644 --- a/test/CodeGenObjC/block-var-layout.m +++ b/test/CodeGenObjC/block-var-layout.m @@ -1,7 +1,5 @@ // RUN: %clang_cc1 -fblocks -fobjc-gc -triple x86_64-apple-darwin -O0 -S %s -o %t-64.s // RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s -// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-gc -triple x86_64-apple-darwin -O0 -S %s -o %t-64.s -// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s struct S { int i1; diff --git a/test/CodeGenObjCXX/block-var-layout.mm b/test/CodeGenObjCXX/block-var-layout.mm new file mode 100644 index 0000000000..0a9a8178e7 --- /dev/null +++ b/test/CodeGenObjCXX/block-var-layout.mm @@ -0,0 +1,150 @@ +// RUN: %clang_cc1 -x objective-c++ -fblocks -fobjc-gc -triple x86_64-apple-darwin -O0 -S %s -o %t-64.s +// RUN: FileCheck -check-prefix LP64 --input-file=%t-64.s %s + + +struct S { + int i1; + id o1; + struct V { + int i2; + id o2; + } v1; + int i3; + id o3; +}; + +__weak id wid; +void x(id y) {} +void y(int a) {} + +void f() { + __block int byref_int = 0; + char ch = 'a'; + char ch1 = 'b'; + char ch2 = 'c'; + short sh = 2; + const id bar = (id)0; + id baz = 0; + __strong void *strong_void_sta; + __block id byref_bab = (id)0; + __block void *bl_var1; + int i; double dob; + + void (^b)() = ^{ + byref_int = sh + ch+ch1+ch2 ; + x(bar); + x(baz); + x((id)strong_void_sta); + x(byref_bab); + }; + b(); + +// Test 2 + void (^c)() = ^{ + byref_int = sh + ch+ch1+ch2 ; + x(bar); + x(baz); + x((id)strong_void_sta); + x(wid); + bl_var1 = 0; + x(byref_bab); + }; + c(); + +// Test 3 +void (^d)() = ^{ + byref_int = sh + ch+ch1+ch2 ; + x(bar); + x(baz); + x(wid); + bl_var1 = 0; + y(i + dob); + x(byref_bab); + }; + d(); + +// Test4 + struct S s2; + void (^e)() = ^{ + x(s2.o1); + }; + e(); +} + +// Test 5 (unions/structs and their nesting): +void Test5() { +struct S5 { + int i1; + id o1; + struct V { + int i2; + id o2; + } v1; + int i3; + union UI { + void * i1; + id o1; + int i3; + id o3; + }ui; +}; + +union U { + void * i1; + id o1; + int i3; + id o3; +}ui; + +struct S5 s2; +union U u2; +void (^c)() = ^{ + x(s2.ui.o1); + x(u2.o1); +}; +c(); + +} + +// rdar: //8417746 +void CFRelease(id); +void notifyBlock(id dependentBlock) { + id singleObservationToken; + id token; + void (^b)(); + void (^wrapperBlock)() = ^() { + CFRelease(singleObservationToken); + CFRelease(singleObservationToken); + CFRelease(token); + CFRelease(singleObservationToken); + b(); + }; + wrapperBlock(); +} + +void test_empty_block() { + void (^wrapperBlock)() = ^() { + }; + wrapperBlock(); +} + +// CHECK-LP64: L_OBJC_CLASS_NAME_: +// CHECK-LP64-NEXT: .asciz "\0011\024" + +// CHECK-LP64: L_OBJC_CLASS_NAME_1: +// CHECK-LP64-NEXT: .asciz "\0011\025" + +// CHECK-LP64: L_OBJC_CLASS_NAME_6: +// CHECK-LP64-NEXT: .asciz "\0011\023!" + +// CHECK-LP64: L_OBJC_CLASS_NAME_11: +// CHECK-LP64-NEXT: .asciz "\001A\021\021" + +// CHECK-LP64: L_OBJC_CLASS_NAME_16: +// CHECK-LP64-NEXT: .asciz "\001A\021\022p" + +// CHECK-LP64: L_OBJC_CLASS_NAME_20: +// CHECK-LP64-NEXT: .asciz "\0013" + +// CHECK-LP64: L_OBJC_CLASS_NAME_24: +// CHECK-LP64-NEXT: .asciz "\001"