forked from OSchip/llvm-project
add parser and type checking support for attribute((objc_exception)).
We don't have "zero cost" exceptions for ObjC yet, so there is no codegen support required. llvm-svn: 64546
This commit is contained in:
parent
9844408ad6
commit
677a35804f
|
@ -43,6 +43,7 @@ public:
|
||||||
NoThrow,
|
NoThrow,
|
||||||
ObjCGC,
|
ObjCGC,
|
||||||
ObjCNSObject,
|
ObjCNSObject,
|
||||||
|
ObjCException,
|
||||||
Overloadable, // Clang-specific
|
Overloadable, // Clang-specific
|
||||||
Packed,
|
Packed,
|
||||||
Section,
|
Section,
|
||||||
|
@ -290,7 +291,6 @@ public:
|
||||||
NoThrowAttr() : Attr(NoThrow) {}
|
NoThrowAttr() : Attr(NoThrow) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast/etc.
|
// Implement isa/cast/dyncast/etc.
|
||||||
|
|
||||||
static bool classof(const Attr *A) { return A->getKind() == NoThrow; }
|
static bool classof(const Attr *A) { return A->getKind() == NoThrow; }
|
||||||
static bool classof(const NoThrowAttr *A) { return true; }
|
static bool classof(const NoThrowAttr *A) { return true; }
|
||||||
};
|
};
|
||||||
|
@ -300,7 +300,6 @@ public:
|
||||||
ConstAttr() : Attr(Const) {}
|
ConstAttr() : Attr(Const) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast/etc.
|
// Implement isa/cast/dyncast/etc.
|
||||||
|
|
||||||
static bool classof(const Attr *A) { return A->getKind() == Const; }
|
static bool classof(const Attr *A) { return A->getKind() == Const; }
|
||||||
static bool classof(const ConstAttr *A) { return true; }
|
static bool classof(const ConstAttr *A) { return true; }
|
||||||
};
|
};
|
||||||
|
@ -310,7 +309,6 @@ public:
|
||||||
PureAttr() : Attr(Pure) {}
|
PureAttr() : Attr(Pure) {}
|
||||||
|
|
||||||
// Implement isa/cast/dyncast/etc.
|
// Implement isa/cast/dyncast/etc.
|
||||||
|
|
||||||
static bool classof(const Attr *A) { return A->getKind() == Pure; }
|
static bool classof(const Attr *A) { return A->getKind() == Pure; }
|
||||||
static bool classof(const PureAttr *A) { return true; }
|
static bool classof(const PureAttr *A) { return true; }
|
||||||
};
|
};
|
||||||
|
@ -322,12 +320,11 @@ public:
|
||||||
NonNullAttr(unsigned* arg_nums = 0, unsigned size = 0) : Attr(NonNull),
|
NonNullAttr(unsigned* arg_nums = 0, unsigned size = 0) : Attr(NonNull),
|
||||||
ArgNums(0), Size(0) {
|
ArgNums(0), Size(0) {
|
||||||
|
|
||||||
if (size) {
|
if (size == 0) return;
|
||||||
assert (arg_nums);
|
assert(arg_nums);
|
||||||
ArgNums = new unsigned[size];
|
ArgNums = new unsigned[size];
|
||||||
Size = size;
|
Size = size;
|
||||||
memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
|
memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~NonNullAttr() {
|
virtual ~NonNullAttr() {
|
||||||
|
@ -459,6 +456,17 @@ static bool classof(const Attr *A) { return A->getKind() == ObjCNSObject; }
|
||||||
static bool classof(const ObjCNSObjectAttr *A) { return true; }
|
static bool classof(const ObjCNSObjectAttr *A) { return true; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ObjCExceptionAttr : public Attr {
|
||||||
|
public:
|
||||||
|
ObjCExceptionAttr() : Attr(ObjCException) {}
|
||||||
|
|
||||||
|
// Implement isa/cast/dyncast/etc.
|
||||||
|
static bool classof(const Attr *A) { return A->getKind() == ObjCException; }
|
||||||
|
static bool classof(const ObjCExceptionAttr *A) { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class OverloadableAttr : public Attr {
|
class OverloadableAttr : public Attr {
|
||||||
public:
|
public:
|
||||||
OverloadableAttr() : Attr(Overloadable) { }
|
OverloadableAttr() : Attr(Overloadable) { }
|
||||||
|
|
|
@ -314,6 +314,8 @@ DIAG(err_attribute_argument_n_not_string, ERROR,
|
||||||
"'%0' attribute requires parameter %1 to be a string")
|
"'%0' attribute requires parameter %1 to be a string")
|
||||||
DIAG(err_attribute_argument_out_of_bounds, ERROR,
|
DIAG(err_attribute_argument_out_of_bounds, ERROR,
|
||||||
"'%0' attribute parameter %1 is out of bounds")
|
"'%0' attribute parameter %1 is out of bounds")
|
||||||
|
DIAG(err_attribute_requires_objc_interface, ERROR,
|
||||||
|
"attribute may only be applied to an Objective-C interface")
|
||||||
DIAG(err_nonnull_pointers_only, ERROR,
|
DIAG(err_nonnull_pointers_only, ERROR,
|
||||||
"nonnull attribute only applies to pointer arguments")
|
"nonnull attribute only applies to pointer arguments")
|
||||||
DIAG(err_format_strftime_third_parameter, ERROR,
|
DIAG(err_format_strftime_third_parameter, ERROR,
|
||||||
|
|
|
@ -75,6 +75,7 @@ public:
|
||||||
AT_warn_unused_result,
|
AT_warn_unused_result,
|
||||||
AT_weak,
|
AT_weak,
|
||||||
AT_objc_gc,
|
AT_objc_gc,
|
||||||
|
AT_objc_exception,
|
||||||
AT_blocks,
|
AT_blocks,
|
||||||
AT_sentinel,
|
AT_sentinel,
|
||||||
AT_const,
|
AT_const,
|
||||||
|
|
|
@ -110,6 +110,9 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
|
||||||
if (!memcmp(Str, "address_space", 13)) return AT_address_space;
|
if (!memcmp(Str, "address_space", 13)) return AT_address_space;
|
||||||
if (!memcmp(Str, "always_inline", 13)) return AT_always_inline;
|
if (!memcmp(Str, "always_inline", 13)) return AT_always_inline;
|
||||||
break;
|
break;
|
||||||
|
case 14:
|
||||||
|
if (!memcmp(Str, "objc_exception", 14)) return AT_objc_exception;
|
||||||
|
break;
|
||||||
case 15:
|
case 15:
|
||||||
if (!memcmp(Str, "ext_vector_type", 15)) return AT_ext_vector_type;
|
if (!memcmp(Str, "ext_vector_type", 15)) return AT_ext_vector_type;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -568,7 +568,7 @@ static void HandleVisibilityAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
||||||
d->addAttr(new VisibilityAttr(type));
|
d->addAttr(new VisibilityAttr(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
static void HandleObjCGCAttr(Decl *D, const AttributeList &Attr, Sema &S) {
|
||||||
if (!Attr.getParameterName()) {
|
if (!Attr.getParameterName()) {
|
||||||
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
|
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
|
||||||
<< "objc_gc" << 1;
|
<< "objc_gc" << 1;
|
||||||
|
@ -579,11 +579,10 @@ static void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
||||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
|
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ObjCGCAttr::GCAttrTypes type;
|
ObjCGCAttr::GCAttrTypes type;
|
||||||
if (Attr.getParameterName()->isStr("weak")) {
|
if (Attr.getParameterName()->isStr("weak")) {
|
||||||
if (isa<FieldDecl>(d) && !isa<ObjCIvarDecl>(d))
|
if (isa<FieldDecl>(D) && !isa<ObjCIvarDecl>(D))
|
||||||
S.Diag(Attr.getLoc(), diag::warn_attribute_weak_on_field);
|
S.Diag(Attr.getLoc(), diag::warn_attribute_weak_on_field);
|
||||||
type = ObjCGCAttr::Weak;
|
type = ObjCGCAttr::Weak;
|
||||||
}
|
}
|
||||||
|
@ -595,15 +594,31 @@ static void HandleObjCGCAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->addAttr(new ObjCGCAttr(type));
|
D->addAttr(new ObjCGCAttr(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HandleObjCNSObject(Decl *d, const AttributeList &Attr, Sema &S) {
|
static void HandleObjCExceptionAttr(Decl *D, const AttributeList &Attr,
|
||||||
|
Sema &S) {
|
||||||
|
if (Attr.getNumArgs() != 0) {
|
||||||
|
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ObjCInterfaceDecl *OCI = dyn_cast<ObjCInterfaceDecl>(D);
|
||||||
|
if (OCI == 0) {
|
||||||
|
S.Diag(Attr.getLoc(), diag::err_attribute_requires_objc_interface);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
D->addAttr(new ObjCExceptionAttr());
|
||||||
|
}
|
||||||
|
|
||||||
|
static void HandleObjCNSObject(Decl *D, const AttributeList &Attr, Sema &S) {
|
||||||
if (Attr.getNumArgs() != 0) {
|
if (Attr.getNumArgs() != 0) {
|
||||||
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
|
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(d)) {
|
if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
|
||||||
QualType T = TD->getUnderlyingType();
|
QualType T = TD->getUnderlyingType();
|
||||||
if (!T->isPointerType() ||
|
if (!T->isPointerType() ||
|
||||||
!T->getAsPointerType()->getPointeeType()->isRecordType()) {
|
!T->getAsPointerType()->getPointeeType()->isRecordType()) {
|
||||||
|
@ -611,7 +626,7 @@ static void HandleObjCNSObject(Decl *d, const AttributeList &Attr, Sema &S) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
d->addAttr(new ObjCNSObjectAttr);
|
D->addAttr(new ObjCNSObjectAttr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -1406,6 +1421,9 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
|
||||||
HandleTransparentUnionAttr(D, Attr, S);
|
HandleTransparentUnionAttr(D, Attr, S);
|
||||||
break;
|
break;
|
||||||
case AttributeList::AT_objc_gc: HandleObjCGCAttr (D, Attr, S); break;
|
case AttributeList::AT_objc_gc: HandleObjCGCAttr (D, Attr, S); break;
|
||||||
|
case AttributeList::AT_objc_exception:
|
||||||
|
HandleObjCExceptionAttr(D, Attr, S);
|
||||||
|
break;
|
||||||
case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
|
case AttributeList::AT_overloadable:HandleOverloadableAttr(D, Attr, S); break;
|
||||||
case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break;
|
case AttributeList::AT_nsobject: HandleObjCNSObject (D, Attr, S); break;
|
||||||
case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break;
|
case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break;
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
// RUN: clang %s -fsyntax-only -verify
|
||||||
|
|
||||||
|
__attribute__((__objc_exception__))
|
||||||
|
@interface NSException {
|
||||||
|
int x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
__attribute__((__objc_exception__)) // expected-error {{attribute may only be applied to an Objective-C interface}}
|
||||||
|
int X;
|
||||||
|
|
||||||
|
__attribute__((__objc_exception__)) // expected-error {{attribute may only be applied to an Objective-C interface}}
|
||||||
|
void foo();
|
||||||
|
|
Loading…
Reference in New Issue