13cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose//==- ObjCMissingSuperCallChecker.cpp - Check missing super-calls in ObjC --==// 23cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// 33cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// The LLVM Compiler Infrastructure 43cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// 53cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// This file is distributed under the University of Illinois Open Source 63cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// License. See LICENSE.TXT for details. 73cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// 83cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose//===----------------------------------------------------------------------===// 93cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// 103cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// This file defines a ObjCMissingSuperCallChecker, a checker that 113cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// analyzes a UIViewController implementation to determine if it 123cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// correctly calls super in the methods where this is mandatory. 133cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// 143cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose//===----------------------------------------------------------------------===// 153cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 163cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose#include "ClangSACheckers.h" 173cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose#include "clang/AST/DeclObjC.h" 1855fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/Expr.h" 1955fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/AST/ExprObjC.h" 203cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose#include "clang/AST/RecursiveASTVisitor.h" 2155fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h" 2255fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/BugReporter/PathDiagnostic.h" 2355fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/Checker.h" 2455fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" 253cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose#include "llvm/ADT/SmallSet.h" 2655fc873017f10f6f566b182b70f6fc22aefa3464Chandler Carruth#include "llvm/ADT/SmallString.h" 273cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose#include "llvm/Support/raw_ostream.h" 283cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 293cf9a72743d147f3a6152ba3374f081bac749c28Jordan Roseusing namespace clang; 303cf9a72743d147f3a6152ba3374f081bac749c28Jordan Roseusing namespace ento; 313cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 32e14999e768fe55f620719fc4fbc361759e990e80Jordan Rosenamespace { 33e14999e768fe55f620719fc4fbc361759e990e80Jordan Rosestruct SelectorDescriptor { 34e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose const char *SelectorName; 35e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose unsigned ArgumentCount; 36e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose}; 373cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose} 383cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 393cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose//===----------------------------------------------------------------------===// 403cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// FindSuperCallVisitor - Identify specific calls to the superclass. 413cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose//===----------------------------------------------------------------------===// 423cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 433cf9a72743d147f3a6152ba3374f081bac749c28Jordan Roseclass FindSuperCallVisitor : public RecursiveASTVisitor<FindSuperCallVisitor> { 443cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rosepublic: 453cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose explicit FindSuperCallVisitor(Selector S) : DoesCallSuper(false), Sel(S) {} 463cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 473cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose bool VisitObjCMessageExpr(ObjCMessageExpr *E) { 483cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose if (E->getSelector() == Sel) 493cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose if (E->getReceiverKind() == ObjCMessageExpr::SuperInstance) 503cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose DoesCallSuper = true; 513cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 523cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose // Recurse if we didn't find the super call yet. 533cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose return !DoesCallSuper; 543cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose } 553cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 563cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose bool DoesCallSuper; 573cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 583cf9a72743d147f3a6152ba3374f081bac749c28Jordan Roseprivate: 593cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose Selector Sel; 603cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose}; 613cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 623cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose//===----------------------------------------------------------------------===// 633cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// ObjCSuperCallChecker 643cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose//===----------------------------------------------------------------------===// 653cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 663cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rosenamespace { 673cf9a72743d147f3a6152ba3374f081bac749c28Jordan Roseclass ObjCSuperCallChecker : public Checker< 683cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose check::ASTDecl<ObjCImplementationDecl> > { 693cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rosepublic: 70e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose ObjCSuperCallChecker() : IsInitialized(false) {} 71e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 723cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager &Mgr, 733cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose BugReporter &BR) const; 74e14999e768fe55f620719fc4fbc361759e990e80Jordan Roseprivate: 75e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose bool isCheckableClass(const ObjCImplementationDecl *D, 76e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose StringRef &SuperclassName) const; 77e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose void initializeSelectors(ASTContext &Ctx) const; 78e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose void fillSelectors(ASTContext &Ctx, ArrayRef<SelectorDescriptor> Sel, 79e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose StringRef ClassName) const; 80e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose mutable llvm::StringMap<llvm::SmallSet<Selector, 16> > SelectorsForClass; 81e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose mutable bool IsInitialized; 823cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose}; 83e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 84e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose} 85e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 86e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose/// \brief Determine whether the given class has a superclass that we want 87e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose/// to check. The name of the found superclass is stored in SuperclassName. 88e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose/// 8945397f92bb3009dd5a1b399ef0885ccddc34838eJordan Rose/// \param D The declaration to check for superclasses. 90e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose/// \param[out] SuperclassName On return, the found superclass name. 91e14999e768fe55f620719fc4fbc361759e990e80Jordan Rosebool ObjCSuperCallChecker::isCheckableClass(const ObjCImplementationDecl *D, 92e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose StringRef &SuperclassName) const { 93e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose const ObjCInterfaceDecl *ID = D->getClassInterface(); 94e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose for ( ; ID ; ID = ID->getSuperClass()) 95e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { 96e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose SuperclassName = ID->getIdentifier()->getName(); 97e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose if (SelectorsForClass.count(SuperclassName)) 98e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose return true; 99e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose } 100e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose return false; 101e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose} 102e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 103e14999e768fe55f620719fc4fbc361759e990e80Jordan Rosevoid ObjCSuperCallChecker::fillSelectors(ASTContext &Ctx, 104e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose ArrayRef<SelectorDescriptor> Sel, 105e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose StringRef ClassName) const { 106e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose llvm::SmallSet<Selector, 16> &ClassSelectors = SelectorsForClass[ClassName]; 107e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose // Fill the Selectors SmallSet with all selectors we want to check. 108e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose for (ArrayRef<SelectorDescriptor>::iterator I = Sel.begin(), E = Sel.end(); 109e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose I != E; ++I) { 110e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose SelectorDescriptor Descriptor = *I; 111e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose assert(Descriptor.ArgumentCount <= 1); // No multi-argument selectors yet. 112e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 113e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose // Get the selector. 114e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose IdentifierInfo *II = &Ctx.Idents.get(Descriptor.SelectorName); 115e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 116e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose Selector Sel = Ctx.Selectors.getSelector(Descriptor.ArgumentCount, &II); 117e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose ClassSelectors.insert(Sel); 118e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose } 119e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose} 120e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 121e14999e768fe55f620719fc4fbc361759e990e80Jordan Rosevoid ObjCSuperCallChecker::initializeSelectors(ASTContext &Ctx) const { 122e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 123e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { // Initialize selectors for: UIViewController 124e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose const SelectorDescriptor Selectors[] = { 125e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "addChildViewController", 1 }, 126e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "viewDidAppear", 1 }, 127e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "viewDidDisappear", 1 }, 128e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "viewWillAppear", 1 }, 129e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "viewWillDisappear", 1 }, 130e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "removeFromParentViewController", 0 }, 131e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "didReceiveMemoryWarning", 0 }, 132e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "viewDidUnload", 0 }, 133e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "viewDidLoad", 0 }, 134e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "viewWillUnload", 0 }, 135e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "updateViewConstraints", 0 }, 136e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "encodeRestorableStateWithCoder", 1 }, 137e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "restoreStateWithCoder", 1 }}; 138e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 139e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose fillSelectors(Ctx, Selectors, "UIViewController"); 140e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose } 141e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 142e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { // Initialize selectors for: UIResponder 143e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose const SelectorDescriptor Selectors[] = { 144e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "resignFirstResponder", 0 }}; 145e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 146e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose fillSelectors(Ctx, Selectors, "UIResponder"); 147e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose } 148e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 149e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { // Initialize selectors for: NSResponder 150e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose const SelectorDescriptor Selectors[] = { 151e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "encodeRestorableStateWithCoder", 1 }, 152e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "restoreStateWithCoder", 1 }}; 153e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 154e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose fillSelectors(Ctx, Selectors, "NSResponder"); 155e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose } 156e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 157e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { // Initialize selectors for: NSDocument 158e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose const SelectorDescriptor Selectors[] = { 159e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "encodeRestorableStateWithCoder", 1 }, 160e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose { "restoreStateWithCoder", 1 }}; 161e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 162e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose fillSelectors(Ctx, Selectors, "NSDocument"); 163e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose } 164e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose 165e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose IsInitialized = true; 1663cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose} 1673cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 1683cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rosevoid ObjCSuperCallChecker::checkASTDecl(const ObjCImplementationDecl *D, 1693cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose AnalysisManager &Mgr, 1703cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose BugReporter &BR) const { 1713cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose ASTContext &Ctx = BR.getContext(); 1723cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 173e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose // We need to initialize the selector table once. 174e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose if (!IsInitialized) 175e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose initializeSelectors(Ctx); 1763cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 177e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose // Find out whether this class has a superclass that we are supposed to check. 178e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose StringRef SuperclassName; 179e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose if (!isCheckableClass(D, SuperclassName)) 180e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose return; 1813cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 1823cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 1833cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose // Iterate over all instance methods. 184651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines for (auto *MD : D->instance_methods()) { 185651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Selector S = MD->getSelector(); 1863cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose // Find out whether this is a selector that we want to check. 187e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose if (!SelectorsForClass[SuperclassName].count(S)) 1883cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose continue; 1893cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 1903cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose // Check if the method calls its superclass implementation. 1913cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose if (MD->getBody()) 1923cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose { 1933cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose FindSuperCallVisitor Visitor(S); 1943cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose Visitor.TraverseDecl(MD); 1953cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 1963cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose // It doesn't call super, emit a diagnostic. 1973cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose if (!Visitor.DoesCallSuper) { 1983cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose PathDiagnosticLocation DLoc = 1993cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose PathDiagnosticLocation::createEnd(MD->getBody(), 2003cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose BR.getSourceManager(), 2013cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose Mgr.getAnalysisDeclContext(D)); 2023cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2033cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose const char *Name = "Missing call to superclass"; 204e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose SmallString<320> Buf; 2053cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose llvm::raw_svector_ostream os(Buf); 2063cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2073cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose os << "The '" << S.getAsString() 208e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose << "' instance method in " << SuperclassName.str() << " subclass '" 209e14999e768fe55f620719fc4fbc361759e990e80Jordan Rose << *D << "' is missing a [super " << S.getAsString() << "] call"; 2103cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 211651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BR.EmitBasicReport(MD, this, Name, categories::CoreFoundationObjectiveC, 2123cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose os.str(), DLoc); 2133cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose } 2143cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose } 2153cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose } 2163cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose} 2173cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2183cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2193cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose//===----------------------------------------------------------------------===// 2203cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose// Check registration. 2213cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose//===----------------------------------------------------------------------===// 2223cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2233cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rosevoid ento::registerObjCSuperCallChecker(CheckerManager &Mgr) { 2243cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose Mgr.registerChecker<ObjCSuperCallChecker>(); 2253cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose} 2263cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2273cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2283cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose/* 2293cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose ToDo list for expanding this check in the future, the list is not exhaustive. 2303cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose There are also cases where calling super is suggested but not "mandatory". 2313cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose In addition to be able to check the classes and methods below, architectural 2323cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose improvements like being able to allow for the super-call to be done in a called 2333cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose method would be good too. 2343cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2353cf9a72743d147f3a6152ba3374f081bac749c28Jordan RoseUIDocument subclasses 2363cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- finishedHandlingError:recovered: (is multi-arg) 2373cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- finishedHandlingError:recovered: (is multi-arg) 2383cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2393cf9a72743d147f3a6152ba3374f081bac749c28Jordan RoseUIViewController subclasses 2403cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- loadView (should *never* call super) 2413cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- transitionFromViewController:toViewController: 2423cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose duration:options:animations:completion: (is multi-arg) 2433cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2443cf9a72743d147f3a6152ba3374f081bac749c28Jordan RoseUICollectionViewController subclasses 2453cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- loadView (take care because UIViewController subclasses should NOT call super 2463cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose in loadView, but UICollectionViewController subclasses should) 2473cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2483cf9a72743d147f3a6152ba3374f081bac749c28Jordan RoseNSObject subclasses 2493cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- doesNotRecognizeSelector (it only has to call super if it doesn't throw) 2503cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2513cf9a72743d147f3a6152ba3374f081bac749c28Jordan RoseUIPopoverBackgroundView subclasses (some of those are class methods) 2523cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- arrowDirection (should *never* call super) 2533cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- arrowOffset (should *never* call super) 2543cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- arrowBase (should *never* call super) 2553cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- arrowHeight (should *never* call super) 2563cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- contentViewInsets (should *never* call super) 2573cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose 2583cf9a72743d147f3a6152ba3374f081bac749c28Jordan RoseUITextSelectionRect subclasses (some of those are properties) 2593cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- rect (should *never* call super) 2603cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- range (should *never* call super) 2613cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- writingDirection (should *never* call super) 2623cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- isVertical (should *never* call super) 2633cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- containsStart (should *never* call super) 2643cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose- containsEnd (should *never* call super) 2653cf9a72743d147f3a6152ba3374f081bac749c28Jordan Rose*/ 266