NoThrow,
ObjCGC,
ObjCNSObject,
+ ObjCException,
Overloadable, // Clang-specific
Packed,
Section,
NoThrowAttr() : Attr(NoThrow) {}
// Implement isa/cast/dyncast/etc.
-
static bool classof(const Attr *A) { return A->getKind() == NoThrow; }
static bool classof(const NoThrowAttr *A) { return true; }
};
ConstAttr() : Attr(Const) {}
// Implement isa/cast/dyncast/etc.
-
static bool classof(const Attr *A) { return A->getKind() == Const; }
static bool classof(const ConstAttr *A) { return true; }
};
PureAttr() : Attr(Pure) {}
// Implement isa/cast/dyncast/etc.
-
static bool classof(const Attr *A) { return A->getKind() == Pure; }
static bool classof(const PureAttr *A) { return true; }
};
NonNullAttr(unsigned* arg_nums = 0, unsigned size = 0) : Attr(NonNull),
ArgNums(0), Size(0) {
- if (size) {
- assert (arg_nums);
- ArgNums = new unsigned[size];
- Size = size;
- memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
- }
+ if (size == 0) return;
+ assert(arg_nums);
+ ArgNums = new unsigned[size];
+ Size = size;
+ memcpy(ArgNums, arg_nums, sizeof(*ArgNums)*size);
}
virtual ~NonNullAttr() {
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 {
public:
OverloadableAttr() : Attr(Overloadable) { }
"'%0' attribute requires parameter %1 to be a string")
DIAG(err_attribute_argument_out_of_bounds, ERROR,
"'%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,
"nonnull attribute only applies to pointer arguments")
DIAG(err_format_strftime_third_parameter, ERROR,
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()) {
S.Diag(Attr.getLoc(), diag::err_attribute_argument_n_not_string)
<< "objc_gc" << 1;
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
return;
}
-
-
+
ObjCGCAttr::GCAttrTypes type;
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);
type = ObjCGCAttr::Weak;
}
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) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments) << 1;
return;
}
- if (TypedefDecl *TD = dyn_cast<TypedefDecl>(d)) {
+ if (TypedefDecl *TD = dyn_cast<TypedefDecl>(D)) {
QualType T = TD->getUnderlyingType();
if (!T->isPointerType() ||
!T->getAsPointerType()->getPointeeType()->isRecordType()) {
return;
}
}
- d->addAttr(new ObjCNSObjectAttr);
+ D->addAttr(new ObjCNSObjectAttr);
}
static void
HandleTransparentUnionAttr(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_nsobject: HandleObjCNSObject (D, Attr, S); break;
case AttributeList::AT_blocks: HandleBlocksAttr (D, Attr, S); break;