Added parsing/sema support for __attribute__ ((IBOutlet)), a clang-specific attribute that the static analyzer will use to recognize what ivars are IBOutlets.

llvm-svn: 53644
This commit is contained in:
Ted Kremenek 2008-07-15 22:26:48 +00:00
parent 3879c5f6e4
commit 8e3704d35a
5 changed files with 38 additions and 2 deletions

View File

@ -37,7 +37,9 @@ public:
Visibility, Visibility,
FastCall, FastCall,
StdCall, StdCall,
TransparentUnion TransparentUnion,
IBOutletKind // Clang-specific. Use "Kind" suffix to not conflict with
// the IBOutlet macro.
}; };
private: private:
@ -120,6 +122,17 @@ public:
static bool classof(const Attr *A) { return A->getKind() == Alias; } static bool classof(const Attr *A) { return A->getKind() == Alias; }
static bool classof(const AliasAttr *A) { return true; } static bool classof(const AliasAttr *A) { return true; }
}; };
class IBOutletAttr : public Attr {
public:
IBOutletAttr() : Attr(IBOutletKind) {}
// Implement isa/cast/dyncast/etc.
static bool classof(const Attr *A) {
return A->getKind() == IBOutletKind;
}
static bool classof(const IBOutletAttr *A) { return true; }
};
class NoReturnAttr : public Attr { class NoReturnAttr : public Attr {
public: public:

View File

@ -672,6 +672,10 @@ DIAG(err_mode_wrong_type, ERROR,
"type of machine mode does not match type of base type") "type of machine mode does not match type of base type")
DIAG(err_attr_wrong_decl, ERROR, DIAG(err_attr_wrong_decl, ERROR,
"'%0' attribute invalid on this declaration, requires typedef or value") "'%0' attribute invalid on this declaration, requires typedef or value")
// Clang-Specific Attributes
DIAG(err_attribute_iboutlet_non_ivar, ERROR,
"'IBOutlet' attribute can only be applied to instance variables")
// Function Parameter Semantic Analysis. // Function Parameter Semantic Analysis.
DIAG(err_param_with_void_type, ERROR, DIAG(err_param_with_void_type, ERROR,

View File

@ -52,6 +52,7 @@ public:
AT_ext_vector_type, AT_ext_vector_type,
AT_fastcall, AT_fastcall,
AT_format, AT_format,
AT_IBOutlet, // Clang-specific.
AT_malloc, AT_malloc,
AT_mode, AT_mode,
AT_noinline, AT_noinline,

View File

@ -49,7 +49,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
Str += 2; Str += 2;
Len -= 4; Len -= 4;
} }
switch (Len) { switch (Len) {
case 4: case 4:
if (!memcmp(Str, "weak", 4)) return AT_weak; if (!memcmp(Str, "weak", 4)) return AT_weak;
@ -76,6 +76,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) {
if (!memcmp(Str, "noreturn", 8)) return AT_noreturn; if (!memcmp(Str, "noreturn", 8)) return AT_noreturn;
if (!memcmp(Str, "noinline", 8)) return AT_noinline; if (!memcmp(Str, "noinline", 8)) return AT_noinline;
if (!memcmp(Str, "fastcall", 8)) return AT_fastcall; if (!memcmp(Str, "fastcall", 8)) return AT_fastcall;
if (!memcmp(Str, "IBOutlet", 8)) return AT_IBOutlet;
break; break;
case 9: case 9:
if (!memcmp(Str, "dllimport", 9)) return AT_dllimport; if (!memcmp(Str, "dllimport", 9)) return AT_dllimport;

View File

@ -217,6 +217,22 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) {
Attr.getName()->getName()); Attr.getName()->getName());
} }
static void HandleIBOutletAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// check the attribute arguments.
if (Attr.getNumArgs() > 0) {
S.Diag(Attr.getLoc(), diag::err_attribute_wrong_number_arguments,
std::string("0"));
return;
}
// The IBOutlet attribute only applies to instance variables of Objective-C
// classes.
if (ObjCIvarDecl *ID = dyn_cast<ObjCIvarDecl>(d))
ID->addAttr(new IBOutletAttr());
else
S.Diag(Attr.getLoc(), diag::err_attribute_iboutlet_non_ivar);
}
static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) { static void HandleAliasAttr(Decl *d, const AttributeList &Attr, Sema &S) {
// check the attribute arguments. // check the attribute arguments.
if (Attr.getNumArgs() != 1) { if (Attr.getNumArgs() != 1) {
@ -746,6 +762,7 @@ static void ProcessDeclAttribute(Decl *D, const AttributeList &Attr, Sema &S) {
case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break; case AttributeList::AT_annotate: HandleAnnotateAttr (D, Attr, S); break;
case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break; case AttributeList::AT_noreturn: HandleNoReturnAttr (D, Attr, S); break;
case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break; case AttributeList::AT_format: HandleFormatAttr (D, Attr, S); break;
case AttributeList::AT_IBOutlet: HandleIBOutletAttr (D, Attr, S); break;
case AttributeList::AT_transparent_union: case AttributeList::AT_transparent_union:
HandleTransparentUnionAttr(D, Attr, S); HandleTransparentUnionAttr(D, Attr, S);
break; break;