From: Ted Kremenek Date: Tue, 15 Jul 2008 22:26:48 +0000 (+0000) Subject: Added parsing/sema support for __attribute__ ((IBOutlet)), a clang-specific attribute... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=96329d4e07a9bcddb5a927892b70408c8fd8c474;p=clang Added parsing/sema support for __attribute__ ((IBOutlet)), a clang-specific attribute that the static analyzer will use to recognize what ivars are IBOutlets. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@53644 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index c7da6d924b..c659454b83 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -37,7 +37,9 @@ public: Visibility, FastCall, StdCall, - TransparentUnion + TransparentUnion, + IBOutletKind // Clang-specific. Use "Kind" suffix to not conflict with + // the IBOutlet macro. }; private: @@ -120,6 +122,17 @@ public: static bool classof(const Attr *A) { return A->getKind() == Alias; } 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 { public: diff --git a/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index c0a2ea0221..d1c4bd9080 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/include/clang/Basic/DiagnosticKinds.def @@ -672,6 +672,10 @@ DIAG(err_mode_wrong_type, ERROR, "type of machine mode does not match type of base type") DIAG(err_attr_wrong_decl, ERROR, "'%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. DIAG(err_param_with_void_type, ERROR, diff --git a/include/clang/Parse/AttributeList.h b/include/clang/Parse/AttributeList.h index 112a495e6e..18a26163a3 100644 --- a/include/clang/Parse/AttributeList.h +++ b/include/clang/Parse/AttributeList.h @@ -52,6 +52,7 @@ public: AT_ext_vector_type, AT_fastcall, AT_format, + AT_IBOutlet, // Clang-specific. AT_malloc, AT_mode, AT_noinline, diff --git a/lib/Parse/AttributeList.cpp b/lib/Parse/AttributeList.cpp index 8697d4ece8..9d84a0f189 100644 --- a/lib/Parse/AttributeList.cpp +++ b/lib/Parse/AttributeList.cpp @@ -49,7 +49,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo *Name) { Str += 2; Len -= 4; } - + switch (Len) { case 4: 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, "noinline", 8)) return AT_noinline; if (!memcmp(Str, "fastcall", 8)) return AT_fastcall; + if (!memcmp(Str, "IBOutlet", 8)) return AT_IBOutlet; break; case 9: if (!memcmp(Str, "dllimport", 9)) return AT_dllimport; diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp index e6dac4901e..f8217b362f 100644 --- a/lib/Sema/SemaDeclAttr.cpp +++ b/lib/Sema/SemaDeclAttr.cpp @@ -217,6 +217,22 @@ static void HandlePackedAttr(Decl *d, const AttributeList &Attr, Sema &S) { 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(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) { // check the attribute arguments. 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_noreturn: HandleNoReturnAttr (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: HandleTransparentUnionAttr(D, Attr, S); break;