<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class="">Apologies! I’m really confused now how was it able to build without modules at all.<br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Aug 17, 2018, at 8:24 PM, Bruno Cardoso Lopes <<a href="mailto:bruno.cardoso@gmail.com" class="">bruno.cardoso@gmail.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none; float: none; display: inline !important;" class="">Hi George,</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none; float: none; display: inline !important;" class="">This broke the modules build, reverted in r340117 for now. I can help</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none; float: none; display: inline !important;" class="">you figure out any module map change if necessary next week.</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none; float: none; display: inline !important;" class="">Thanks,</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none; float: none; display: inline !important;" class="">On Fri, Aug 17, 2018 at 6:46 PM George Karpenkov via cfe-commits</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none; float: none; display: inline !important;" class=""><</span><a href="mailto:cfe-commits@lists.llvm.org" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" class="">cfe-commits@lists.llvm.org</a><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none; float: none; display: inline !important;" class="">> wrote:</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><blockquote type="cite" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><br class="">Author: george.karpenkov<br class="">Date: Fri Aug 17 18:45:50 2018<br class="">New Revision: 340114<br class=""><br class="">URL: <a href="http://llvm.org/viewvc/llvm-project?rev=340114&view=rev" class="">http://llvm.org/viewvc/llvm-project?rev=340114&view=rev</a><br class="">Log:<br class="">[analyzer] [NFC] Split up RetainSummaryManager from RetainCountChecker<br class=""><br class="">ARCMigrator is using code from RetainCountChecker, which is a layering<br class="">violation (and it also does it badly, by using a different header, and<br class="">then relying on implementation being present in a header file).<br class=""><br class="">This change splits up RetainSummaryManager into a separate library in<br class="">lib/Analysis, which can be used independently of a checker.<br class=""><br class="">Differential Revision: <a href="https://reviews.llvm.org/D50934" class="">https://reviews.llvm.org/D50934</a><br class=""><br class="">Added:<br class="">   cfe/trunk/include/clang/Analysis/RetainSummaryManager.h<br class="">   cfe/trunk/include/clang/StaticAnalyzer/Checkers/SelectorExtras.h<br class="">   cfe/trunk/lib/Analysis/RetainSummaryManager.cpp<br class="">Removed:<br class="">   cfe/trunk/include/clang/Analysis/ObjCRetainCount.h<br class="">   cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.cpp<br class="">   cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountSummaries.h<br class="">   cfe/trunk/lib/StaticAnalyzer/Checkers/SelectorExtras.h<br class="">Modified:<br class="">   cfe/trunk/lib/ARCMigrate/CMakeLists.txt<br class="">   cfe/trunk/lib/ARCMigrate/ObjCMT.cpp<br class="">   cfe/trunk/lib/Analysis/CMakeLists.txt<br class="">   cfe/trunk/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp<br class="">   cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt<br class="">   cfe/trunk/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp<br class="">   cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.cpp<br class="">   cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountChecker.h<br class="">   cfe/trunk/lib/StaticAnalyzer/Checkers/RetainCountChecker/RetainCountDiagnostics.h<br class="">   cfe/trunk/lib/StaticAnalyzer/Checkers/TrustNonnullChecker.cpp<br class=""><br class="">Removed: cfe/trunk/include/clang/Analysis/ObjCRetainCount.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/ObjCRetainCount.h?rev=340113&view=auto" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/ObjCRetainCount.h?rev=340113&view=auto</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Analysis/ObjCRetainCount.h (original)<br class="">+++ cfe/trunk/include/clang/Analysis/ObjCRetainCount.h (removed)<br class="">@@ -1,231 +0,0 @@<br class="">-//==-- ObjCRetainCount.h - Retain count summaries for Cocoa -------*- C++ -*--//<br class="">-//<br class="">-//                     The LLVM Compiler Infrastructure<br class="">-//<br class="">-// This file is distributed under the University of Illinois Open Source<br class="">-// License. See LICENSE.TXT for details.<br class="">-//<br class="">-//===----------------------------------------------------------------------===//<br class="">-//<br class="">-//  This file defines the core data structures for retain count "summaries"<br class="">-//  for Objective-C and Core Foundation APIs.  These summaries are used<br class="">-//  by the static analyzer to summarize the retain/release effects of<br class="">-//  function and method calls.  This drives a path-sensitive typestate<br class="">-//  analysis in the static analyzer, but can also potentially be used by<br class="">-//  other clients.<br class="">-//<br class="">-//===----------------------------------------------------------------------===//<br class="">-<br class="">-#ifndef LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H<br class="">-#define LLVM_CLANG_STATICANALYZER_CHECKERS_OBJCRETAINCOUNT_H<br class="">-<br class="">-#include "clang/Basic/LLVM.h"<br class="">-#include "llvm/ADT/ArrayRef.h"<br class="">-#include "llvm/ADT/SmallVector.h"<br class="">-<br class="">-namespace clang {<br class="">-class FunctionDecl;<br class="">-class ObjCMethodDecl;<br class="">-<br class="">-namespace ento { namespace objc_retain {<br class="">-<br class="">-/// An ArgEffect summarizes the retain count behavior on an argument or receiver<br class="">-/// to a function or method.<br class="">-enum ArgEffect {<br class="">-  /// There is no effect.<br class="">-  DoNothing,<br class="">-<br class="">-  /// The argument is treated as if an -autorelease message had been sent to<br class="">-  /// the referenced object.<br class="">-  Autorelease,<br class="">-<br class="">-  /// The argument is treated as if an -dealloc message had been sent to<br class="">-  /// the referenced object.<br class="">-  Dealloc,<br class="">-<br class="">-  /// The argument has its reference count decreased by 1.  This is as<br class="">-  /// if CFRelease has been called on the argument.<br class="">-  DecRef,<br class="">-<br class="">-  /// The argument has its reference count decreased by 1.  This is as<br class="">-  /// if a -release message has been sent to the argument.  This differs<br class="">-  /// in behavior from DecRef when GC is enabled.<br class="">-  DecRefMsg,<br class="">-<br class="">-  /// The argument has its reference count decreased by 1 to model<br class="">-  /// a transferred bridge cast under ARC.<br class="">-  DecRefBridgedTransferred,<br class="">-<br class="">-  /// The argument has its reference count increased by 1.  This is as<br class="">-  /// if a -retain message has been sent to the argument.  This differs<br class="">-  /// in behavior from IncRef when GC is enabled.<br class="">-  IncRefMsg,<br class="">-<br class="">-  /// The argument has its reference count increased by 1.  This is as<br class="">-  /// if CFRetain has been called on the argument.<br class="">-  IncRef,<br class="">-<br class="">-  /// Used to mark an argument as collectible in GC mode, currently a noop.<br class="">-  MakeCollectable,<br class="">-<br class="">-  /// The argument is a pointer to a retain-counted object; on exit, the new<br class="">-  /// value of the pointer is a +0 value or NULL.<br class="">-  UnretainedOutParameter,<br class="">-<br class="">-  /// The argument is a pointer to a retain-counted object; on exit, the new<br class="">-  /// value of the pointer is a +1 value or NULL.<br class="">-  RetainedOutParameter,<br class="">-<br class="">-  /// The argument is treated as potentially escaping, meaning that<br class="">-  /// even when its reference count hits 0 it should be treated as still<br class="">-  /// possibly being alive as someone else *may* be holding onto the object.<br class="">-  MayEscape,<br class="">-<br class="">-  /// All typestate tracking of the object ceases.  This is usually employed<br class="">-  /// when the effect of the call is completely unknown.<br class="">-  StopTracking,<br class="">-<br class="">-  /// All typestate tracking of the object ceases.  Unlike StopTracking,<br class="">-  /// this is also enforced when the method body is inlined.<br class="">-  ///<br class="">-  /// In some cases, we obtain a better summary for this checker<br class="">-  /// by looking at the call site than by inlining the function.<br class="">-  /// Signifies that we should stop tracking the symbol even if<br class="">-  /// the function is inlined.<br class="">-  StopTrackingHard,<br class="">-<br class="">-  /// Performs the combined functionality of DecRef and StopTrackingHard.<br class="">-  ///<br class="">-  /// The models the effect that the called function decrements the reference<br class="">-  /// count of the argument and all typestate tracking on that argument<br class="">-  /// should cease.<br class="">-  DecRefAndStopTrackingHard,<br class="">-<br class="">-  /// Performs the combined functionality of DecRefMsg and StopTrackingHard.<br class="">-  ///<br class="">-  /// The models the effect that the called function decrements the reference<br class="">-  /// count of the argument and all typestate tracking on that argument<br class="">-  /// should cease.<br class="">-  DecRefMsgAndStopTrackingHard<br class="">-};<br class="">-<br class="">-/// RetEffect summarizes a call's retain/release behavior with respect<br class="">-/// to its return value.<br class="">-class RetEffect {<br class="">-public:<br class="">-  enum Kind {<br class="">-    /// Indicates that no retain count information is tracked for<br class="">-    /// the return value.<br class="">-    NoRet,<br class="">-    /// Indicates that the returned value is an owned (+1) symbol.<br class="">-    OwnedSymbol,<br class="">-    /// Indicates that the returned value is an object with retain count<br class="">-    /// semantics but that it is not owned (+0).  This is the default<br class="">-    /// for getters, etc.<br class="">-    NotOwnedSymbol,<br class="">-    /// Indicates that the object is not owned and controlled by the<br class="">-    /// Garbage collector.<br class="">-    GCNotOwnedSymbol,<br class="">-    /// Indicates that the return value is an owned object when the<br class="">-    /// receiver is also a tracked object.<br class="">-    OwnedWhenTrackedReceiver,<br class="">-    // Treat this function as returning a non-tracked symbol even if<br class="">-    // the function has been inlined. This is used where the call<br class="">-    // site summary is more presise than the summary indirectly produced<br class="">-    // by inlining the function<br class="">-    NoRetHard<br class="">-  };<br class="">-<br class="">-  /// Determines the object kind of a tracked object.<br class="">-  enum ObjKind {<br class="">-    /// Indicates that the tracked object is a CF object.  This is<br class="">-    /// important between GC and non-GC code.<br class="">-    CF,<br class="">-    /// Indicates that the tracked object is an Objective-C object.<br class="">-    ObjC,<br class="">-    /// Indicates that the tracked object could be a CF or Objective-C object.<br class="">-    AnyObj,<br class="">-    /// Indicates that the tracked object is a generalized object.<br class="">-    Generalized<br class="">-  };<br class="">-<br class="">-private:<br class="">-  Kind K;<br class="">-  ObjKind O;<br class="">-<br class="">-  RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}<br class="">-<br class="">-public:<br class="">-  Kind getKind() const { return K; }<br class="">-<br class="">-  ObjKind getObjKind() const { return O; }<br class="">-<br class="">-  bool isOwned() const {<br class="">-    return K == OwnedSymbol || K == OwnedWhenTrackedReceiver;<br class="">-  }<br class="">-<br class="">-  bool notOwned() const {<br class="">-    return K == NotOwnedSymbol;<br class="">-  }<br class="">-<br class="">-  bool operator==(const RetEffect &Other) const {<br class="">-    return K == Other.K && O == Other.O;<br class="">-  }<br class="">-<br class="">-  static RetEffect MakeOwnedWhenTrackedReceiver() {<br class="">-    return RetEffect(OwnedWhenTrackedReceiver, ObjC);<br class="">-  }<br class="">-<br class="">-  static RetEffect MakeOwned(ObjKind o) {<br class="">-    return RetEffect(OwnedSymbol, o);<br class="">-  }<br class="">-  static RetEffect MakeNotOwned(ObjKind o) {<br class="">-    return RetEffect(NotOwnedSymbol, o);<br class="">-  }<br class="">-  static RetEffect MakeGCNotOwned() {<br class="">-    return RetEffect(GCNotOwnedSymbol, ObjC);<br class="">-  }<br class="">-  static RetEffect MakeNoRet() {<br class="">-    return RetEffect(NoRet);<br class="">-  }<br class="">-  static RetEffect MakeNoRetHard() {<br class="">-    return RetEffect(NoRetHard);<br class="">-  }<br class="">-};<br class="">-<br class="">-/// Encapsulates the retain count semantics on the arguments, return value,<br class="">-/// and receiver (if any) of a function/method call.<br class="">-///<br class="">-/// Note that construction of these objects is not highly efficient.  That<br class="">-/// is okay for clients where creating these objects isn't really a bottleneck.<br class="">-/// The purpose of the API is to provide something simple.  The actual<br class="">-/// static analyzer checker that implements retain/release typestate<br class="">-/// tracking uses something more efficient.<br class="">-class CallEffects {<br class="">-  llvm::SmallVector<ArgEffect, 10> Args;<br class="">-  RetEffect Ret;<br class="">-  ArgEffect Receiver;<br class="">-<br class="">-  CallEffects(const RetEffect &R) : Ret(R) {}<br class="">-<br class="">-public:<br class="">-  /// Returns the argument effects for a call.<br class="">-  ArrayRef<ArgEffect> getArgs() const { return Args; }<br class="">-<br class="">-  /// Returns the effects on the receiver.<br class="">-  ArgEffect getReceiver() const { return Receiver; }<br class="">-<br class="">-  /// Returns the effect on the return value.<br class="">-  RetEffect getReturnValue() const { return Ret; }<br class="">-<br class="">-  /// Return the CallEfect for a given Objective-C method.<br class="">-  static CallEffects getEffect(const ObjCMethodDecl *MD);<br class="">-<br class="">-  /// Return the CallEfect for a given C/C++ function.<br class="">-  static CallEffects getEffect(const FunctionDecl *FD);<br class="">-};<br class="">-<br class="">-}}}<br class="">-<br class="">-#endif<br class="">-<br class=""><br class="">Added: cfe/trunk/include/clang/Analysis/RetainSummaryManager.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/RetainSummaryManager.h?rev=340114&view=auto" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/RetainSummaryManager.h?rev=340114&view=auto</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/Analysis/RetainSummaryManager.h (added)<br class="">+++ cfe/trunk/include/clang/Analysis/RetainSummaryManager.h Fri Aug 17 18:45:50 2018<br class="">@@ -0,0 +1,706 @@<br class="">+//=== RetainSummaryManager.h - Summaries for reference counting ---*- C++ -*--//<br class="">+//<br class="">+//                     The LLVM Compiler Infrastructure<br class="">+//<br class="">+// This file is distributed under the University of Illinois Open Source<br class="">+// License. See LICENSE.TXT for details.<br class="">+//<br class="">+//===----------------------------------------------------------------------===//<br class="">+//<br class="">+//  This file defines summaries implementation for retain counting, which<br class="">+//  implements a reference count checker for Core Foundation and Cocoa<br class="">+//  on (Mac OS X).<br class="">+//<br class="">+//===----------------------------------------------------------------------===//<br class="">+<br class="">+#ifndef LLVM_CLANG_LIB_ANALYSIS_RETAINSUMMARYMANAGER<br class="">+#define LLVM_CLANG_LIB_ANALYSIS_RETAINSUMMARYMANAGER<br class="">+<br class="">+#include "llvm/ADT/DenseMap.h"<br class="">+#include "llvm/ADT/FoldingSet.h"<br class="">+#include "clang/AST/Attr.h"<br class="">+#include "clang/AST/DeclCXX.h"<br class="">+#include "clang/AST/DeclObjC.h"<br class="">+#include "clang/AST/ParentMap.h"<br class="">+#include "clang/StaticAnalyzer/Checkers/SelectorExtras.h"<br class="">+#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"<br class="">+#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h"<br class="">+#include "clang/StaticAnalyzer/Core/Checker.h"<br class="">+#include "clang/StaticAnalyzer/Core/CheckerManager.h"<br class="">+#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"<br class="">+#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"<br class="">+#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramStateTrait.h"<br class="">+#include "clang/StaticAnalyzer/Core/PathSensitive/SymbolManager.h"<br class="">+#include "llvm/ADT/ImmutableList.h"<br class="">+#include "llvm/ADT/ImmutableMap.h"<br class="">+#include "llvm/ADT/STLExtras.h"<br class="">+<br class="">+//===----------------------------------------------------------------------===//<br class="">+// Adapters for FoldingSet.<br class="">+//===----------------------------------------------------------------------===//<br class="">+<br class="">+using namespace clang;<br class="">+using namespace ento;<br class="">+<br class="">+namespace clang {<br class="">+namespace ento {<br class="">+<br class="">+/// An ArgEffect summarizes the retain count behavior on an argument or receiver<br class="">+/// to a function or method.<br class="">+enum ArgEffect {<br class="">+  /// There is no effect.<br class="">+  DoNothing,<br class="">+<br class="">+  /// The argument is treated as if an -autorelease message had been sent to<br class="">+  /// the referenced object.<br class="">+  Autorelease,<br class="">+<br class="">+  /// The argument is treated as if an -dealloc message had been sent to<br class="">+  /// the referenced object.<br class="">+  Dealloc,<br class="">+<br class="">+  /// The argument has its reference count decreased by 1.  This is as<br class="">+  /// if CFRelease has been called on the argument.<br class="">+  DecRef,<br class="">+<br class="">+  /// The argument has its reference count decreased by 1.  This is as<br class="">+  /// if a -release message has been sent to the argument.  This differs<br class="">+  /// in behavior from DecRef when GC is enabled.<br class="">+  DecRefMsg,<br class="">+<br class="">+  /// The argument has its reference count decreased by 1 to model<br class="">+  /// a transferred bridge cast under ARC.<br class="">+  DecRefBridgedTransferred,<br class="">+<br class="">+  /// The argument has its reference count increased by 1.  This is as<br class="">+  /// if a -retain message has been sent to the argument.  This differs<br class="">+  /// in behavior from IncRef when GC is enabled.<br class="">+  IncRefMsg,<br class="">+<br class="">+  /// The argument has its reference count increased by 1.  This is as<br class="">+  /// if CFRetain has been called on the argument.<br class="">+  IncRef,<br class="">+<br class="">+  /// The argument acts as if has been passed to CFMakeCollectable, which<br class="">+  /// transfers the object to the Garbage Collector under GC.<br class="">+  MakeCollectable,<br class="">+<br class="">+  /// The argument is a pointer to a retain-counted object; on exit, the new<br class="">+  /// value of the pointer is a +0 value or NULL.<br class="">+  UnretainedOutParameter,<br class="">+<br class="">+  /// The argument is a pointer to a retain-counted object; on exit, the new<br class="">+  /// value of the pointer is a +1 value or NULL.<br class="">+  RetainedOutParameter,<br class="">+<br class="">+  /// The argument is treated as potentially escaping, meaning that<br class="">+  /// even when its reference count hits 0 it should be treated as still<br class="">+  /// possibly being alive as someone else *may* be holding onto the object.<br class="">+  MayEscape,<br class="">+<br class="">+  /// All typestate tracking of the object ceases.  This is usually employed<br class="">+  /// when the effect of the call is completely unknown.<br class="">+  StopTracking,<br class="">+<br class="">+  /// All typestate tracking of the object ceases.  Unlike StopTracking,<br class="">+  /// this is also enforced when the method body is inlined.<br class="">+  ///<br class="">+  /// In some cases, we obtain a better summary for this checker<br class="">+  /// by looking at the call site than by inlining the function.<br class="">+  /// Signifies that we should stop tracking the symbol even if<br class="">+  /// the function is inlined.<br class="">+  StopTrackingHard,<br class="">+<br class="">+  /// Performs the combined functionality of DecRef and StopTrackingHard.<br class="">+  ///<br class="">+  /// The models the effect that the called function decrements the reference<br class="">+  /// count of the argument and all typestate tracking on that argument<br class="">+  /// should cease.<br class="">+  DecRefAndStopTrackingHard,<br class="">+<br class="">+  /// Performs the combined functionality of DecRefMsg and StopTrackingHard.<br class="">+  ///<br class="">+  /// The models the effect that the called function decrements the reference<br class="">+  /// count of the argument and all typestate tracking on that argument<br class="">+  /// should cease.<br class="">+  DecRefMsgAndStopTrackingHard<br class="">+};<br class="">+<br class="">+/// RetEffect summarizes a call's retain/release behavior with respect<br class="">+/// to its return value.<br class="">+class RetEffect {<br class="">+public:<br class="">+  enum Kind {<br class="">+    /// Indicates that no retain count information is tracked for<br class="">+    /// the return value.<br class="">+    NoRet,<br class="">+    /// Indicates that the returned value is an owned (+1) symbol.<br class="">+    OwnedSymbol,<br class="">+    /// Indicates that the returned value is an object with retain count<br class="">+    /// semantics but that it is not owned (+0).  This is the default<br class="">+    /// for getters, etc.<br class="">+    NotOwnedSymbol,<br class="">+    /// Indicates that the object is not owned and controlled by the<br class="">+    /// Garbage collector.<br class="">+    GCNotOwnedSymbol,<br class="">+    /// Indicates that the return value is an owned object when the<br class="">+    /// receiver is also a tracked object.<br class="">+    OwnedWhenTrackedReceiver,<br class="">+    // Treat this function as returning a non-tracked symbol even if<br class="">+    // the function has been inlined. This is used where the call<br class="">+    // site summary is more presise than the summary indirectly produced<br class="">+    // by inlining the function<br class="">+    NoRetHard<br class="">+  };<br class="">+<br class="">+  /// Determines the object kind of a tracked object.<br class="">+  enum ObjKind {<br class="">+    /// Indicates that the tracked object is a CF object.  This is<br class="">+    /// important between GC and non-GC code.<br class="">+    CF,<br class="">+    /// Indicates that the tracked object is an Objective-C object.<br class="">+    ObjC,<br class="">+    /// Indicates that the tracked object could be a CF or Objective-C object.<br class="">+    AnyObj,<br class="">+    /// Indicates that the tracked object is a generalized object.<br class="">+    Generalized<br class="">+  };<br class="">+<br class="">+private:<br class="">+  Kind K;<br class="">+  ObjKind O;<br class="">+<br class="">+  RetEffect(Kind k, ObjKind o = AnyObj) : K(k), O(o) {}<br class="">+<br class="">+public:<br class="">+  Kind getKind() const { return K; }<br class="">+<br class="">+  ObjKind getObjKind() const { return O; }<br class="">+<br class="">+  bool isOwned() const {<br class="">+    return K == OwnedSymbol || K == OwnedWhenTrackedReceiver;<br class="">+  }<br class="">+<br class="">+  bool notOwned() const {<br class="">+    return K == NotOwnedSymbol;<br class="">+  }<br class="">+<br class="">+  bool operator==(const RetEffect &Other) const {<br class="">+    return K == Other.K && O == Other.O;<br class="">+  }<br class="">+<br class="">+  static RetEffect MakeOwnedWhenTrackedReceiver() {<br class="">+    return RetEffect(OwnedWhenTrackedReceiver, ObjC);<br class="">+  }<br class="">+<br class="">+  static RetEffect MakeOwned(ObjKind o) {<br class="">+    return RetEffect(OwnedSymbol, o);<br class="">+  }<br class="">+  static RetEffect MakeNotOwned(ObjKind o) {<br class="">+    return RetEffect(NotOwnedSymbol, o);<br class="">+  }<br class="">+  static RetEffect MakeGCNotOwned() {<br class="">+    return RetEffect(GCNotOwnedSymbol, ObjC);<br class="">+  }<br class="">+  static RetEffect MakeNoRet() {<br class="">+    return RetEffect(NoRet);<br class="">+  }<br class="">+  static RetEffect MakeNoRetHard() {<br class="">+    return RetEffect(NoRetHard);<br class="">+  }<br class="">+};<br class="">+<br class="">+/// Encapsulates the retain count semantics on the arguments, return value,<br class="">+/// and receiver (if any) of a function/method call.<br class="">+///<br class="">+/// Note that construction of these objects is not highly efficient.  That<br class="">+/// is okay for clients where creating these objects isn't really a bottleneck.<br class="">+/// The purpose of the API is to provide something simple.  The actual<br class="">+/// static analyzer checker that implements retain/release typestate<br class="">+/// tracking uses something more efficient.<br class="">+class CallEffects {<br class="">+  llvm::SmallVector<ArgEffect, 10> Args;<br class="">+  RetEffect Ret;<br class="">+  ArgEffect Receiver;<br class="">+<br class="">+  CallEffects(const RetEffect &R) : Ret(R) {}<br class="">+<br class="">+public:<br class="">+  /// Returns the argument effects for a call.<br class="">+  ArrayRef<ArgEffect> getArgs() const { return Args; }<br class="">+<br class="">+  /// Returns the effects on the receiver.<br class="">+  ArgEffect getReceiver() const { return Receiver; }<br class="">+<br class="">+  /// Returns the effect on the return value.<br class="">+  RetEffect getReturnValue() const { return Ret; }<br class="">+<br class="">+  /// Return the CallEfect for a given Objective-C method.<br class="">+  static CallEffects getEffect(const ObjCMethodDecl *MD);<br class="">+<br class="">+  /// Return the CallEfect for a given C/C++ function.<br class="">+  static CallEffects getEffect(const FunctionDecl *FD);<br class="">+};<br class="">+<br class="">+/// A key identifying a summary.<br class="">+class ObjCSummaryKey {<br class="">+  IdentifierInfo* II;<br class="">+  Selector S;<br class="">+public:<br class="">+  ObjCSummaryKey(IdentifierInfo* ii, Selector s)<br class="">+    : II(ii), S(s) {}<br class="">+<br class="">+  ObjCSummaryKey(const ObjCInterfaceDecl *d, Selector s)<br class="">+    : II(d ? d->getIdentifier() : nullptr), S(s) {}<br class="">+<br class="">+  ObjCSummaryKey(Selector s)<br class="">+    : II(nullptr), S(s) {}<br class="">+<br class="">+  IdentifierInfo *getIdentifier() const { return II; }<br class="">+  Selector getSelector() const { return S; }<br class="">+};<br class="">+<br class="">+} // end namespace ento<br class="">+} // end namespace clang<br class="">+<br class="">+namespace llvm {<br class="">+<br class="">+template <> struct FoldingSetTrait<ArgEffect> {<br class="">+static inline void Profile(const ArgEffect X, FoldingSetNodeID &ID) {<br class="">+  ID.AddInteger((unsigned) X);<br class="">+}<br class="">+};<br class="">+template <> struct FoldingSetTrait<RetEffect> {<br class="">+  static inline void Profile(const RetEffect &X, FoldingSetNodeID &ID) {<br class="">+    ID.AddInteger((unsigned) X.getKind());<br class="">+    ID.AddInteger((unsigned) X.getObjKind());<br class="">+}<br class="">+};<br class="">+<br class="">+template <> struct DenseMapInfo<ObjCSummaryKey> {<br class="">+  static inline ObjCSummaryKey getEmptyKey() {<br class="">+    return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getEmptyKey(),<br class="">+                          DenseMapInfo<Selector>::getEmptyKey());<br class="">+  }<br class="">+<br class="">+  static inline ObjCSummaryKey getTombstoneKey() {<br class="">+    return ObjCSummaryKey(DenseMapInfo<IdentifierInfo*>::getTombstoneKey(),<br class="">+                          DenseMapInfo<Selector>::getTombstoneKey());<br class="">+  }<br class="">+<br class="">+  static unsigned getHashValue(const ObjCSummaryKey &V) {<br class="">+    typedef std::pair<IdentifierInfo*, Selector> PairTy;<br class="">+    return DenseMapInfo<PairTy>::getHashValue(PairTy(V.getIdentifier(),<br class="">+                                                     V.getSelector()));<br class="">+  }<br class="">+<br class="">+  static bool isEqual(const ObjCSummaryKey& LHS, const ObjCSummaryKey& RHS) {<br class="">+    return LHS.getIdentifier() == RHS.getIdentifier() &&<br class="">+           LHS.getSelector() == RHS.getSelector();<br class="">+  }<br class="">+<br class="">+};<br class="">+<br class="">+} // end llvm namespace<br class="">+<br class="">+<br class="">+namespace clang {<br class="">+namespace ento {<br class="">+<br class="">+/// ArgEffects summarizes the effects of a function/method call on all of<br class="">+/// its arguments.<br class="">+typedef llvm::ImmutableMap<unsigned, ArgEffect> ArgEffects;<br class="">+<br class="">+/// Summary for a function with respect to ownership changes.<br class="">+class RetainSummary {<br class="">+  /// Args - a map of (index, ArgEffect) pairs, where index<br class="">+  ///  specifies the argument (starting from 0).  This can be sparsely<br class="">+  ///  populated; arguments with no entry in Args use 'DefaultArgEffect'.<br class="">+  ArgEffects Args;<br class="">+<br class="">+  /// DefaultArgEffect - The default ArgEffect to apply to arguments that<br class="">+  ///  do not have an entry in Args.<br class="">+  ArgEffect DefaultArgEffect;<br class="">+<br class="">+  /// Receiver - If this summary applies to an Objective-C message expression,<br class="">+  ///  this is the effect applied to the state of the receiver.<br class="">+  ArgEffect Receiver;<br class="">+<br class="">+  /// Ret - The effect on the return value.  Used to indicate if the<br class="">+  ///  function/method call returns a new tracked symbol.<br class="">+  RetEffect Ret;<br class="">+<br class="">+public:<br class="">+  RetainSummary(ArgEffects A, RetEffect R, ArgEffect defaultEff,<br class="">+                ArgEffect ReceiverEff)<br class="">+    : Args(A), DefaultArgEffect(defaultEff), Receiver(ReceiverEff), Ret(R) {}<br class="">+<br class="">+  /// getArg - Return the argument effect on the argument specified by<br class="">+  ///  idx (starting from 0).<br class="">+  ArgEffect getArg(unsigned idx) const {<br class="">+    if (const ArgEffect *AE = Args.lookup(idx))<br class="">+      return *AE;<br class="">+<br class="">+    return DefaultArgEffect;<br class="">+  }<br class="">+<br class="">+  void addArg(ArgEffects::Factory &af, unsigned idx, ArgEffect e) {<br class="">+    Args = af.add(Args, idx, e);<br class="">+  }<br class="">+<br class="">+  /// setDefaultArgEffect - Set the default argument effect.<br class="">+  void setDefaultArgEffect(ArgEffect E) {<br class="">+    DefaultArgEffect = E;<br class="">+  }<br class="">+<br class="">+  /// getRetEffect - Returns the effect on the return value of the call.<br class="">+  RetEffect getRetEffect() const { return Ret; }<br class="">+<br class="">+  /// setRetEffect - Set the effect of the return value of the call.<br class="">+  void setRetEffect(RetEffect E) { Ret = E; }<br class="">+<br class="">+<br class="">+  /// Sets the effect on the receiver of the message.<br class="">+  void setReceiverEffect(ArgEffect e) { Receiver = e; }<br class="">+<br class="">+  /// getReceiverEffect - Returns the effect on the receiver of the call.<br class="">+  ///  This is only meaningful if the summary applies to an ObjCMessageExpr*.<br class="">+  ArgEffect getReceiverEffect() const { return Receiver; }<br class="">+<br class="">+  /// Test if two retain summaries are identical. Note that merely equivalent<br class="">+  /// summaries are not necessarily identical (for example, if an explicit<br class="">+  /// argument effect matches the default effect).<br class="">+  bool operator==(const RetainSummary &Other) const {<br class="">+    return Args == Other.Args && DefaultArgEffect == Other.DefaultArgEffect &&<br class="">+           Receiver == Other.Receiver && Ret == Other.Ret;<br class="">+  }<br class="">+<br class="">+  /// Profile this summary for inclusion in a FoldingSet.<br class="">+  void Profile(llvm::FoldingSetNodeID& ID) const {<br class="">+    ID.Add(Args);<br class="">+    ID.Add(DefaultArgEffect);<br class="">+    ID.Add(Receiver);<br class="">+    ID.Add(Ret);<br class="">+  }<br class="">+<br class="">+  /// A retain summary is simple if it has no ArgEffects other than the default.<br class="">+  bool isSimple() const {<br class="">+    return Args.isEmpty();<br class="">+  }<br class="">+<br class="">+  ArgEffects getArgEffects() const { return Args; }<br class="">+<br class="">+private:<br class="">+  ArgEffect getDefaultArgEffect() const { return DefaultArgEffect; }<br class="">+<br class="">+  friend class RetainSummaryManager;<br class="">+};<br class="">+<br class="">+class ObjCSummaryCache {<br class="">+  typedef llvm::DenseMap<ObjCSummaryKey, const RetainSummary *> MapTy;<br class="">+  MapTy M;<br class="">+public:<br class="">+  ObjCSummaryCache() {}<br class="">+<br class="">+  const RetainSummary * find(const ObjCInterfaceDecl *D, Selector S) {<br class="">+    // Do a lookup with the (D,S) pair.  If we find a match return<br class="">+    // the iterator.<br class="">+    ObjCSummaryKey K(D, S);<br class="">+    MapTy::iterator I = M.find(K);<br class="">+<br class="">+    if (I != M.end())<br class="">+      return I->second;<br class="">+    if (!D)<br class="">+      return nullptr;<br class="">+<br class="">+    // Walk the super chain.  If we find a hit with a parent, we'll end<br class="">+    // up returning that summary.  We actually allow that key (null,S), as<br class="">+    // we cache summaries for the null ObjCInterfaceDecl* to allow us to<br class="">+    // generate initial summaries without having to worry about NSObject<br class="">+    // being declared.<br class="">+    // FIXME: We may change this at some point.<br class="">+    for (ObjCInterfaceDecl *C=D->getSuperClass() ;; C=C->getSuperClass()) {<br class="">+      if ((I = M.find(ObjCSummaryKey(C, S))) != M.end())<br class="">+        break;<br class="">+<br class="">+      if (!C)<br class="">+        return nullptr;<br class="">+    }<br class="">+<br class="">+    // Cache the summary with original key to make the next lookup faster<br class="">+    // and return the iterator.<br class="">+    const RetainSummary *Summ = I->second;<br class="">+    M[K] = Summ;<br class="">+    return Summ;<br class="">+  }<br class="">+<br class="">+  const RetainSummary *find(IdentifierInfo* II, Selector S) {<br class="">+    // FIXME: Class method lookup.  Right now we don't have a good way<br class="">+    // of going between IdentifierInfo* and the class hierarchy.<br class="">+    MapTy::iterator I = M.find(ObjCSummaryKey(II, S));<br class="">+<br class="">+    if (I == M.end())<br class="">+      I = M.find(ObjCSummaryKey(S));<br class="">+<br class="">+    return I == M.end() ? nullptr : I->second;<br class="">+  }<br class="">+<br class="">+  const RetainSummary *& operator[](ObjCSummaryKey K) {<br class="">+    return M[K];<br class="">+  }<br class="">+<br class="">+  const RetainSummary *& operator[](Selector S) {<br class="">+    return M[ ObjCSummaryKey(S) ];<br class="">+  }<br class="">+};<br class="">+<br class="">+class RetainSummaryManager {<br class="">+  typedef llvm::DenseMap<const FunctionDecl*, const RetainSummary *><br class="">+          FuncSummariesTy;<br class="">+<br class="">+  typedef ObjCSummaryCache ObjCMethodSummariesTy;<br class="">+<br class="">+  typedef llvm::FoldingSetNodeWrapper<RetainSummary> CachedSummaryNode;<br class="">+<br class="">+  /// Ctx - The ASTContext object for the analyzed ASTs.<br class="">+  ASTContext &Ctx;<br class="">+<br class="">+  /// Records whether or not the analyzed code runs in ARC mode.<br class="">+  const bool ARCEnabled;<br class="">+<br class="">+  /// FuncSummaries - A map from FunctionDecls to summaries.<br class="">+  FuncSummariesTy FuncSummaries;<br class="">+<br class="">+  /// ObjCClassMethodSummaries - A map from selectors (for instance methods)<br class="">+  ///  to summaries.<br class="">+  ObjCMethodSummariesTy ObjCClassMethodSummaries;<br class="">+<br class="">+  /// ObjCMethodSummaries - A map from selectors to summaries.<br class="">+  ObjCMethodSummariesTy ObjCMethodSummaries;<br class="">+<br class="">+  /// BPAlloc - A BumpPtrAllocator used for allocating summaries, ArgEffects,<br class="">+  ///  and all other data used by the checker.<br class="">+  llvm::BumpPtrAllocator BPAlloc;<br class="">+<br class="">+  /// AF - A factory for ArgEffects objects.<br class="">+  ArgEffects::Factory AF;<br class="">+<br class="">+  /// ScratchArgs - A holding buffer for construct ArgEffects.<br class="">+  ArgEffects ScratchArgs;<br class="">+<br class="">+  /// ObjCAllocRetE - Default return effect for methods returning Objective-C<br class="">+  ///  objects.<br class="">+  RetEffect ObjCAllocRetE;<br class="">+<br class="">+  /// ObjCInitRetE - Default return effect for init methods returning<br class="">+  ///   Objective-C objects.<br class="">+  RetEffect ObjCInitRetE;<br class="">+<br class="">+  /// SimpleSummaries - Used for uniquing summaries that don't have special<br class="">+  /// effects.<br class="">+  llvm::FoldingSet<CachedSummaryNode> SimpleSummaries;<br class="">+<br class="">+  /// getArgEffects - Returns a persistent ArgEffects object based on the<br class="">+  ///  data in ScratchArgs.<br class="">+  ArgEffects getArgEffects();<br class="">+<br class="">+  enum UnaryFuncKind { cfretain, cfrelease, cfautorelease, cfmakecollectable };<br class="">+<br class="">+  const RetainSummary *getUnarySummary(const FunctionType* FT,<br class="">+                                       UnaryFuncKind func);<br class="">+<br class="">+  const RetainSummary *getCFSummaryCreateRule(const FunctionDecl *FD);<br class="">+  const RetainSummary *getCFSummaryGetRule(const FunctionDecl *FD);<br class="">+  const RetainSummary *getCFCreateGetRuleSummary(const FunctionDecl *FD);<br class="">+<br class="">+  const RetainSummary *getPersistentSummary(const RetainSummary &OldSumm);<br class="">+<br class="">+  const RetainSummary *getPersistentSummary(RetEffect RetEff,<br class="">+                                            ArgEffect ReceiverEff = DoNothing,<br class="">+                                            ArgEffect DefaultEff = MayEscape) {<br class="">+    RetainSummary Summ(getArgEffects(), RetEff, DefaultEff, ReceiverEff);<br class="">+    return getPersistentSummary(Summ);<br class="">+  }<br class="">+<br class="">+  const RetainSummary *getDoNothingSummary() {<br class="">+    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);<br class="">+  }<br class="">+<br class="">+  const RetainSummary *getDefaultSummary() {<br class="">+    return getPersistentSummary(RetEffect::MakeNoRet(),<br class="">+                                DoNothing, MayEscape);<br class="">+  }<br class="">+<br class="">+  const RetainSummary *getPersistentStopSummary() {<br class="">+    return getPersistentSummary(RetEffect::MakeNoRet(),<br class="">+                                StopTracking, StopTracking);<br class="">+  }<br class="">+<br class="">+  void InitializeClassMethodSummaries();<br class="">+  void InitializeMethodSummaries();<br class="">+<br class="">+  void addNSObjectClsMethSummary(Selector S, const RetainSummary *Summ) {<br class="">+    ObjCClassMethodSummaries[S] = Summ;<br class="">+  }<br class="">+<br class="">+  void addNSObjectMethSummary(Selector S, const RetainSummary *Summ) {<br class="">+    ObjCMethodSummaries[S] = Summ;<br class="">+  }<br class="">+<br class="">+  void addClassMethSummary(const char* Cls, const char* name,<br class="">+                           const RetainSummary *Summ, bool isNullary = true) {<br class="">+    IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);<br class="">+    Selector S = isNullary ? GetNullarySelector(name, Ctx)<br class="">+                           : GetUnarySelector(name, Ctx);<br class="">+    ObjCClassMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;<br class="">+  }<br class="">+<br class="">+  void addInstMethSummary(const char* Cls, const char* nullaryName,<br class="">+                          const RetainSummary *Summ) {<br class="">+    IdentifierInfo* ClsII = &Ctx.Idents.get(Cls);<br class="">+    Selector S = GetNullarySelector(nullaryName, Ctx);<br class="">+    ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)]  = Summ;<br class="">+  }<br class="">+<br class="">+  template <typename... Keywords><br class="">+  void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries,<br class="">+                        const RetainSummary *Summ, Keywords *... Kws) {<br class="">+    Selector S = getKeywordSelector(Ctx, Kws...);<br class="">+    Summaries[ObjCSummaryKey(ClsII, S)] = Summ;<br class="">+  }<br class="">+<br class="">+  template <typename... Keywords><br class="">+  void addInstMethSummary(const char *Cls, const RetainSummary *Summ,<br class="">+                          Keywords *... Kws) {<br class="">+    addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, Kws...);<br class="">+  }<br class="">+<br class="">+  template <typename... Keywords><br class="">+  void addClsMethSummary(const char *Cls, const RetainSummary *Summ,<br class="">+                         Keywords *... Kws) {<br class="">+    addMethodSummary(&Ctx.Idents.get(Cls), ObjCClassMethodSummaries, Summ,<br class="">+                     Kws...);<br class="">+  }<br class="">+<br class="">+  template <typename... Keywords><br class="">+  void addClsMethSummary(IdentifierInfo *II, const RetainSummary *Summ,<br class="">+                         Keywords *... Kws) {<br class="">+    addMethodSummary(II, ObjCClassMethodSummaries, Summ, Kws...);<br class="">+  }<br class="">+<br class="">+  const RetainSummary * generateSummary(const FunctionDecl *FD,<br class="">+                                        bool &AllowAnnotations);<br class="">+<br class="">+public:<br class="">+  RetainSummaryManager(ASTContext &ctx, bool usesARC)<br class="">+   : Ctx(ctx),<br class="">+     ARCEnabled(usesARC),<br class="">+     AF(BPAlloc), ScratchArgs(AF.getEmptyMap()),<br class="">+     ObjCAllocRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)<br class="">+                               : RetEffect::MakeOwned(RetEffect::ObjC)),<br class="">+     ObjCInitRetE(usesARC ? RetEffect::MakeNotOwned(RetEffect::ObjC)<br class="">+                               : RetEffect::MakeOwnedWhenTrackedReceiver()) {<br class="">+    InitializeClassMethodSummaries();<br class="">+    InitializeMethodSummaries();<br class="">+  }<br class="">+<br class="">+  bool canEval(const CallExpr *CE,<br class="">+               const FunctionDecl *FD,<br class="">+               bool &hasTrustedImplementationAnnotation);<br class="">+<br class="">+  bool isTrustedReferenceCountImplementation(const FunctionDecl *FD);<br class="">+<br class="">+  const RetainSummary *getSummary(const CallEvent &Call,<br class="">+                                  QualType ReceiverType=QualType());<br class="">+<br class="">+  const RetainSummary *getFunctionSummary(const FunctionDecl *FD);<br class="">+<br class="">+  const RetainSummary *getMethodSummary(Selector S, const ObjCInterfaceDecl *ID,<br class="">+                                        const ObjCMethodDecl *MD,<br class="">+                                        QualType RetTy,<br class="">+                                        ObjCMethodSummariesTy &CachedSummaries);<br class="">+<br class="">+  const RetainSummary *<br class="">+  getInstanceMethodSummary(const ObjCMethodCall &M,<br class="">+                           QualType ReceiverType);<br class="">+<br class="">+  const RetainSummary *getClassMethodSummary(const ObjCMethodCall &M) {<br class="">+    assert(!M.isInstanceMessage());<br class="">+    const ObjCInterfaceDecl *Class = M.getReceiverInterface();<br class="">+<br class="">+    return getMethodSummary(M.getSelector(), Class, M.getDecl(),<br class="">+                            M.getResultType(), ObjCClassMethodSummaries);<br class="">+  }<br class="">+<br class="">+  /// getMethodSummary - This version of getMethodSummary is used to query<br class="">+  ///  the summary for the current method being analyzed.<br class="">+  const RetainSummary *getMethodSummary(const ObjCMethodDecl *MD) {<br class="">+    const ObjCInterfaceDecl *ID = MD->getClassInterface();<br class="">+    Selector S = MD->getSelector();<br class="">+    QualType ResultTy = MD->getReturnType();<br class="">+<br class="">+    ObjCMethodSummariesTy *CachedSummaries;<br class="">+    if (MD->isInstanceMethod())<br class="">+      CachedSummaries = &ObjCMethodSummaries;<br class="">+    else<br class="">+      CachedSummaries = &ObjCClassMethodSummaries;<br class="">+<br class="">+    return getMethodSummary(S, ID, MD, ResultTy, *CachedSummaries);<br class="">+  }<br class="">+<br class="">+  const RetainSummary *getStandardMethodSummary(const ObjCMethodDecl *MD,<br class="">+                                                Selector S, QualType RetTy);<br class="">+<br class="">+  /// Determine if there is a special return effect for this function or method.<br class="">+  Optional<RetEffect> getRetEffectFromAnnotations(QualType RetTy,<br class="">+                                                  const Decl *D);<br class="">+<br class="">+  void updateSummaryFromAnnotations(const RetainSummary *&Summ,<br class="">+                                    const ObjCMethodDecl *MD);<br class="">+<br class="">+  void updateSummaryFromAnnotations(const RetainSummary *&Summ,<br class="">+                                    const FunctionDecl *FD);<br class="">+<br class="">+  void updateSummaryForCall(const RetainSummary *&Summ,<br class="">+                            const CallEvent &Call);<br class="">+<br class="">+  bool isARCEnabled() const { return ARCEnabled; }<br class="">+<br class="">+  RetEffect getObjAllocRetEffect() const { return ObjCAllocRetE; }<br class="">+<br class="">+  friend class RetainSummaryTemplate;<br class="">+};<br class="">+<br class="">+// Used to avoid allocating long-term (BPAlloc'd) memory for default retain<br class="">+// summaries. If a function or method looks like it has a default summary, but<br class="">+// it has annotations, the annotations are added to the stack-based template<br class="">+// and then copied into managed memory.<br class="">+class RetainSummaryTemplate {<br class="">+  RetainSummaryManager &Manager;<br class="">+  const RetainSummary *&RealSummary;<br class="">+  RetainSummary ScratchSummary;<br class="">+  bool Accessed;<br class="">+public:<br class="">+  RetainSummaryTemplate(const RetainSummary *&real, RetainSummaryManager &mgr)<br class="">+    : Manager(mgr), RealSummary(real), ScratchSummary(*real), Accessed(false) {}<br class="">+<br class="">+  ~RetainSummaryTemplate() {<br class="">+    if (Accessed)<br class="">+      RealSummary = Manager.getPersistentSummary(ScratchSummary);<br class="">+  }<br class="">+<br class="">+  RetainSummary &operator*() {<br class="">+    Accessed = true;<br class="">+    return ScratchSummary;<br class="">+  }<br class="">+<br class="">+  RetainSummary *operator->() {<br class="">+    Accessed = true;<br class="">+    return &ScratchSummary;<br class="">+  }<br class="">+};<br class="">+<br class="">+} // end namespace ento<br class="">+} // end namespace clang<br class="">+<br class="">+#endif<br class=""><br class="">Added: cfe/trunk/include/clang/StaticAnalyzer/Checkers/SelectorExtras.h<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/SelectorExtras.h?rev=340114&view=auto" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Checkers/SelectorExtras.h?rev=340114&view=auto</a><br class="">==============================================================================<br class="">--- cfe/trunk/include/clang/StaticAnalyzer/Checkers/SelectorExtras.h (added)<br class="">+++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/SelectorExtras.h Fri Aug 17 18:45:50 2018<br class="">@@ -0,0 +1,39 @@<br class="">+//=== SelectorExtras.h - Helpers for checkers using selectors -----*- C++ -*-=//<br class="">+//<br class="">+//                     The LLVM Compiler Infrastructure<br class="">+//<br class="">+// This file is distributed under the University of Illinois Open Source<br class="">+// License. See LICENSE.TXT for details.<br class="">+//<br class="">+//===----------------------------------------------------------------------===//<br class="">+<br class="">+#ifndef LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SELECTOREXTRAS_H<br class="">+#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SELECTOREXTRAS_H<br class="">+<br class="">+#include "clang/AST/ASTContext.h"<br class="">+<br class="">+namespace clang {<br class="">+namespace ento {<br class="">+<br class="">+template <typename... IdentifierInfos><br class="">+static inline Selector getKeywordSelector(ASTContext &Ctx,<br class="">+                                          IdentifierInfos *... IIs) {<br class="">+  static_assert(sizeof...(IdentifierInfos),<br class="">+                "keyword selectors must have at least one argument");<br class="">+  SmallVector<IdentifierInfo *, 10> II({&Ctx.Idents.get(IIs)...});<br class="">+<br class="">+  return Ctx.Selectors.getSelector(II.size(), &II[0]);<br class="">+}<br class="">+<br class="">+template <typename... IdentifierInfos><br class="">+static inline void lazyInitKeywordSelector(Selector &Sel, ASTContext &Ctx,<br class="">+                                           IdentifierInfos *... IIs) {<br class="">+  if (!Sel.isNull())<br class="">+    return;<br class="">+  Sel = getKeywordSelector(Ctx, IIs...);<br class="">+}<br class="">+<br class="">+} // end namespace ento<br class="">+} // end namespace clang<br class="">+<br class="">+#endif<br class=""><br class="">Modified: cfe/trunk/lib/ARCMigrate/CMakeLists.txt<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/CMakeLists.txt?rev=340114&r1=340113&r2=340114&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/CMakeLists.txt?rev=340114&r1=340113&r2=340114&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/ARCMigrate/CMakeLists.txt (original)<br class="">+++ cfe/trunk/lib/ARCMigrate/CMakeLists.txt Fri Aug 17 18:45:50 2018<br class="">@@ -34,5 +34,4 @@ add_clang_library(clangARCMigrate<br class="">  clangRewrite<br class="">  clangSema<br class="">  clangSerialization<br class="">-  clangStaticAnalyzerCheckers<br class="">  )<br class=""><br class="">Modified: cfe/trunk/lib/ARCMigrate/ObjCMT.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=340114&r1=340113&r2=340114&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ARCMigrate/ObjCMT.cpp?rev=340114&r1=340113&r2=340114&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/ARCMigrate/ObjCMT.cpp (original)<br class="">+++ cfe/trunk/lib/ARCMigrate/ObjCMT.cpp Fri Aug 17 18:45:50 2018<br class="">@@ -8,7 +8,7 @@<br class="">//===----------------------------------------------------------------------===//<br class=""><br class="">#include "Transforms.h"<br class="">-#include "clang/Analysis/ObjCRetainCount.h"<br class="">+#include "clang/Analysis/RetainSummaryManager.h"<br class="">#include "clang/ARCMigrate/ARCMT.h"<br class="">#include "clang/ARCMigrate/ARCMTActions.h"<br class="">#include "clang/AST/ASTConsumer.h"<br class="">@@ -35,8 +35,8 @@<br class="">#include "llvm/Support/YAMLParser.h"<br class=""><br class="">using namespace clang;<br class="">+using namespace ento;<br class="">using namespace arcmt;<br class="">-using namespace ento::objc_retain;<br class=""><br class="">namespace {<br class=""><br class=""><br class="">Modified: cfe/trunk/lib/Analysis/CMakeLists.txt<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=340114&r1=340113&r2=340114&view=diff" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CMakeLists.txt?rev=340114&r1=340113&r2=340114&view=diff</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Analysis/CMakeLists.txt (original)<br class="">+++ cfe/trunk/lib/Analysis/CMakeLists.txt Fri Aug 17 18:45:50 2018<br class="">@@ -24,6 +24,7 @@ add_clang_library(clangAnalysis<br class="">  ProgramPoint.cpp<br class="">  PseudoConstantAnalysis.cpp<br class="">  ReachableCode.cpp<br class="">+  RetainSummaryManager.cpp<br class="">  ScanfFormatString.cpp<br class="">  ThreadSafety.cpp<br class="">  ThreadSafetyCommon.cpp<br class=""><br class="">Added: cfe/trunk/lib/Analysis/RetainSummaryManager.cpp<br class="">URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RetainSummaryManager.cpp?rev=340114&view=auto" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/RetainSummaryManager.cpp?rev=340114&view=auto</a><br class="">==============================================================================<br class="">--- cfe/trunk/lib/Analysis/RetainSummaryManager.cpp (added)<br class="">+++ cfe/trunk/lib/Analysis/RetainSummaryManager.cpp Fri Aug 17 18:45:50 2018<br class="">@@ -0,0 +1,902 @@<br class="">+//== RetainSummaryManager.cpp - Summaries for reference counting --*- C++ -*--//<br class="">+//<br class="">+//                     The LLVM Compiler Infrastructure<br class="">+//<br class="">+// This file is distributed under the University of Illinois Open Source<br class="">+// License. See LICENSE.TXT for details.<br class="">+//<br class="">+//===----------------------------------------------------------------------===//<br class="">+//<br class="">+//  This file defines summaries implementation for retain counting, which<br class="">+//  implements a reference count checker for Core Foundation and Cocoa<br class="">+//  on (Mac OS X).<br class="">+//<br class="">+//===----------------------------------------------------------------------===//<br class="">+<br class="">+#include "clang/Analysis/RetainSummaryManager.h"<br class="">+#include "clang/Analysis/DomainSpecific/CocoaConventions.h"<br class="">+#include "clang/AST/Attr.h"<br class="">+#include "clang/AST/DeclCXX.h"<br class="">+#include "clang/AST/DeclObjC.h"<br class="">+#include "clang/AST/ParentMap.h"<br class="">+<br class="">+using namespace clang;<br class="">+using namespace ento;<br class="">+<br class="">+ArgEffects RetainSummaryManager::getArgEffects() {<br class="">+  ArgEffects AE = ScratchArgs;<br class="">+  ScratchArgs = AF.getEmptyMap();<br class="">+  return AE;<br class="">+}<br class="">+<br class="">+const RetainSummary *<br class="">+RetainSummaryManager::getPersistentSummary(const RetainSummary &OldSumm) {<br class="">+  // Unique "simple" summaries -- those without ArgEffects.<br class="">+  if (OldSumm.isSimple()) {<br class="">+    ::llvm::FoldingSetNodeID ID;<br class="">+    OldSumm.Profile(ID);<br class="">+<br class="">+    void *Pos;<br class="">+    CachedSummaryNode *N = SimpleSummaries.FindNodeOrInsertPos(ID, Pos);<br class="">+<br class="">+    if (!N) {<br class="">+      N = (CachedSummaryNode *) BPAlloc.Allocate<CachedSummaryNode>();<br class="">+      new (N) CachedSummaryNode(OldSumm);<br class="">+      SimpleSummaries.InsertNode(N, Pos);<br class="">+    }<br class="">+<br class="">+    return &N->getValue();<br class="">+  }<br class="">+<br class="">+  RetainSummary *Summ = (RetainSummary *) BPAlloc.Allocate<RetainSummary>();<br class="">+  new (Summ) RetainSummary(OldSumm);<br class="">+  return Summ;<br class="">+}<br class="">+<br class="">+static bool hasRCAnnotation(const Decl *D, StringRef rcAnnotation) {<br class="">+  for (const auto *Ann : D->specific_attrs<AnnotateAttr>()) {<br class="">+    if (Ann->getAnnotation() == rcAnnotation)<br class="">+      return true;<br class="">+  }<br class="">+  return false;<br class="">+}<br class="">+<br class="">+static bool isRetain(const FunctionDecl *FD, StringRef FName) {<br class="">+  return FName.startswith_lower("retain") || FName.endswith_lower("retain");<br class="">+}<br class="">+<br class="">+static bool isRelease(const FunctionDecl *FD, StringRef FName) {<br class="">+  return FName.startswith_lower("release") || FName.endswith_lower("release");<br class="">+}<br class="">+<br class="">+static bool isAutorelease(const FunctionDecl *FD, StringRef FName) {<br class="">+  return FName.startswith_lower("autorelease") ||<br class="">+         FName.endswith_lower("autorelease");<br class="">+}<br class="">+<br class="">+static bool isMakeCollectable(StringRef FName) {<br class="">+  return FName.contains_lower("MakeCollectable");<br class="">+}<br class="">+<br class="">+const RetainSummary *<br class="">+RetainSummaryManager::generateSummary(const FunctionDecl *FD,<br class="">+                                      bool &AllowAnnotations) {<br class="">+  // We generate "stop" summaries for implicitly defined functions.<br class="">+  if (FD->isImplicit()) {<br class="">+    return getPersistentStopSummary();<br class="">+  }<br class="">+<br class="">+  // [PR 3337] Use 'getAs<FunctionType>' to strip away any typedefs on the<br class="">+  // function's type.<br class="">+  const FunctionType *FT = FD->getType()->getAs<FunctionType>();<br class="">+  const IdentifierInfo *II = FD->getIdentifier();<br class="">+  if (!II)<br class="">+    return getDefaultSummary();<br class="">+<br class="">+  StringRef FName = II->getName();<br class="">+<br class="">+  // Strip away preceding '_'.  Doing this here will effect all the checks<br class="">+  // down below.<br class="">+  FName = FName.substr(FName.find_first_not_of('_'));<br class="">+<br class="">+  // Inspect the result type.<br class="">+  QualType RetTy = FT->getReturnType();<br class="">+  std::string RetTyName = RetTy.getAsString();<br class="">+<br class="">+  // FIXME: This should all be refactored into a chain of "summary lookup"<br class="">+  //  filters.<br class="">+  assert(ScratchArgs.isEmpty());<br class="">+<br class="">+  if (FName == "pthread_create" || FName == "pthread_setspecific") {<br class="">+    // Part of: <<a href="rdar://problem/7299394" class="">rdar://problem/7299394</a>> and <<a href="rdar://problem/11282706" class="">rdar://problem/11282706</a>>.<br class="">+    // This will be addressed better with IPA.<br class="">+    return getPersistentStopSummary();<br class="">+  } else if(FName == "NSMakeCollectable") {<br class="">+    // Handle: id NSMakeCollectable(CFTypeRef)<br class="">+    AllowAnnotations = false;<br class="">+    return RetTy->isObjCIdType() ? getUnarySummary(FT, cfmakecollectable)<br class="">+                                 : getPersistentStopSummary();<br class="">+  } else if (FName == "CFPlugInInstanceCreate") {<br class="">+    return getPersistentSummary(RetEffect::MakeNoRet());<br class="">+  } else if (FName == "IORegistryEntrySearchCFProperty" ||<br class="">+             (RetTyName == "CFMutableDictionaryRef" &&<br class="">+              (FName == "IOBSDNameMatching" || FName == "IOServiceMatching" ||<br class="">+               FName == "IOServiceNameMatching" ||<br class="">+               FName == "IORegistryEntryIDMatching" ||<br class="">+               FName == "IOOpenFirmwarePathMatching"))) {<br class="">+    // Part of <<a href="rdar://problem/6961230" class="">rdar://problem/6961230</a>>. (IOKit)<br class="">+    // This should be addressed using a API table.<br class="">+    return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF), DoNothing,<br class="">+                             DoNothing);<br class="">+  } else if (FName == "IOServiceGetMatchingService" ||<br class="">+             FName == "IOServiceGetMatchingServices") {<br class="">+    // FIXES: <<a href="rdar://problem/6326900" class="">rdar://problem/6326900</a>><br class="">+    // This should be addressed using a API table.  This strcmp is also<br class="">+    // a little gross, but there is no need to super optimize here.<br class="">+    ScratchArgs = AF.add(ScratchArgs, 1, DecRef);<br class="">+    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);<br class="">+  } else if (FName == "IOServiceAddNotification" ||<br class="">+             FName == "IOServiceAddMatchingNotification") {<br class="">+    // Part of <<a href="rdar://problem/6961230" class="">rdar://problem/6961230</a>>. (IOKit)<br class="">+    // This should be addressed using a API table.<br class="">+    ScratchArgs = AF.add(ScratchArgs, 2, DecRef);<br class="">+    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);<br class="">+  } else if (FName == "CVPixelBufferCreateWithBytes") {<br class="">+    // FIXES: <<a href="rdar://problem/7283567" class="">rdar://problem/7283567</a>><br class="">+    // Eventually this can be improved by recognizing that the pixel<br class="">+    // buffer passed to CVPixelBufferCreateWithBytes is released via<br class="">+    // a callback and doing full IPA to make sure this is done correctly.<br class="">+    // FIXME: This function has an out parameter that returns an<br class="">+    // allocated object.<br class="">+    ScratchArgs = AF.add(ScratchArgs, 7, StopTracking);<br class="">+    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);<br class="">+  } else if (FName == "CGBitmapContextCreateWithData") {<br class="">+    // FIXES: <<a href="rdar://problem/7358899" class="">rdar://problem/7358899</a>><br class="">+    // Eventually this can be improved by recognizing that 'releaseInfo'<br class="">+    // passed to CGBitmapContextCreateWithData is released via<br class="">+    // a callback and doing full IPA to make sure this is done correctly.<br class="">+    ScratchArgs = AF.add(ScratchArgs, 8, StopTracking);<br class="">+    return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF), DoNothing,<br class="">+                             DoNothing);<br class="">+  } else if (FName == "CVPixelBufferCreateWithPlanarBytes") {<br class="">+    // FIXES: <<a href="rdar://problem/7283567" class="">rdar://problem/7283567</a>><br class="">+    // Eventually this can be improved by recognizing that the pixel<br class="">+    // buffer passed to CVPixelBufferCreateWithPlanarBytes is released<br class="">+    // via a callback and doing full IPA to make sure this is done<br class="">+    // correctly.<br class="">+    ScratchArgs = AF.add(ScratchArgs, 12, StopTracking);<br class="">+    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);<br class="">+  } else if (FName == "VTCompressionSessionEncodeFrame") {<br class="">+    // The context argument passed to VTCompressionSessionEncodeFrame()<br class="">+    // is passed to the callback specified when creating the session<br class="">+    // (e.g. with VTCompressionSessionCreate()) which can release it.<br class="">+    // To account for this possibility, conservatively stop tracking<br class="">+    // the context.<br class="">+    ScratchArgs = AF.add(ScratchArgs, 5, StopTracking);<br class="">+    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);<br class="">+  } else if (FName == "dispatch_set_context" ||<br class="">+             FName == "xpc_connection_set_context") {<br class="">+    // <<a href="rdar://problem/11059275" class="">rdar://problem/11059275</a>> - The analyzer currently doesn't have<br class="">+    // a good way to reason about the finalizer function for libdispatch.<br class="">+    // If we pass a context object that is memory managed, stop tracking it.<br class="">+    // <<a href="rdar://problem/13783514" class="">rdar://problem/13783514</a>> - Same problem, but for XPC.<br class="">+    // FIXME: this hack should possibly go away once we can handle<br class="">+    // libdispatch and XPC finalizers.<br class="">+    ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);<br class="">+    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);<br class="">+  } else if (FName.startswith("NSLog")) {<br class="">+    return getDoNothingSummary();<br class="">+  } else if (FName.startswith("NS") &&<br class="">+             (FName.find("Insert") != StringRef::npos)) {<br class="">+    // Whitelist NSXXInsertXX, for example NSMapInsertIfAbsent, since they can<br class="">+    // be deallocated by NSMapRemove. (<a href="radar://11152419" class="">radar://11152419</a>)<br class="">+    ScratchArgs = AF.add(ScratchArgs, 1, StopTracking);<br class="">+    ScratchArgs = AF.add(ScratchArgs, 2, StopTracking);<br class="">+    return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);<br class="">+  }<br class="">+<br class="">+  if (RetTy->isPointerType()) {<br class="">+    // For CoreFoundation ('CF') types.<br class="">+    if (cocoa::isRefType(RetTy, "CF", FName)) {<br class="">+      if (isRetain(FD, FName)) {<br class="">+        // CFRetain isn't supposed to be annotated. However, this may as well<br class="">+        // be a user-made "safe" CFRetain function that is incorrectly<br class="">+        // annotated as cf_returns_retained due to lack of better options.<br class="">+        // We want to ignore such annotation.<br class="">+        AllowAnnotations = false;<br class="">+<br class="">+        return getUnarySummary(FT, cfretain);<br class="">+      } else if (isAutorelease(FD, FName)) {<br class="">+        // The headers use cf_consumed, but we can fully model CFAutorelease<br class="">+        // ourselves.<br class="">+        AllowAnnotations = false;<br class="">+<br class="">+        return getUnarySummary(FT, cfautorelease);<br class="">+      } else if (isMakeCollectable(FName)) {<br class="">+        AllowAnnotations = false;<br class="">+        return getUnarySummary(FT, cfmakecollectable);<br class="">+      } else {<br class="">+        return getCFCreateGetRuleSummary(FD);<br class="">+      }<br class="">+    }<br class="">+<br class="">+    // For CoreGraphics ('CG') and CoreVideo ('CV') types.<br class="">+    if (cocoa::isRefType(RetTy, "CG", FName) ||<br class="">+        cocoa::isRefType(RetTy, "CV", FName)) {<br class="">+      if (isRetain(FD, FName))<br class="">+        return getUnarySummary(FT, cfretain);<br class="">+      else<br class="">+        return getCFCreateGetRuleSummary(FD);<br class="">+    }<br class="">+<br class="">+    // For all other CF-style types, use the Create/Get<br class="">+    // rule for summaries but don't support Retain functions<br class="">+    // with framework-specific prefixes.<br class="">+    if (coreFoundation::isCFObjectRef(RetTy)) {<br class="">+      return getCFCreateGetRuleSummary(FD);<br class="">+    }<br class="">+<br class="">+    if (FD->hasAttr<CFAuditedTransferAttr>()) {<br class="">+      return getCFCreateGetRuleSummary(FD);<br class="">+    }<br class="">+  }<br class="">+<br class="">+  // Check for release functions, the only kind of functions that we care<br class="">+  // about that don't return a pointer type.<br class="">+  if (FName.size() >= 2 && FName[0] == 'C' &&<br class="">+      (FName[1] == 'F' || FName[1] == 'G')) {<br class="">+    // Test for 'CGCF'.<br class="">+    FName = FName.substr(FName.startswith("CGCF") ? 4 : 2);<br class="">+<br class="">+    if (isRelease(FD, FName))<br class="">+      return getUnarySummary(FT, cfrelease);<br class="">+    else {<br class="">+      assert(ScratchArgs.isEmpty());<br class="">+      // Remaining CoreFoundation and CoreGraphics functions.<br class="">+      // We use to assume that they all strictly followed the ownership idiom<br class="">+      // and that ownership cannot be transferred.  While this is technically<br class="">+      // correct, many methods allow a tracked object to escape.  For example:<br class="">+      //<br class="">+      //   CFMutableDictionaryRef x = CFDictionaryCreateMutable(...);<br class="">+      //   CFDictionaryAddValue(y, key, x);<br class="">+      //   CFRelease(x);<br class="">+      //   ... it is okay to use 'x' since 'y' has a reference to it<br class="">+      //<br class="">+      // We handle this and similar cases with the follow heuristic.  If the<br class="">+      // function name contains "InsertValue", "SetValue", "AddValue",<br class="">+      // "AppendValue", or "SetAttribute", then we assume that arguments may<br class="">+      // "escape."  This means that something else holds on to the object,<br class="">+      // allowing it be used even after its local retain count drops to 0.<br class="">+      ArgEffect E = (StrInStrNoCase(FName, "InsertValue") != StringRef::npos ||<br class="">+                     StrInStrNoCase(FName, "AddValue") != StringRef::npos ||<br class="">+                     StrInStrNoCase(FName, "SetValue") != StringRef::npos ||<br class="">+                     StrInStrNoCase(FName, "AppendValue") != StringRef::npos ||<br class="">+                     StrInStrNoCase(FName, "SetAttribute") != StringRef::npos)<br class="">+                        ? MayEscape<br class="">+                        : DoNothing;<br class="">+<br class="">+      return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, E);<br class="">+    }<br class="">+  }<br class="">+<br class="">+  return getDefaultSummary();<br class="">+}<br class="">+<br class="">+const RetainSummary *<br class="">+RetainSummaryManager::getFunctionSummary(const FunctionDecl *FD) {<br class="">+  // If we don't know what function we're calling, use our default summary.<br class="">+  if (!FD)<br class="">+    return getDefaultSummary();<br class="">+<br class="">+  // Look up a summary in our cache of FunctionDecls -> Summaries.<br class="">+  FuncSummariesTy::iterator I = FuncSummaries.find(FD);<br class="">+  if (I != FuncSummaries.end())<br class="">+    return I->second;<br class="">+<br class="">+  // No summary?  Generate one.<br class="">+  bool AllowAnnotations = true;<br class="">+  const RetainSummary *S = generateSummary(FD, AllowAnnotations);<br class="">+<br class="">+  // Annotations override defaults.<br class="">+  if (AllowAnnotations)<br class="">+    updateSummaryFromAnnotations(S, FD);<br class="">+<br class="">+  FuncSummaries[FD] = S;<br class="">+  return S;<br class="">+}<br class="">+<br class="">+//===----------------------------------------------------------------------===//<br class="">+// Summary creation for functions (largely uses of Core Foundation).<br class="">+//===----------------------------------------------------------------------===//<br class="">+<br class="">+static ArgEffect getStopTrackingHardEquivalent(ArgEffect E) {<br class="">+  switch (E) {<br class="">+  case DoNothing:<br class="">+  case Autorelease:<br class="">+  case DecRefBridgedTransferred:<br class="">+  case IncRef:<br class="">+  case IncRefMsg:<br class="">+  case MakeCollectable:<br class="">+  case UnretainedOutParameter:<br class="">+  case RetainedOutParameter:<br class="">+  case MayEscape:<br class="">+  case StopTracking:<br class="">+  case StopTrackingHard:<br class="">+    return StopTrackingHard;<br class="">+  case DecRef:<br class="">+  case DecRefAndStopTrackingHard:<br class="">+    return DecRefAndStopTrackingHard;<br class="">+  case DecRefMsg:<br class="">+  case DecRefMsgAndStopTrackingHard:<br class="">+    return DecRefMsgAndStopTrackingHard;<br class="">+  case Dealloc:<br class="">+    return Dealloc;<br class="">+  }<br class="">+<br class="">+  llvm_unreachable("Unknown ArgEffect kind");<br class="">+}<br class="">+<br class="">+void RetainSummaryManager::updateSummaryForCall(const RetainSummary *&S,<br class="">+                                                const CallEvent &Call) {<br class="">+  if (Call.hasNonZeroCallbackArg()) {<br class="">+    ArgEffect RecEffect =<br class="">+      getStopTrackingHardEquivalent(S->getReceiverEffect());<br class="">+    ArgEffect DefEffect =<br class="">+      getStopTrackingHardEquivalent(S->getDefaultArgEffect());<br class="">+<br class="">+    ArgEffects CustomArgEffects = S->getArgEffects();<br class="">+    for (ArgEffects::iterator I = CustomArgEffects.begin(),<br class="">+                              E = CustomArgEffects.end();<br class="">+         I != E; ++I) {<br class="">+      ArgEffect Translated = getStopTrackingHardEquivalent(I->second);<br class="">+      if (Translated != DefEffect)<br class="">+        ScratchArgs = AF.add(ScratchArgs, I->first, Translated);<br class="">+    }<br class="">+<br class="">+    RetEffect RE = RetEffect::MakeNoRetHard();<br class="">+<br class="">+    // Special cases where the callback argument CANNOT free the return value.<br class="">+    // This can generally only happen if we know that the callback will only be<br class="">+    // called when the return value is already being deallocated.<br class="">+    if (const SimpleFunctionCall *FC = dyn_cast<SimpleFunctionCall>(&Call)) {<br class="">+      if (IdentifierInfo *Name = FC->getDecl()->getIdentifier()) {<br class="">+        // When the CGBitmapContext is deallocated, the callback here will free<br class="">+        // the associated data buffer.<br class="">+        // The callback in dispatch_data_create frees the buffer, but not<br class="">+        // the data object.<br class="">+        if (Name->isStr("CGBitmapContextCreateWithData") ||<br class="">+            Name->isStr("dispatch_data_create"))<br class="">+          RE = S->getRetEffect();<br class="">+      }<br class="">+    }<br class="">+<br class="">+    S = getPersistentSummary(RE, RecEffect, DefEffect);<br class="">+  }<br class="">+<br class="">+  // Special case '[super init];' and '[self init];'<br class="">+  //<br class="">+  // Even though calling '[super init]' without assigning the result to self<br class="">+  // and checking if the parent returns 'nil' is a bad pattern, it is common.<br class="">+  // Additionally, our Self Init checker already warns about it. To avoid<br class="">+  // overwhelming the user with messages from both checkers, we model the case<br class="">+  // of '[super init]' in cases when it is not consumed by another expression<br class="">+  // as if the call preserves the value of 'self'; essentially, assuming it can<br class="">+  // never fail and return 'nil'.<br class="">+  // Note, we don't want to just stop tracking the value since we want the<br class="">+  // RetainCount checker to report leaks and use-after-free if SelfInit checker<br class="">+  // is turned off.<br class="">+  if (const ObjCMethodCall *MC = dyn_cast<ObjCMethodCall>(&Call)) {<br class="">+    if (MC->getMethodFamily() == OMF_init && MC->isReceiverSelfOrSuper()) {<br class="">+<br class="">+      // Check if the message is not consumed, we know it will not be used in<br class="">+      // an assignment, ex: "self = [super init]".<br class="">+      const Expr *ME = MC->getOriginExpr();<br class="">+      const LocationContext *LCtx = MC->getLocationContext();<br class="">+      ParentMap &PM = LCtx->getAnalysisDeclContext()->getParentMap();<br class="">+      if (!PM.isConsumedExpr(ME)) {<br class="">+        RetainSummaryTemplate ModifiableSummaryTemplate(S, *this);<br class="">+        ModifiableSummaryTemplate->setReceiverEffect(DoNothing);<br class="">+        ModifiableSummaryTemplate->setRetEffect(RetEffect::MakeNoRet());<br class="">+      }<br class="">+    }<br class="">+  }<br class="">+}<br class="">+<br class="">+const RetainSummary *<br class="">+RetainSummaryManager::getSummary(const CallEvent &Call,<br class="">+                                 QualType ReceiverType) {<br class="">+  const RetainSummary *Summ;<br class="">+  switch (Call.getKind()) {<br class="">+  case CE_Function:<br class="">+    Summ = getFunctionSummary(cast<SimpleFunctionCall>(Call).getDecl());<br class="">+    break;<br class="">+  case CE_CXXMember:<br class="">+  case CE_CXXMemberOperator:<br class="">+  case CE_Block:<br class="">+  case CE_CXXConstructor:<br class="">+  case CE_CXXDestructor:<br class="">+  case CE_CXXAllocator:<br class="">+    // FIXME: These calls are currently unsupported.<br class="">+    return getPersistentStopSummary();<br class="">+  case CE_ObjCMessage: {<br class="">+    const ObjCMethodCall &Msg = cast<ObjCMethodCall>(Call);<br class="">+    if (Msg.isInstanceMessage())<br class="">+      Summ = getInstanceMethodSummary(Msg, ReceiverType);<br class="">+    else<br class="">+      Summ = getClassMethodSummary(Msg);<br class="">+    break;<br class="">+  }<br class="">+  }<br class="">+<br class="">+  updateSummaryForCall(Summ, Call);<br class="">+<br class="">+  assert(Summ && "Unknown call type?");<br class="">+  return Summ;<br class="">+}<br class="">+<br class="">+<br class="">+const RetainSummary *<br class="">+RetainSummaryManager::getCFCreateGetRuleSummary(const FunctionDecl *FD) {<br class="">+  if (coreFoundation::followsCreateRule(FD))<br class="">+    return getCFSummaryCreateRule(FD);<br class="">+<br class="">+  return getCFSummaryGetRule(FD);<br class="">+}<br class="">+<br class="">+bool RetainSummaryManager::isTrustedReferenceCountImplementation(<br class="">+    const FunctionDecl *FD) {<br class="">+  return hasRCAnnotation(FD, "rc_ownership_trusted_implementation");<br class="">+}<br class="">+<br class="">+bool RetainSummaryManager::canEval(const CallExpr *CE,<br class="">+                                   const FunctionDecl *FD,<br class="">+                                   bool &hasTrustedImplementationAnnotation) {<br class="">+  // For now, we're only handling the functions that return aliases of their<br class="">+  // arguments: CFRetain (and its families).<br class="">+  // Eventually we should add other functions we can model entirely,<br class="">+  // such as CFRelease, which don't invalidate their arguments or globals.<br class="">+  if (CE->getNumArgs() != 1)<br class="">+    return false;<br class="">+<br class="">+  IdentifierInfo *II = FD->getIdentifier();<br class="">+  if (!II)<br class="">+    return false;<br class="">+<br class="">+  StringRef FName = II->getName();<br class="">+  FName = FName.substr(FName.find_first_not_of('_'));<br class="">+<br class="">+  QualType ResultTy = CE->getCallReturnType(Ctx);<br class="">+  if (ResultTy->isObjCIdType()) {<br class="">+    return II->isStr("NSMakeCollectable");<br class="">+  } else if (ResultTy->isPointerType()) {<br class="">+    // Handle: (CF|CG|CV)Retain<br class="">+    //         CFAutorelease<br class="">+    // It's okay to be a little sloppy here.<br class="">+    if (cocoa::isRefType(ResultTy, "CF", FName) ||<br class="">+        cocoa::isRefType(ResultTy, "CG", FName) ||<br class="">+        cocoa::isRefType(ResultTy, "CV", FName))<br class="">+      return isRetain(FD, FName) || isAutorelease(FD, FName) ||<br class="">+             isMakeCollectable(FName);<br class="">+<br class="">+    const FunctionDecl* FDD = FD->getDefinition();<br class="">+    if (FDD && isTrustedReferenceCountImplementation(FDD)) {<br class="">+      hasTrustedImplementationAnnotation = true;<br class="">+      return true;<br class="">+    }<br class="">+  }<br class="">+<br class="">+  return false;<br class="">+<br class="">+}<br class="">+<br class="">+const RetainSummary *<br class="">+RetainSummaryManager::getUnarySummary(const FunctionType* FT,<br class="">+                                      UnaryFuncKind func) {<br class="">+<br class="">+  // Sanity check that this is *really* a unary function.  This can<br class="">+  // happen if people do weird things.<br class="">+  const FunctionProtoType* FTP = dyn_cast<FunctionProtoType>(FT);<br class="">+  if (!FTP || FTP->getNumParams() != 1)<br class="">+    return getPersistentStopSummary();<br class="">+<br class="">+  assert (ScratchArgs.isEmpty());<br class="">+<br class="">+  ArgEffect Effect;<br class="">+  switch (func) {<br class="">+  case cfretain: Effect = IncRef; break;<br class="">+  case cfrelease: Effect = DecRef; break;<br class="">+  case cfautorelease: Effect = Autorelease; break;<br class="">+  case cfmakecollectable: Effect = MakeCollectable; break;<br class="">+  }<br class="">+<br class="">+  ScratchArgs = AF.add(ScratchArgs, 0, Effect);<br class="">+  return getPersistentSummary(RetEffect::MakeNoRet(), DoNothing, DoNothing);<br class="">+}<br class="">+<br class="">+const RetainSummary *<br class="">+RetainSummaryManager::getCFSummaryCreateRule(const FunctionDecl *FD) {<br class="">+  assert (ScratchArgs.isEmpty());<br class="">+<br class="">+  return getPersistentSummary(RetEffect::MakeOwned(RetEffect::CF));<br class="">+}<br class="">+<br class="">+const RetainSummary *<br class="">+RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) {<br class="">+  assert (ScratchArgs.isEmpty());<br class="">+  return getPersistentSummary(RetEffect::MakeNotOwned(RetEffect::CF),<br class="">+                              DoNothing, DoNothing);<br class="">+}<br class="">+<br class="">+<br class="">+<br class="">+<br class="">+//===----------------------------------------------------------------------===//<br class="">+// Summary creation for Selectors.<br class="">+//===----------------------------------------------------------------------===//<br class="">+<br class="">+Optional<RetEffect><br class="">+RetainSummaryManager::getRetEffectFromAnnotations(QualType RetTy,<br class="">+                                                  const Decl *D) {<br class="">+  if (cocoa::isCocoaObjectRef(RetTy)) {<br class="">+    if (D->hasAttr<NSReturnsRetainedAttr>())<br class="">+      return ObjCAllocRetE;<br class="">+<br class="">+    if (D->hasAttr<NSReturnsNotRetainedAttr>() ||<br class="">+        D->hasAttr<NSReturnsAutoreleasedAttr>())<br class="">+      return RetEffect::MakeNotOwned(RetEffect::ObjC);<br class="">+<br class="">+  } else if (!RetTy->isPointerType()) {<br class="">+    return None;<br class="">+  }<br class="">+<br class="">+  if (D->hasAttr<CFReturnsRetainedAttr>())<br class="">+    return RetEffect::MakeOwned(RetEffect::CF);<br class="">+  else if (hasRCAnnotation(D, "rc_ownership_returns_retained"))<br class="">+    return RetEffect::MakeOwned(RetEffect::Generalized);<br class="">+<br class="">+  if (D->hasAttr<CFReturnsNotRetainedAttr>())<br class="">+    return RetEffect::MakeNotOwned(RetEffect::CF);<br class="">+<br class="">+  return None;<br class="">+}<br class="">+<br class="">+void<br class="">+RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,<br class="">+                                                   const FunctionDecl *FD) {<br class="">+  if (!FD)<br class="">+    return;<br class="">+<br class="">+  assert(Summ && "Must have a summary to add annotations to.");<br class="">+  RetainSummaryTemplate Template(Summ, *this);<br class="">+<br class="">+  // Effects on the parameters.<br class="">+  unsigned parm_idx = 0;<br class="">+  for (FunctionDecl::param_const_iterator pi = FD->param_begin(),<br class="">+         pe = FD->param_end(); pi != pe; ++pi, ++parm_idx) {<br class="">+    const ParmVarDecl *pd = *pi;<br class="">+    if (pd->hasAttr<NSConsumedAttr>())<br class="">+      Template->addArg(AF, parm_idx, DecRefMsg);<br class="">+    else if (pd->hasAttr<CFConsumedAttr>() ||<br class="">+             hasRCAnnotation(pd, "rc_ownership_consumed"))<br class="">+      Template->addArg(AF, parm_idx, DecRef);<br class="">+    else if (pd->hasAttr<CFReturnsRetainedAttr>() ||<br class="">+             hasRCAnnotation(pd, "rc_ownership_returns_retained")) {<br class="">+      QualType PointeeTy = pd->getType()->getPointeeType();<br class="">+      if (!PointeeTy.isNull())<br class="">+        if (coreFoundation::isCFObjectRef(PointeeTy))<br class="">+          Template->addArg(AF, parm_idx, RetainedOutParameter);<br class="">+    } else if (pd->hasAttr<CFReturnsNotRetainedAttr>()) {<br class="">+      QualType PointeeTy = pd->getType()->getPointeeType();<br class="">+      if (!PointeeTy.isNull())<br class="">+        if (coreFoundation::isCFObjectRef(PointeeTy))<br class="">+          Template->addArg(AF, parm_idx, UnretainedOutParameter);<br class="">+    }<br class="">+  }<br class="">+<br class="">+  QualType RetTy = FD->getReturnType();<br class="">+  if (Optional<RetEffect> RetE = getRetEffectFromAnnotations(RetTy, FD))<br class="">+    Template->setRetEffect(*RetE);<br class="">+}<br class="">+<br class="">+void<br class="">+RetainSummaryManager::updateSummaryFromAnnotations(const RetainSummary *&Summ,<br class="">+                                                   const ObjCMethodDecl *MD) {<br class="">+  if (!MD)<br class="">+    return;<br class="">+<br class="">+  assert(Summ && "Must have a valid summary to add annotations to");<br class="">+  RetainSummaryTemplate Template(Summ, *this);<br class="">+<br class="">+  // Effects on the receiver.<br class="">+  if (MD->hasAttr<NSConsumesSelfAttr>())<br class="">+    Template->setReceiverEffect(DecRefMsg);<br class="">+<br class="">+  // Effects on the parameters.<br class="">+  unsigned parm_idx = 0;<br class="">+  for (ObjCMethodDecl::param_const_iterator<br class="">+         pi=MD->param_begin(), pe=MD->param_end();<br class="">+       pi != pe; ++pi, ++parm_idx) {<br class="">+    const ParmVarDecl *pd = *pi;<br class="">+    if (pd->hasAttr<NSConsumedAttr>())<br class="">+      Template->addArg(AF, parm_idx, DecRefMsg);<br class="">+    else if (pd->hasAttr<CFConsumedAttr>()) {<br class="">+      Template->addArg(AF, parm_idx, DecRef);<br class="">+    } else if (pd->hasAttr<CFReturnsRetainedAttr>()) {<br class="">+      QualType PointeeTy = pd->getType()->getPointeeType();<br class="">+      if (!PointeeTy.isNull())<br class="">+        if (coreFoundation::isCFObjectRef(PointeeTy))<br class="">+          Template->addArg(AF, parm_idx, RetainedOutParameter);<br class="">+    } else if (pd->hasAttr<CFReturnsNotRetainedAttr>()) {<br class="">+      QualType PointeeTy = pd->getType()->getPointeeType();<br class="">+      if (!PointeeTy.isNull())<br class="">+        if (coreFoundation::isCFObjectRef(PointeeTy))<br class="">+          Template->addArg(AF, parm_idx, UnretainedOutParameter);<br class="">+    }<br class="">+  }<br class="">+<br class="">+  QualType RetTy = MD->getReturnType();<br class="">+  if (Optional<RetEffect> RetE = getRetEffectFromAnnotations(RetTy, MD))<br class="">+    Template->setRetEffect(*RetE);<br class="">+}<br class="">+<br class="">+const RetainSummary *<br class="">+RetainSummaryManager::getStandardMethodSummary(const ObjCMethodDecl *MD,<br class="">+                                               Selector S, QualType RetTy) {<br class="">+  // Any special effects?<br class="">+  ArgEffect ReceiverEff = DoNothing;<br class="">+  RetEffect ResultEff = RetEffect::MakeNoRet();<br class="">+<br class="">+  // Check the method family, and apply any default annotations.<br class="">+  switch (MD ? MD->getMethodFamily() : S.getMethodFamily()) {<br class="">+    case OMF_None:<br class="">+    case OMF_initialize:<br class="">+    case OMF_performSelector:<br class="">+      // Assume all Objective-C methods follow Cocoa Memory Management rules.<br class="">+      // FIXME: Does the non-threaded performSelector family really belong here?<br class="">+      // The selector could be, say, @selector(copy).<br class="">+      if (cocoa::isCocoaObjectRef(RetTy))<br class="">+        ResultEff = RetEffect::MakeNotOwned(RetEffect::ObjC);<br class="">+      else if (coreFoundation::isCFObjectRef(RetTy)) {<br class="">+        // ObjCMethodDecl currently doesn't consider CF objects as valid return<br class="">+        // values for alloc, new, copy, or mutableCopy, so we have to<br class="">+        // double-check with the selector. This is ugly, but there aren't that<br class="">+        // many Objective-C methods that return CF objects, right?<br class="">+        if (MD) {<br class="">+          switch (S.getMethodFamily()) {<br class="">+          case OMF_alloc:<br class="">+          case OMF_new:<br class="">+          case OMF_copy:<br class="">+          case OMF_mutableCopy:<br class="">+            ResultEff = RetEffect::MakeOwned(RetEffect::CF);<br class="">+            break;<br class="">+          default:<br class="">+            ResultEff = RetEffect::MakeNotOwned(RetEffect::CF);<br class="">+            break;<br class="">+          }<br class="">+        } else {<br class="">+          ResultEff = RetEffect::MakeNotOwned(RetEffect::CF);<br class="">+        }<br class="">+      }<br class="">+      break;<br class="">+    case OMF_init:<br class="">+      ResultEff = ObjCInitRetE;<br class="">+      ReceiverEff = DecRefMsg;<br class="">+      break;<br class="">+    case OMF_alloc:<br class="">+    case OMF_new:<br class="">+    case OMF_copy:<br class="">+    case OMF_mutableCopy:<br class="">+      if (cocoa::isCocoaObjectRef(RetTy))<br class="">+        ResultEff = ObjCAllocRetE;<br class="">+      else if (coreFoundation::isCFObjectRef(RetTy))<br class="">+        ResultEff = RetEffect::MakeOwned(RetEffect::CF);<br class="">+      break;<br class="">+    case OMF_autorelease:<br class="">+      ReceiverEff = Autorelease;<br class="">+      break;<br class="">+    case OMF_retain:<br class="">+      ReceiverEff = IncRefMsg;<br class="">+      break;<br class="">+    case OMF_release:<br class="">+      ReceiverEff = DecRefMsg;<br class="">+      break;<br class="">+    case OMF_dealloc:<br class="">+      ReceiverEff = Dealloc;<br class="">+      break;<br class="">+    case OMF_self:<br class="">+      // -self is handled specially by the ExprEngine to propagate the receiver.<br class="">+      break;<br class="">+    case OMF_retainCount:<br class="">+    case OMF_finalize:<br class="">+      // These methods don't return objects.<br class="">+      break;<br class="">+  }<br class="">+<br class="">+  // If one of the arguments in the selector has the keyword 'delegate' we<br class="">+  // should stop tracking the reference count for the receiver.  This is<br class="">+  // because the reference count is quite possibly handled by a delegate<br class="">+  // method.<br class="">+  if (S.isKeywordSelector()) {<br class="">+    for (unsigned i = 0, e = S.getNumArgs(); i != e; ++i) {<br class="">+      StringRef Slot = S.getNameForSlot(i);<br class="">+      if (Slot.substr(Slot.size() - 8).equals_lower("delegate")) {<br class="">+        if (ResultEff == ObjCInitRetE)<br class="">+          ResultEff = RetEffect::MakeNoRetHard();<br class="">+        else<br class="">+          ReceiverEff = StopTrackingHard;<br class="">+      }<br class="">+    }<br class="">+  }<br class="">+<br class="">+  if (ScratchArgs.isEmpty() && ReceiverEff == DoNothing &&<br class="">+      ResultEff.getKind() == RetEffect::NoRet)<br class="">+    return getDefaultSummary();<br class="">+<br class="">+  return getPersistentSummary(ResultEff, ReceiverEff, MayEscape);<br class="">+}<br class="">+<br class="">+const RetainSummary *RetainSummaryManager::getInstanceMethodSummary(<br class="">+    const ObjCMethodCall &Msg, QualType ReceiverType) {<br class="">+  const ObjCInterfaceDecl *ReceiverClass = nullptr;<br class="">+<br class="">+  // We do better tracking of the type of the object than the core ExprEngine.<br class="">+  // See if we have its type in our private state.<br class="">+  if (!ReceiverType.isNull())<br class="">+    if (const auto *PT = ReceiverType->getAs<ObjCObjectPointerType>())<br class="">+      ReceiverClass = PT->getInterfaceDecl();<br class="">+<br class="">+  // If we don't know what kind of object this is, fall back to its static type.<br class="">+  if (!ReceiverClass)<br class="">+    ReceiverClass = Msg.getReceiverInterface();<br class="">+<br class="">+  // FIXME: The receiver could be a reference to a class, meaning that<br class="">+  //  we should use the class method.<br class="">+  // id x = [NSObject class];<br class="">+  // [x performSelector:... withObject:... afterDelay:...];<br class="">+  Selector S = Msg.getSelector();<br class="">+  const ObjCMethodDecl *Method = Msg.getDecl();<br class="">+  if (!Method && ReceiverClass)<br class="">+    Method = ReceiverClass->getInstanceMethod(S);<br class="">+<br class="">+  return getMethodSummary(S, ReceiverClass, Method, Msg.getResultType(),<br class="">+                          ObjCMethodSummaries);<br class="">+}<br class="">+<br class="">+const RetainSummary *<br class="">+RetainSummaryManager::getMethodSummary(Se<br class=""></blockquote><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none; float: none; display: inline !important;" class="">--<span class="Apple-converted-space"> </span></span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><span style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none; float: none; display: inline !important;" class="">Bruno Cardoso Lopes</span><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""><a href="http://www.brunocardoso.cc/" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" class="">http://www.brunocardoso.cc</a><br style="caret-color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); text-decoration: none;" class=""></div></blockquote></div><br class=""></body></html>