From: Mike Stump Date: Tue, 21 Apr 2009 00:51:43 +0000 (+0000) Subject: Fixup codegen for write barriers for block variables. Radar 6786715 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=75b163f4c832696edf4d66d8ac1ec0ed5ea59e17;p=clang Fixup codegen for write barriers for block variables. Radar 6786715 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69642 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 62750087c0..d5d607fde9 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -2009,7 +2009,7 @@ inline bool Type::isPointerType() const { return isa(CanonicalType.getUnqualifiedType()); } inline bool Type::isBlockPointerType() const { - return isa(CanonicalType); + return isa(CanonicalType.getUnqualifiedType()); } inline bool Type::isReferenceType() const { return isa(CanonicalType.getUnqualifiedType()); diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index c3c07b7f4a..1be687be8e 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -561,7 +561,10 @@ struct DeclaratorChunk { /// For now, sema will catch these as invalid. /// The type qualifiers: const/volatile/restrict. unsigned TypeQuals : 3; - void destroy() {} + AttributeList *AttrList; + void destroy() { + delete AttrList; + } }; struct MemberPointerTypeInfo { @@ -617,7 +620,7 @@ struct DeclaratorChunk { case MemberPointer: return Mem.AttrList; case Array: return 0; case Function: return 0; - case BlockPointer: return 0; // FIXME: Do blocks have attr list? + case BlockPointer: return Cls.AttrList; } } @@ -672,12 +675,13 @@ struct DeclaratorChunk { /// getBlockPointer - Return a DeclaratorChunk for a block. /// - static DeclaratorChunk getBlockPointer(unsigned TypeQuals, - SourceLocation Loc) { + static DeclaratorChunk getBlockPointer(unsigned TypeQuals, SourceLocation Loc, + AttributeList *AL) { DeclaratorChunk I; I.Kind = BlockPointer; I.Loc = Loc; I.Cls.TypeQuals = TypeQuals; + I.Cls.AttrList = AL; return I; } diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index 55355880b1..938e965556 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1876,7 +1876,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D, else // Remember that we parsed a Block type, and remember the type-quals. D.AddTypeInfo(DeclaratorChunk::getBlockPointer(DS.getTypeQualifiers(), - Loc), + Loc, DS.TakeAttributes()), SourceLocation()); } else { // Is a reference diff --git a/test/CodeGenObjC/blocks-1.m b/test/CodeGenObjC/blocks-1.m index e343a58ee5..2b4f8faeb8 100644 --- a/test/CodeGenObjC/blocks-1.m +++ b/test/CodeGenObjC/blocks-1.m @@ -1,13 +1,13 @@ // RUN: clang-cc %s -emit-llvm -o %t -fobjc-gc -fblocks -triple i386-apple-darwin10 && -// RUN: grep "_Block_object_dispose" %t | count 4 && -// RUN: grep "__copy_helper_block_" %t | count 2 && -// RUN: grep "__destroy_helper_block_" %t | count 2 && +// RUN: grep "_Block_object_dispose" %t | count 6 && +// RUN: grep "__copy_helper_block_" %t | count 4 && +// RUN: grep "__destroy_helper_block_" %t | count 4 && // RUN: grep "__Block_byref_id_object_copy_" %t | count 2 && // RUN: grep "__Block_byref_id_object_dispose_" %t | count 2 && // RUN: grep "i32 135)" %t | count 0 && -// RUN: grep "_Block_object_assign" %t | count 3 && +// RUN: grep "_Block_object_assign" %t | count 4 && // RUN: grep "objc_read_weak" %t | count 2 && -// RUN: grep "objc_assign_weak" %t | count 2 +// RUN: grep "objc_assign_weak" %t | count 3 @interface NSDictionary @end @@ -24,3 +24,10 @@ void foo() { l = weakSelf; weakSelf = l; } + +void (^__weak b)(void); + +void test2() { + __block int i = 0; + b = ^ { ++i; }; +}