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