From: Steve Naroff Date: Thu, 18 Sep 2008 16:44:58 +0000 (+0000) Subject: Finish pushing blocks attribute through the clang attribute machinery. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9eae5761c0691c0f11d7a823b8ee54f05786cbbe;p=clang Finish pushing blocks attribute through the clang attribute machinery. Also added a couple simple tests from the "gcc.apple" test suite. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@56309 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 0d4c355ad1..3115a4513e 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -46,7 +46,8 @@ public: TransparentUnion, Unused, Visibility, - Weak + Weak, + Blocks }; private: @@ -363,6 +364,24 @@ public: static bool classof(const ObjCGCAttr *A) { return true; } }; +class BlocksAttr : public Attr { +public: + enum BlocksAttrTypes { + ByRef = 0 + }; +private: + BlocksAttrTypes BlocksAttrType; +public: + BlocksAttr(BlocksAttrTypes t) : Attr(Blocks), BlocksAttrType(t) {} + + BlocksAttrTypes getType() const { return BlocksAttrType; } + + // Implement isa/cast/dyncast/etc. + + static bool classof(const Attr *A) { return A->getKind() == Blocks; } + static bool classof(const ObjCGCAttr *A) { return true; } +}; + } // end namespace clang #endif diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h index b6efce388f..2cc786369b 100644 --- a/include/clang/Parse/AttributeList.h +++ b/include/clang/Parse/AttributeList.h @@ -71,6 +71,7 @@ public: AT_warn_unused_result, AT_weak, AT_objc_gc, + AT_blocks, UnknownAttribute }; diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp index 00da27cf0e..b39dbe8c01 100644 --- a/lib/Parse/AttributeList.cpp +++ b/lib/Parse/AttributeList.cpp @@ -65,6 +65,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { if (!memcmp(Str, "malloc", 6)) return AT_malloc; if (!memcmp(Str, "format", 6)) return AT_format; if (!memcmp(Str, "unused", 6)) return AT_unused; + if (!memcmp(Str, "blocks", 6)) return AT_blocks; break; case 7: if (!memcmp(Str, "aligned", 7)) return AT_aligned; diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index b5737d8b3c..c014e35569 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -509,6 +509,34 @@ static void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) { d->addAttr(new ObjCGCAttr(type)); } +static void HandleBlocksAttr(Decl *d, const AttributeList &Attr, Sema &S) { + if (!Attr.getParameterName()) { + S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string, + "blocks", std::string("1")); + return; + } + + if (Attr.getNumArgs() != 0) { + S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments, + std::string("1")); + return; + } + const char *TypeStr = Attr.getParameterName()->getName(); + unsigned TypeLen = Attr.getParameterName()->getLength(); + + BlocksAttr::BlocksAttrTypes type; + + if (TypeLen == 5 && !memcmp(TypeStr, "byref", 5)) + type = BlocksAttr::ByRef; + else { + S.Diag(Attr.getLoc(), diag::warn_attribute_type_not_supported, + "blocks", TypeStr); + return; + } + + d->addAttr(new BlocksAttr(type)); +} + static void HandleWeakAttr(Decl *d, const AttributeList &Attr, Sema &S) { // check the attribute arguments. if (Attr.getNumArgs() != 0) { @@ -968,6 +996,7 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) { HandleTransparentUnionAttr(D, Attr, S); break; case AttributeList::AT_objc_gc: HandleObjCGCAttr (D, Attr, S); break; + case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break; default: #if 0 // TODO: when we have the full set of attributes, warn about unknown ones. diff --git a/test/Sema/block-byref-args.c b/test/Sema/block-byref-args.c new file mode 100644 index 0000000000..9b568f0584 --- /dev/null +++ b/test/Sema/block-byref-args.c @@ -0,0 +1,18 @@ +// RUN: clang %s -fsyntax-only -verify + +#include + +int main(int argc, char **argv) { + __block void(*bobTheFunction)(void); + __block void(^bobTheBlock)(void); + + bobTheBlock = ^{;}; + + __block int JJJJ; + __attribute__((__blocks__(byref))) int III; + + int (^XXX)(void) = ^{ return III+JJJJ; }; + + return 0; +} + diff --git a/test/Sema/block-storageclass.c b/test/Sema/block-storageclass.c new file mode 100644 index 0000000000..662bd738c8 --- /dev/null +++ b/test/Sema/block-storageclass.c @@ -0,0 +1,18 @@ +// RUN: clang %s -fsyntax-only -verify + +#include +void _Block_byref_release(void*src){} + +int main() { + __block int X = 1234; + __block const char * message = "HELLO"; + + X = X - 1234; + + X += 1; + + printf ("%s(%d)\n", message, X); + X -= 1; + + return X; +}