clang API Documentation

ObjCRetainCount.h
Go to the documentation of this file.
00001 //==-- ObjCRetainCount.h - Retain count summaries for Cocoa -------*- C++ -*--//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  This file defines the core data structures for retain count "summaries"
00011 //  for Objective-C and Core Foundation APIs.  These summaries are used
00012 //  by the static analyzer to summarize the retain/release effects of
00013 //  function and method calls.  This drives a path-sensitive typestate
00014 //  analysis in the static analyzer, but can also potentially be used by
00015 //  other clients.
00016 //
00017 //===----------------------------------------------------------------------===//
00018 
00019 #ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H
00020 #define LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H
00021 
00022 #include "clang/Basic/LLVM.h"
00023 #include "llvm/ADT/ArrayRef.h"
00024 #include "llvm/ADT/SmallVector.h"
00025 
00026 namespace clang {
00027 class FunctionDecl;
00028 class ObjCMethodDecl;
00029 
00030 namespace ento { namespace objc_retain {
00031 
00032 /// An ArgEffect summarizes the retain count behavior on an argument or receiver
00033 /// to a function or method.
00034 enum ArgEffect {
00035   /// There is no effect.
00036   DoNothing,
00037 
00038   /// The argument is treated as if an -autorelease message had been sent to
00039   /// the referenced object.
00040   Autorelease,
00041 
00042   /// The argument is treated as if an -dealloc message had been sent to
00043   /// the referenced object.
00044   Dealloc,
00045 
00046   /// The argument has its reference count decreased by 1.  This is as
00047   /// if CFRelease has been called on the argument.
00048   DecRef,
00049 
00050   /// The argument has its reference count decreased by 1.  This is as
00051   /// if a -release message has been sent to the argument.  This differs
00052   /// in behavior from DecRef when GC is enabled.
00053   DecRefMsg,
00054 
00055   /// The argument has its reference count decreased by 1 to model
00056   /// a transferred bridge cast under ARC.
00057   DecRefBridgedTransferred,
00058 
00059   /// The argument has its reference count increased by 1.  This is as
00060   /// if a -retain message has been sent to the argument.  This differs
00061   /// in behavior from IncRef when GC is enabled.
00062   IncRefMsg,
00063 
00064   /// The argument has its reference count increased by 1.  This is as
00065   /// if CFRetain has been called on the argument.
00066   IncRef,
00067 
00068   /// The argument acts as if has been passed to CFMakeCollectable, which
00069   /// transfers the object to the Garbage Collector under GC.
00070   MakeCollectable,
00071 
00072   /// The argument is treated as potentially escaping, meaning that
00073   /// even when its reference count hits 0 it should be treated as still
00074   /// possibly being alive as someone else *may* be holding onto the object.
00075   MayEscape,
00076 
00077   /// All typestate tracking of the object ceases.  This is usually employed
00078   /// when the effect of the call is completely unknown.
00079   StopTracking,
00080 
00081   /// All typestate tracking of the object ceases.  Unlike StopTracking,
00082   /// this is also enforced when the method body is inlined.
00083   ///
00084   /// In some cases, we obtain a better summary for this checker
00085   /// by looking at the call site than by inlining the function.
00086   /// Signifies that we should stop tracking the symbol even if
00087   /// the function is inlined.
00088   StopTrackingHard,
00089 
00090   /// Performs the combined functionality of DecRef and StopTrackingHard.
00091   ///
00092   /// The models the effect that the called function decrements the reference
00093   /// count of the argument and all typestate tracking on that argument
00094   /// should cease.
00095   DecRefAndStopTrackingHard,
00096 
00097   /// Performs the combined functionality of DecRefMsg and StopTrackingHard.
00098   ///
00099   /// The models the effect that the called function decrements the reference
00100   /// count of the argument and all typestate tracking on that argument
00101   /// should cease.
00102   DecRefMsgAndStopTrackingHard
00103 };
00104 
00105 /// RetEffect summarizes a call's retain/release behavior with respect
00106 /// to its return value.
00107 class RetEffect {
00108 public:
00109   enum Kind {
00110     /// Indicates that no retain count information is tracked for
00111     /// the return value.
00112     NoRet,
00113     /// Indicates that the returned value is an owned (+1) symbol.
00114     OwnedSymbol,
00115     /// Indicates that the returned value is an owned (+1) symbol and
00116     /// that it should be treated as freshly allocated.
00117     OwnedAllocatedSymbol,
00118     /// Indicates that the returned value is an object with retain count
00119     /// semantics but that it is not owned (+0).  This is the default
00120     /// for getters, etc.
00121     NotOwnedSymbol,
00122     /// Indicates that the object is not owned and controlled by the
00123     /// Garbage collector.
00124     GCNotOwnedSymbol,
00125     /// Indicates that the return value is an owned object when the
00126     /// receiver is also a tracked object.
00127     OwnedWhenTrackedReceiver,
00128     // Treat this function as returning a non-tracked symbol even if
00129     // the function has been inlined. This is used where the call
00130     // site summary is more presise than the summary indirectly produced
00131     // by inlining the function
00132     NoRetHard
00133   };
00134   
00135   /// Determines the object kind of a tracked object.
00136   enum ObjKind {
00137     /// Indicates that the tracked object is a CF object.  This is
00138     /// important between GC and non-GC code.
00139     CF,
00140     /// Indicates that the tracked object is an Objective-C object.
00141     ObjC,
00142     /// Indicates that the tracked object could be a CF or Objective-C object.
00143     AnyObj
00144   };
00145   
00146 private:
00147   Kind K;
00148   ObjKind O;
00149   
00150   RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}
00151   
00152 public:
00153   Kind getKind() const { return K; }
00154   
00155   ObjKind getObjKind() const { return O; }
00156   
00157   bool isOwned() const {
00158     return K == OwnedSymbol || K == OwnedAllocatedSymbol ||
00159     K == OwnedWhenTrackedReceiver;
00160   }
00161   
00162   bool notOwned() const {
00163     return K == NotOwnedSymbol;
00164   }
00165   
00166   bool operator==(const RetEffect &Other) const {
00167     return K == Other.K && O == Other.O;
00168   }
00169   
00170   static RetEffect MakeOwnedWhenTrackedReceiver() {
00171     return RetEffect(OwnedWhenTrackedReceiver, ObjC);
00172   }
00173   
00174   static RetEffect MakeOwned(ObjKind o, bool isAllocated = false) {
00175     return RetEffect(isAllocated ? OwnedAllocatedSymbol : OwnedSymbol, o);
00176   }
00177   static RetEffect MakeNotOwned(ObjKind o) {
00178     return RetEffect(NotOwnedSymbol, o);
00179   }
00180   static RetEffect MakeGCNotOwned() {
00181     return RetEffect(GCNotOwnedSymbol, ObjC);
00182   }
00183   static RetEffect MakeNoRet() {
00184     return RetEffect(NoRet);
00185   }
00186   static RetEffect MakeNoRetHard() {
00187     return RetEffect(NoRetHard);
00188   }
00189 };
00190 
00191 /// Encapsulates the retain count semantics on the arguments, return value,
00192 /// and receiver (if any) of a function/method call.
00193 ///
00194 /// Note that construction of these objects is not highly efficient.  That
00195 /// is okay for clients where creating these objects isn't really a bottleneck.
00196 /// The purpose of the API is to provide something simple.  The actual
00197 /// static analyzer checker that implements retain/release typestate
00198 /// tracking uses something more efficient.
00199 class CallEffects {
00200   llvm::SmallVector<ArgEffect, 10> Args;
00201   RetEffect Ret;
00202   ArgEffect Receiver;
00203 
00204   CallEffects(const RetEffect &R) : Ret(R) {}
00205 
00206 public:
00207   /// Returns the argument effects for a call.
00208   ArrayRef<ArgEffect> getArgs() const { return Args; }
00209 
00210   /// Returns the effects on the receiver.
00211   ArgEffect getReceiver() const { return Receiver; }
00212 
00213   /// Returns the effect on the return value.
00214   RetEffect getReturnValue() const { return Ret; }
00215 
00216   /// Return the CallEfect for a given Objective-C method.
00217   static CallEffects getEffect(const ObjCMethodDecl *MD);
00218 
00219   /// Return the CallEfect for a given C/C++ function.
00220   static CallEffects getEffect(const FunctionDecl *FD);
00221 };
00222 
00223 }}}
00224 
00225 #endif
00226