forked from OSchip/llvm-project
Finish pushing blocks attribute through the clang attribute machinery.
Also added a couple simple tests from the "gcc.apple" test suite. llvm-svn: 56309
This commit is contained in:
parent
1fd58f738b
commit
3405a73ab8
|
@ -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
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
AT_warn_unused_result,
|
||||
AT_weak,
|
||||
AT_objc_gc,
|
||||
AT_blocks,
|
||||
UnknownAttribute
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
// RUN: clang %s -fsyntax-only -verify
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
// RUN: clang %s -fsyntax-only -verify
|
||||
|
||||
#include <stdio.h>
|
||||
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;
|
||||
}
|
Loading…
Reference in New Issue