diff options
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/DeclObjC.h | 20 | ||||
-rw-r--r-- | include/clang/AST/ExprObjC.h | 5 | ||||
-rw-r--r-- | include/clang/Analysis/DomainSpecific/CocoaConventions.h | 2 | ||||
-rw-r--r-- | include/clang/Basic/IdentifierTable.h | 53 | ||||
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h | 2 |
5 files changed, 74 insertions, 8 deletions
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index b3ca474fcc..c36ab29661 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -112,17 +112,20 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext { public: enum ImplementationControl { None, Required, Optional }; private: - /// Bitfields must be first fields in this class so they pack with those - /// declared in class Decl. + // The conventional meaning of this method; an ObjCMethodFamily. + // This is not serialized; instead, it is computed on demand and + // cached. + mutable unsigned Family : ObjCMethodFamilyBitWidth; + /// instance (true) or class (false) method. - bool IsInstance : 1; - bool IsVariadic : 1; + unsigned IsInstance : 1; + unsigned IsVariadic : 1; // Synthesized declaration method for a property setter/getter - bool IsSynthesized : 1; + unsigned IsSynthesized : 1; // Method has a definition. - bool IsDefined : 1; + unsigned IsDefined : 1; // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum /// @required/@optional @@ -170,7 +173,7 @@ private: ImplementationControl impControl = None, unsigned numSelectorArgs = 0) : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), - DeclContext(ObjCMethod), + DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily), IsInstance(isInstance), IsVariadic(isVariadic), IsSynthesized(isSynthesized), IsDefined(isDefined), @@ -279,6 +282,9 @@ public: ImplicitParamDecl * getCmdDecl() const { return CmdDecl; } void setCmdDecl(ImplicitParamDecl *CD) { CmdDecl = CD; } + /// Determines the family of this method. + ObjCMethodFamily getMethodFamily() const; + bool isInstanceMethod() const { return IsInstance; } void setInstanceMethod(bool isInst) { IsInstance = isInst; } bool isVariadic() const { return IsVariadic; } diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 285efb757b..0068ee499a 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -741,6 +741,11 @@ public: SelectorOrMethod = reinterpret_cast<uintptr_t>(MD); } + ObjCMethodFamily getMethodFamily() const { + if (HasMethod) return getMethodDecl()->getMethodFamily(); + return getSelector().getMethodFamily(); + } + /// \brief Return the number of actual arguments in this message, /// not counting the receiver. unsigned getNumArgs() const { return NumArgs; } diff --git a/include/clang/Analysis/DomainSpecific/CocoaConventions.h b/include/clang/Analysis/DomainSpecific/CocoaConventions.h index 7e6e381540..18e81fed79 100644 --- a/include/clang/Analysis/DomainSpecific/CocoaConventions.h +++ b/include/clang/Analysis/DomainSpecific/CocoaConventions.h @@ -22,7 +22,7 @@ namespace cocoa { enum NamingConvention { NoConvention, CreateRule, InitRule }; - NamingConvention deriveNamingConvention(Selector S, bool ignorePrefix = true); + NamingConvention deriveNamingConvention(Selector S); static inline bool followsFundamentalRule(Selector S) { return deriveNamingConvention(S) == CreateRule; diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index d576643550..88799e2f8d 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -443,6 +443,52 @@ public: void AddKeywords(const LangOptions &LangOpts); }; +/// ObjCMethodFamily - A family of Objective-C methods. These +/// families have no inherent meaning in the language, but are +/// nonetheless central enough in the existing implementations to +/// merit direct AST support. While, in theory, arbitrary methods can +/// be considered to form families, we focus here on the methods +/// involving allocation and retain-count management, as these are the +/// most "core" and the most likely to be useful to diverse clients +/// without extra information. +/// +/// Both selectors and actual method declarations may be classified +/// into families. Method families may impose additional restrictions +/// beyond their selector name; for example, a method called '_init' +/// that returns void is not considered to be in the 'init' family +/// (but would be if it returned 'id'). It is also possible to +/// explicitly change or remove a method's family. Therefore the +/// method's family should be considered the single source of truth. +enum ObjCMethodFamily { + /// \brief No particular method family. + OMF_None, + + // Selectors in these families may have arbitrary arity, may be + // written with arbitrary leading underscores, and may have + // additional CamelCase "words" in their first selector chunk + // following the family name. + OMF_alloc, + OMF_copy, + OMF_init, + OMF_mutableCopy, + OMF_new, + + // These families are singletons consisting only of the nullary + // selector with the given name. + OMF_autorelease, + OMF_dealloc, + OMF_release, + OMF_retain, + OMF_retainCount +}; + +/// Enough bits to store any enumerator in ObjCMethodFamily or +/// InvalidObjCMethodFamily. +enum { ObjCMethodFamilyBitWidth = 4 }; + +/// An invalid value of ObjCMethodFamily. +enum { InvalidObjCMethodFamily = (1 << ObjCMethodFamilyBitWidth) - 1 }; + /// Selector - This smart pointer class efficiently represents Objective-C /// method names. This class will either point to an IdentifierInfo or a /// MultiKeywordSelector (which is private). This enables us to optimize @@ -479,6 +525,8 @@ class Selector { return InfoPtr & ArgFlags; } + static ObjCMethodFamily getMethodFamilyImpl(Selector sel); + public: friend class SelectorTable; // only the SelectorTable can create these friend class DeclarationName; // and the AST's DeclarationName. @@ -541,6 +589,11 @@ public: /// it as an std::string. std::string getAsString() const; + /// getMethodFamily - Derive the conventional family of this method. + ObjCMethodFamily getMethodFamily() const { + return getMethodFamilyImpl(*this); + } + static Selector getEmptyMarker() { return Selector(uintptr_t(-1)); } diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h b/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h index 710fc6b84f..dda855fb82 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/ObjCMessage.h @@ -72,6 +72,8 @@ public: return getType(ctx); } + ObjCMethodFamily getMethodFamily() const; + Selector getSelector() const; const Expr *getInstanceReceiver() const { |