Add new checker-specific attribute 'objc_ownership_returns'. This isn't hooked
up to the checker yet, but essentially it allows a user to specify that an Objective-C method or C function returns an owned an Objective-C object. llvm-svn: 70001
This commit is contained in:
parent
defc644e06
commit
44e662cd4f
|
@ -51,6 +51,7 @@ public:
|
|||
NonNull,
|
||||
ObjCException,
|
||||
ObjCNSObject,
|
||||
ObjCOwnershipReturns, // Clang/Checker-specific.
|
||||
Overloadable, // Clang-specific
|
||||
Packed,
|
||||
Pure,
|
||||
|
@ -587,6 +588,21 @@ public:
|
|||
static bool classof(const Attr *A) { return A->getKind() == Regparm; }
|
||||
static bool classof(const RegparmAttr *A) { return true; }
|
||||
};
|
||||
|
||||
|
||||
#define DEF_SIMPLE_ATTR(ATTR)\
|
||||
class ATTR##Attr : public Attr {\
|
||||
public:\
|
||||
ATTR##Attr() : Attr(ATTR) {}\
|
||||
static bool classof(const Attr *A) { return A->getKind() == ATTR; }\
|
||||
static bool classof(const ATTR##Attr *A) { return true; }\
|
||||
};
|
||||
|
||||
// Checker-specific attributes.
|
||||
DEF_SIMPLE_ATTR(ObjCOwnershipReturns)
|
||||
|
||||
#undef DEF_SIMPLE_ATTR
|
||||
|
||||
} // end namespace clang
|
||||
|
||||
#endif
|
||||
|
|
|
@ -75,8 +75,9 @@ public:
|
|||
AT_nothrow,
|
||||
AT_nsobject,
|
||||
AT_objc_exception,
|
||||
AT_objc_ownership_returns, // Clang-specific.
|
||||
AT_objc_gc,
|
||||
AT_overloadable, // Clang-specific
|
||||
AT_overloadable, // Clang-specific.
|
||||
AT_packed,
|
||||
AT_pure,
|
||||
AT_regparm,
|
||||
|
|
|
@ -3045,6 +3045,7 @@ Attr *PCHReader::ReadAttributes() {
|
|||
|
||||
SIMPLE_ATTR(ObjCException);
|
||||
SIMPLE_ATTR(ObjCNSObject);
|
||||
SIMPLE_ATTR(ObjCOwnershipReturns);
|
||||
SIMPLE_ATTR(Overloadable);
|
||||
UNSIGNED_ATTR(Packed);
|
||||
SIMPLE_ATTR(Pure);
|
||||
|
|
|
@ -2181,6 +2181,7 @@ void PCHWriter::WriteAttributeRecord(const Attr *Attr) {
|
|||
|
||||
case Attr::ObjCException:
|
||||
case Attr::ObjCNSObject:
|
||||
case Attr::ObjCOwnershipReturns:
|
||||
case Attr::Overloadable:
|
||||
break;
|
||||
|
||||
|
|
|
@ -133,6 +133,10 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
|
|||
case 18:
|
||||
if (!memcmp(Str, "warn_unused_result", 18)) return AT_warn_unused_result;
|
||||
break;
|
||||
case 22:
|
||||
if (!memcmp(Str, "objc_ownership_returns", 22))
|
||||
return AT_objc_ownership_returns;
|
||||
break;
|
||||
}
|
||||
return UnknownAttribute;
|
||||
}
|
||||
|
|
|
@ -1517,6 +1517,22 @@ static void HandleRegparmAttr(Decl *d, const AttributeList &Attr, Sema &S) {
|
|||
d->addAttr(::new (S.Context) RegparmAttr(NumParams.getZExtValue()));
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Checker-specific attribute handlers.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
static void HandleObjCOwnershipReturnsAttr(Decl *d, const AttributeList &Attr,
|
||||
Sema &S) {
|
||||
|
||||
if (!isa<ObjCMethodDecl>(d) && !isa<FunctionDecl>(d)) {
|
||||
S.Diag(Attr.getLoc(), diag::warn_attribute_wrong_decl_type) <<
|
||||
"objc_ownership_returns" << 3 /* function or method */;
|
||||
return;
|
||||
}
|
||||
|
||||
d->addAttr(::new (S.Context) ObjCOwnershipReturnsAttr());
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Top Level Sema Entry Points
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -1553,6 +1569,11 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
|
|||
case AttributeList::AT_nonnull: HandleNonNullAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_nothrow: HandleNothrowAttr (D, Attr, S); break;
|
||||
|
||||
// Checker-specific.
|
||||
case AttributeList::AT_objc_ownership_returns:
|
||||
HandleObjCOwnershipReturnsAttr(D, Attr, S); break;
|
||||
|
||||
case AttributeList::AT_packed: HandlePackedAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_section: HandleSectionAttr (D, Attr, S); break;
|
||||
case AttributeList::AT_stdcall: HandleStdCallAttr (D, Attr, S); break;
|
||||
|
|
|
@ -405,3 +405,15 @@ void rdar6704930(unsigned char *s, unsigned int length) {
|
|||
}
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Tests of ownership attributes.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@interface TestOwnershipAttr : NSObject
|
||||
- (NSString*) returnsAnOwnedString __attribute__((objc_ownership_returns));
|
||||
@end
|
||||
|
||||
void test_attr_1(TestOwnershipAttr *X) {
|
||||
NSString *str = [X returnsAnOwnedString];
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue