clang API Documentation
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