//=- LocalizationChecker.cpp -------------------------------------*- C++ -*-==//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//  This file defines a set of checks for localizability including:
//  1) A checker that warns about uses of non-localized NSStrings passed to
//     UI methods expecting localized strings
//  2) A syntactic checker that warns against the bad practice of
//     not including a comment in NSLocalizedString macros.
//
//===----------------------------------------------------------------------===//

#include "clang/StaticAnalyzer/Checkers/BuiltinCheckerRegistration.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/Lex/Lexer.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugReporter.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "llvm/Support/Unicode.h"

using namespace clang;
using namespace ento;

namespace {
struct LocalizedState {
private:
  enum Kind { NonLocalized, Localized } K;
  LocalizedState(Kind InK) : K(InK) {}

public:
  bool isLocalized() const { return K == Localized; }
  bool isNonLocalized() const { return K == NonLocalized; }

  static LocalizedState getLocalized() { return LocalizedState(Localized); }
  static LocalizedState getNonLocalized() {
    return LocalizedState(NonLocalized);
  }

  // Overload the == operator
  bool operator==(const LocalizedState &X) const { return K == X.K; }

  // LLVMs equivalent of a hash function
  void Profile(llvm::FoldingSetNodeID &ID) const { ID.AddInteger(K); }
};

class NonLocalizedStringChecker
    : public Checker<check::PreCall, check::PostCall, check::PreObjCMessage,
                     check::PostObjCMessage,
                     check::PostStmt<ObjCStringLiteral>> {

  mutable std::unique_ptr<BugType> BT;

  // Methods that require a localized string
  mutable llvm::DenseMap<const IdentifierInfo *,
                         llvm::DenseMap<Selector, uint8_t>> UIMethods;
  // Methods that return a localized string
  mutable llvm::SmallSet<std::pair<const IdentifierInfo *, Selector>, 12> LSM;
  // C Functions that return a localized string
  mutable llvm::SmallSet<const IdentifierInfo *, 5> LSF;

  void initUIMethods(ASTContext &Ctx) const;
  void initLocStringsMethods(ASTContext &Ctx) const;

  bool hasNonLocalizedState(SVal S, CheckerContext &C) const;
  bool hasLocalizedState(SVal S, CheckerContext &C) const;
  void setNonLocalizedState(SVal S, CheckerContext &C) const;
  void setLocalizedState(SVal S, CheckerContext &C) const;

  bool isAnnotatedAsReturningLocalized(const Decl *D) const;
  bool isAnnotatedAsTakingLocalized(const Decl *D) const;
  void reportLocalizationError(SVal S, const CallEvent &M, CheckerContext &C,
                               int argumentNumber = 0) const;

  int getLocalizedArgumentForSelector(const IdentifierInfo *Receiver,
                                      Selector S) const;

public:
  NonLocalizedStringChecker();

  // When this parameter is set to true, the checker assumes all
  // methods that return NSStrings are unlocalized. Thus, more false
  // positives will be reported.
  DefaultBool IsAggressive;

  void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
  void checkPostObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
  void checkPostStmt(const ObjCStringLiteral *SL, CheckerContext &C) const;
  void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
  void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
};

} // end anonymous namespace

REGISTER_MAP_WITH_PROGRAMSTATE(LocalizedMemMap, const MemRegion *,
                               LocalizedState)

NonLocalizedStringChecker::NonLocalizedStringChecker() {
  BT.reset(new BugType(this, "Unlocalizable string",
                       "Localizability Issue (Apple)"));
}

namespace {
class NonLocalizedStringBRVisitor final : public BugReporterVisitor {

  const MemRegion *NonLocalizedString;
  bool Satisfied;

public:
  NonLocalizedStringBRVisitor(const MemRegion *NonLocalizedString)
      : NonLocalizedString(NonLocalizedString), Satisfied(false) {
        assert(NonLocalizedString);
  }

  std::shared_ptr<PathDiagnosticPiece> VisitNode(const ExplodedNode *Succ,
                                                 BugReporterContext &BRC,
                                                 BugReport &BR) override;

  void Profile(llvm::FoldingSetNodeID &ID) const override {
    ID.Add(NonLocalizedString);
  }
};
} // End anonymous namespace.

#define NEW_RECEIVER(receiver)                                                 \
  llvm::DenseMap<Selector, uint8_t> &receiver##M =                             \
      UIMethods.insert({&Ctx.Idents.get(#receiver),                            \
                        llvm::DenseMap<Selector, uint8_t>()})                  \
          .first->second;
#define ADD_NULLARY_METHOD(receiver, method, argument)                         \
  receiver##M.insert(                                                          \
      {Ctx.Selectors.getNullarySelector(&Ctx.Idents.get(#method)), argument});
#define ADD_UNARY_METHOD(receiver, method, argument)                           \
  receiver##M.insert(                                                          \
      {Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(#method)), argument});
#define ADD_METHOD(receiver, method_list, count, argument)                     \
  receiver##M.insert({Ctx.Selectors.getSelector(count, method_list), argument});

/// Initializes a list of methods that require a localized string
/// Format: {"ClassName", {{"selectorName:", LocStringArg#}, ...}, ...}
void NonLocalizedStringChecker::initUIMethods(ASTContext &Ctx) const {
  if (!UIMethods.empty())
    return;

  // UI Methods
  NEW_RECEIVER(UISearchDisplayController)
  ADD_UNARY_METHOD(UISearchDisplayController, setSearchResultsTitle, 0)

  NEW_RECEIVER(UITabBarItem)
  IdentifierInfo *initWithTitleUITabBarItemTag[] = {
      &Ctx.Idents.get("initWithTitle"), &Ctx.Idents.get("image"),
      &Ctx.Idents.get("tag")};
  ADD_METHOD(UITabBarItem, initWithTitleUITabBarItemTag, 3, 0)
  IdentifierInfo *initWithTitleUITabBarItemImage[] = {
      &Ctx.Idents.get("initWithTitle"), &Ctx.Idents.get("image"),
      &Ctx.Idents.get("selectedImage")};
  ADD_METHOD(UITabBarItem, initWithTitleUITabBarItemImage, 3, 0)

  NEW_RECEIVER(NSDockTile)
  ADD_UNARY_METHOD(NSDockTile, setBadgeLabel, 0)

  NEW_RECEIVER(NSStatusItem)
  ADD_UNARY_METHOD(NSStatusItem, setTitle, 0)
  ADD_UNARY_METHOD(NSStatusItem, setToolTip, 0)

  NEW_RECEIVER(UITableViewRowAction)
  IdentifierInfo *rowActionWithStyleUITableViewRowAction[] = {
      &Ctx.Idents.get("rowActionWithStyle"), &Ctx.Idents.get("title"),
      &Ctx.Idents.get("handler")};
  ADD_METHOD(UITableViewRowAction, rowActionWithStyleUITableViewRowAction, 3, 1)
  ADD_UNARY_METHOD(UITableViewRowAction, setTitle, 0)

  NEW_RECEIVER(NSBox)
  ADD_UNARY_METHOD(NSBox, setTitle, 0)

  NEW_RECEIVER(NSButton)
  ADD_UNARY_METHOD(NSButton, setTitle, 0)
  ADD_UNARY_METHOD(NSButton, setAlternateTitle, 0)
  IdentifierInfo *radioButtonWithTitleNSButton[] = {
      &Ctx.Idents.get("radioButtonWithTitle"), &Ctx.Idents.get("target"),
      &Ctx.Idents.get("action")};
  ADD_METHOD(NSButton, radioButtonWithTitleNSButton, 3, 0)
  IdentifierInfo *buttonWithTitleNSButtonImage[] = {
      &Ctx.Idents.get("buttonWithTitle"), &Ctx.Idents.get("image"),
      &Ctx.Idents.get("target"), &Ctx.Idents.get("action")};
  ADD_METHOD(NSButton, buttonWithTitleNSButtonImage, 4, 0)
  IdentifierInfo *checkboxWithTitleNSButton[] = {
      &Ctx.Idents.get("checkboxWithTitle"), &Ctx.Idents.get("target"),
      &Ctx.Idents.get("action")};
  ADD_METHOD(NSButton, checkboxWithTitleNSButton, 3, 0)
  IdentifierInfo *buttonWithTitleNSButtonTarget[] = {
      &Ctx.Idents.get("buttonWithTitle"), &Ctx.Idents.get("target"),
      &Ctx.Idents.get("action")};
  ADD_METHOD(NSButton, buttonWithTitleNSButtonTarget, 3, 0)

  NEW_RECEIVER(NSSavePanel)
  ADD_UNARY_METHOD(NSSavePanel, setPrompt, 0)
  ADD_UNARY_METHOD(NSSavePanel, setTitle, 0)
  ADD_UNARY_METHOD(NSSavePanel, setNameFieldLabel, 0)
  ADD_UNARY_METHOD(NSSavePanel, setNameFieldStringValue, 0)
  ADD_UNARY_METHOD(NSSavePanel, setMessage, 0)

  NEW_RECEIVER(UIPrintInfo)
  ADD_UNARY_METHOD(UIPrintInfo, setJobName, 0)

  NEW_RECEIVER(NSTabViewItem)
  ADD_UNARY_METHOD(NSTabViewItem, setLabel, 0)
  ADD_UNARY_METHOD(NSTabViewItem, setToolTip, 0)

  NEW_RECEIVER(NSBrowser)
  IdentifierInfo *setTitleNSBrowser[] = {&Ctx.Idents.get("setTitle"),
                                         &Ctx.Idents.get("ofColumn")};
  ADD_METHOD(NSBrowser, setTitleNSBrowser, 2, 0)

  NEW_RECEIVER(UIAccessibilityElement)
  ADD_UNARY_METHOD(UIAccessibilityElement, setAccessibilityLabel, 0)
  ADD_UNARY_METHOD(UIAccessibilityElement, setAccessibilityHint, 0)
  ADD_UNARY_METHOD(UIAccessibilityElement, setAccessibilityValue, 0)

  NEW_RECEIVER(UIAlertAction)
  IdentifierInfo *actionWithTitleUIAlertAction[] = {
      &Ctx.Idents.get("actionWithTitle"), &Ctx.Idents.get("style"),
      &Ctx.Idents.get("handler")};
  ADD_METHOD(UIAlertAction, actionWithTitleUIAlertAction, 3, 0)

  NEW_RECEIVER(NSPopUpButton)
  ADD_UNARY_METHOD(NSPopUpButton, addItemWithTitle, 0)
  IdentifierInfo *insertItemWithTitleNSPopUpButton[] = {
      &Ctx.Idents.get("insertItemWithTitle"), &Ctx.Idents.get("atIndex")};
  ADD_METHOD(NSPopUpButton, insertItemWithTitleNSPopUpButton, 2, 0)
  ADD_UNARY_METHOD(NSPopUpButton, removeItemWithTitle, 0)
  ADD_UNARY_METHOD(NSPopUpButton, selectItemWithTitle, 0)
  ADD_UNARY_METHOD(NSPopUpButton, setTitle, 0)

  NEW_RECEIVER(NSTableViewRowAction)
  IdentifierInfo *rowActionWithStyleNSTableViewRowAction[] = {
      &Ctx.Idents.get("rowActionWithStyle"), &Ctx.Idents.get("title"),
      &Ctx.Idents.get("handler")};
  ADD_METHOD(NSTableViewRowAction, rowActionWithStyleNSTableViewRowAction, 3, 1)
  ADD_UNARY_METHOD(NSTableViewRowAction, setTitle, 0)

  NEW_RECEIVER(NSImage)
  ADD_UNARY_METHOD(NSImage, setAccessibilityDescription, 0)

  NEW_RECEIVER(NSUserActivity)
  ADD_UNARY_METHOD(NSUserActivity, setTitle, 0)

  NEW_RECEIVER(NSPathControlItem)
  ADD_UNARY_METHOD(NSPathControlItem, setTitle, 0)

  NEW_RECEIVER(NSCell)
  ADD_UNARY_METHOD(NSCell, initTextCell, 0)
  ADD_UNARY_METHOD(NSCell, setTitle, 0)
  ADD_UNARY_METHOD(NSCell, setStringValue, 0)

  NEW_RECEIVER(NSPathControl)
  ADD_UNARY_METHOD(NSPathControl, setPlaceholderString, 0)

  NEW_RECEIVER(UIAccessibility)
  ADD_UNARY_METHOD(UIAccessibility, setAccessibilityLabel, 0)
  ADD_UNARY_METHOD(UIAccessibility, setAccessibilityHint, 0)
  ADD_UNARY_METHOD(UIAccessibility, setAccessibilityValue, 0)

  NEW_RECEIVER(NSTableColumn)
  ADD_UNARY_METHOD(NSTableColumn, setTitle, 0)
  ADD_UNARY_METHOD(NSTableColumn, setHeaderToolTip, 0)

  NEW_RECEIVER(NSSegmentedControl)
  IdentifierInfo *setLabelNSSegmentedControl[] = {
      &Ctx.Idents.get("setLabel"), &Ctx.Idents.get("forSegment")};
  ADD_METHOD(NSSegmentedControl, setLabelNSSegmentedControl, 2, 0)
  IdentifierInfo *setToolTipNSSegmentedControl[] = {
      &Ctx.Idents.get("setToolTip"), &Ctx.Idents.get("forSegment")};
  ADD_METHOD(NSSegmentedControl, setToolTipNSSegmentedControl, 2, 0)

  NEW_RECEIVER(NSButtonCell)
  ADD_UNARY_METHOD(NSButtonCell, setTitle, 0)
  ADD_UNARY_METHOD(NSButtonCell, setAlternateTitle, 0)

  NEW_RECEIVER(NSDatePickerCell)
  ADD_UNARY_METHOD(NSDatePickerCell, initTextCell, 0)

  NEW_RECEIVER(NSSliderCell)
  ADD_UNARY_METHOD(NSSliderCell, setTitle, 0)

  NEW_RECEIVER(NSControl)
  ADD_UNARY_METHOD(NSControl, setStringValue, 0)

  NEW_RECEIVER(NSAccessibility)
  ADD_UNARY_METHOD(NSAccessibility, setAccessibilityValueDescription, 0)
  ADD_UNARY_METHOD(NSAccessibility, setAccessibilityLabel, 0)
  ADD_UNARY_METHOD(NSAccessibility, setAccessibilityTitle, 0)
  ADD_UNARY_METHOD(NSAccessibility, setAccessibilityPlaceholderValue, 0)
  ADD_UNARY_METHOD(NSAccessibility, setAccessibilityHelp, 0)

  NEW_RECEIVER(NSMatrix)
  IdentifierInfo *setToolTipNSMatrix[] = {&Ctx.Idents.get("setToolTip"),
                                          &Ctx.Idents.get("forCell")};
  ADD_METHOD(NSMatrix, setToolTipNSMatrix, 2, 0)

  NEW_RECEIVER(NSPrintPanel)
  ADD_UNARY_METHOD(NSPrintPanel, setDefaultButtonTitle, 0)

  NEW_RECEIVER(UILocalNotification)
  ADD_UNARY_METHOD(UILocalNotification, setAlertBody, 0)
  ADD_UNARY_METHOD(UILocalNotification, setAlertAction, 0)
  ADD_UNARY_METHOD(UILocalNotification, setAlertTitle, 0)

  NEW_RECEIVER(NSSlider)
  ADD_UNARY_METHOD(NSSlider, setTitle, 0)

  NEW_RECEIVER(UIMenuItem)
  IdentifierInfo *initWithTitleUIMenuItem[] = {&Ctx.Idents.get("initWithTitle"),
                                               &Ctx.Idents.get("action")};
  ADD_METHOD(UIMenuItem, initWithTitleUIMenuItem, 2, 0)
  ADD_UNARY_METHOD(UIMenuItem, setTitle, 0)

  NEW_RECEIVER(UIAlertController)
  IdentifierInfo *alertControllerWithTitleUIAlertController[] = {
      &Ctx.Idents.get("alertControllerWithTitle"), &Ctx.Idents.get("message"),
      &Ctx.Idents.get("preferredStyle")};
  ADD_METHOD(UIAlertController, alertControllerWithTitleUIAlertController, 3, 1)
  ADD_UNARY_METHOD(UIAlertController, setTitle, 0)
  ADD_UNARY_METHOD(UIAlertController, setMessage, 0)

  NEW_RECEIVER(UIApplicationShortcutItem)
  IdentifierInfo *initWithTypeUIApplicationShortcutItemIcon[] = {
      &Ctx.Idents.get("initWithType"), &Ctx.Idents.get("localizedTitle"),
      &Ctx.Idents.get("localizedSubtitle"), &Ctx.Idents.get("icon"),
      &Ctx.Idents.get("userInfo")};
  ADD_METHOD(UIApplicationShortcutItem,
             initWithTypeUIApplicationShortcutItemIcon, 5, 1)
  IdentifierInfo *initWithTypeUIApplicationShortcutItem[] = {
      &Ctx.Idents.get("initWithType"), &Ctx.Idents.get("localizedTitle")};
  ADD_METHOD(UIApplicationShortcutItem, initWithTypeUIApplicationShortcutItem,
             2, 1)

  NEW_RECEIVER(UIActionSheet)
  IdentifierInfo *initWithTitleUIActionSheet[] = {
      &Ctx.Idents.get("initWithTitle"), &Ctx.Idents.get("delegate"),
      &Ctx.Idents.get("cancelButtonTitle"),
      &Ctx.Idents.get("destructiveButtonTitle"),
      &Ctx.Idents.get("otherButtonTitles")};
  ADD_METHOD(UIActionSheet, initWithTitleUIActionSheet, 5, 0)
  ADD_UNARY_METHOD(UIActionSheet, addButtonWithTitle, 0)
  ADD_UNARY_METHOD(UIActionSheet, setTitle, 0)

  NEW_RECEIVER(UIAccessibilityCustomAction)
  IdentifierInfo *initWithNameUIAccessibilityCustomAction[] = {
      &Ctx.Idents.get("initWithName"), &Ctx.Idents.get("target"),
      &Ctx.Idents.get("selector")};
  ADD_METHOD(UIAccessibilityCustomAction,
             initWithNameUIAccessibilityCustomAction, 3, 0)
  ADD_UNARY_METHOD(UIAccessibilityCustomAction, setName, 0)

  NEW_RECEIVER(UISearchBar)
  ADD_UNARY_METHOD(UISearchBar, setText, 0)
  ADD_UNARY_METHOD(UISearchBar, setPrompt, 0)
  ADD_UNARY_METHOD(UISearchBar, setPlaceholder, 0)

  NEW_RECEIVER(UIBarItem)
  ADD_UNARY_METHOD(UIBarItem, setTitle, 0)

  NEW_RECEIVER(UITextView)
  ADD_UNARY_METHOD(UITextView, setText, 0)

  NEW_RECEIVER(NSView)
  ADD_UNARY_METHOD(NSView, setToolTip, 0)

  NEW_RECEIVER(NSTextField)
  ADD_UNARY_METHOD(NSTextField, setPlaceholderString, 0)
  ADD_UNARY_METHOD(NSTextField, textFieldWithString, 0)
  ADD_UNARY_METHOD(NSTextField, wrappingLabelWithString, 0)
  ADD_UNARY_METHOD(NSTextField, labelWithString, 0)

  NEW_RECEIVER(NSAttributedString)
  ADD_UNARY_METHOD(NSAttributedString, initWithString, 0)
  IdentifierInfo *initWithStringNSAttributedString[] = {
      &Ctx.Idents.get("initWithString"), &Ctx.Idents.get("attributes")};
  ADD_METHOD(NSAttributedString, initWithStringNSAttributedString, 2, 0)

  NEW_RECEIVER(NSText)
  ADD_UNARY_METHOD(NSText, setString, 0)

  NEW_RECEIVER(UIKeyCommand)
  IdentifierInfo *keyCommandWithInputUIKeyCommand[] = {
      &Ctx.Idents.get("keyCommandWithInput"), &Ctx.Idents.get("modifierFlags"),
      &Ctx.Idents.get("action"), &Ctx.Idents.get("discoverabilityTitle")};
  ADD_METHOD(UIKeyCommand, keyCommandWithInputUIKeyCommand, 4, 3)
  ADD_UNARY_METHOD(UIKeyCommand, setDiscoverabilityTitle, 0)

  NEW_RECEIVER(UILabel)
  ADD_UNARY_METHOD(UILabel, setText, 0)

  NEW_RECEIVER(NSAlert)
  IdentifierInfo *alertWithMessageTextNSAlert[] = {
      &Ctx.Idents.get("alertWithMessageText"), &Ctx.Idents.get("defaultButton"),
      &Ctx.Idents.get("alternateButton"), &Ctx.Idents.get("otherButton"),
      &Ctx.Idents.get("informativeTextWithFormat")};
  ADD_METHOD(NSAlert, alertWithMessageTextNSAlert, 5, 0)
  ADD_UNARY_METHOD(NSAlert, addButtonWithTitle, 0)
  ADD_UNARY_METHOD(NSAlert, setMessageText, 0)
  ADD_UNARY_METHOD(NSAlert, setInformativeText, 0)
  ADD_UNARY_METHOD(NSAlert, setHelpAnchor, 0)

  NEW_RECEIVER(UIMutableApplicationShortcutItem)
  ADD_UNARY_METHOD(UIMutableApplicationShortcutItem, setLocalizedTitle, 0)
  ADD_UNARY_METHOD(UIMutableApplicationShortcutItem, setLocalizedSubtitle, 0)

  NEW_RECEIVER(UIButton)
  IdentifierInfo *setTitleUIButton[] = {&Ctx.Idents.get("setTitle"),
                                        &Ctx.Idents.get("forState")};
  ADD_METHOD(UIButton, setTitleUIButton, 2, 0)

  NEW_RECEIVER(NSWindow)
  ADD_UNARY_METHOD(NSWindow, setTitle, 0)
  IdentifierInfo *minFrameWidthWithTitleNSWindow[] = {
      &Ctx.Idents.get("minFrameWidthWithTitle"), &Ctx.Idents.get("styleMask")};
  ADD_METHOD(NSWindow, minFrameWidthWithTitleNSWindow, 2, 0)
  ADD_UNARY_METHOD(NSWindow, setMiniwindowTitle, 0)

  NEW_RECEIVER(NSPathCell)
  ADD_UNARY_METHOD(NSPathCell, setPlaceholderString, 0)

  NEW_RECEIVER(UIDocumentMenuViewController)
  IdentifierInfo *addOptionWithTitleUIDocumentMenuViewController[] = {
      &Ctx.Idents.get("addOptionWithTitle"), &Ctx.Idents.get("image"),
      &Ctx.Idents.get("order"), &Ctx.Idents.get("handler")};
  ADD_METHOD(UIDocumentMenuViewController,
             addOptionWithTitleUIDocumentMenuViewController, 4, 0)

  NEW_RECEIVER(UINavigationItem)
  ADD_UNARY_METHOD(UINavigationItem, initWithTitle, 0)
  ADD_UNARY_METHOD(UINavigationItem, setTitle, 0)
  ADD_UNARY_METHOD(UINavigationItem, setPrompt, 0)

  NEW_RECEIVER(UIAlertView)
  IdentifierInfo *initWithTitleUIAlertView[] = {
      &Ctx.Idents.get("initWithTitle"), &Ctx.Idents.get("message"),
      &Ctx.Idents.get("delegate"), &Ctx.Idents.get("cancelButtonTitle"),
      &Ctx.Idents.get("otherButtonTitles")};
  ADD_METHOD(UIAlertView, initWithTitleUIAlertView, 5, 0)
  ADD_UNARY_METHOD(UIAlertView, addButtonWithTitle, 0)
  ADD_UNARY_METHOD(UIAlertView, setTitle, 0)
  ADD_UNARY_METHOD(UIAlertView, setMessage, 0)

  NEW_RECEIVER(NSFormCell)
  ADD_UNARY_METHOD(NSFormCell, initTextCell, 0)
  ADD_UNARY_METHOD(NSFormCell, setTitle, 0)
  ADD_UNARY_METHOD(NSFormCell, setPlaceholderString, 0)

  NEW_RECEIVER(NSUserNotification)
  ADD_UNARY_METHOD(NSUserNotification, setTitle, 0)
  ADD_UNARY_METHOD(NSUserNotification, setSubtitle, 0)
  ADD_UNARY_METHOD(NSUserNotification, setInformativeText, 0)
  ADD_UNARY_METHOD(NSUserNotification, setActionButtonTitle, 0)
  ADD_UNARY_METHOD(NSUserNotification, setOtherButtonTitle, 0)
  ADD_UNARY_METHOD(NSUserNotification, setResponsePlaceholder, 0)

  NEW_RECEIVER(NSToolbarItem)
  ADD_UNARY_METHOD(NSToolbarItem, setLabel, 0)
  ADD_UNARY_METHOD(NSToolbarItem, setPaletteLabel, 0)
  ADD_UNARY_METHOD(NSToolbarItem, setToolTip, 0)

  NEW_RECEIVER(NSProgress)
  ADD_UNARY_METHOD(NSProgress, setLocalizedDescription, 0)
  ADD_UNARY_METHOD(NSProgress, setLocalizedAdditionalDescription, 0)

  NEW_RECEIVER(NSSegmentedCell)
  IdentifierInfo *setLabelNSSegmentedCell[] = {&Ctx.Idents.get("setLabel"),
                                               &Ctx.Idents.get("forSegment")};
  ADD_METHOD(NSSegmentedCell, setLabelNSSegmentedCell, 2, 0)
  IdentifierInfo *setToolTipNSSegmentedCell[] = {&Ctx.Idents.get("setToolTip"),
                                                 &Ctx.Idents.get("forSegment")};
  ADD_METHOD(NSSegmentedCell, setToolTipNSSegmentedCell, 2, 0)

  NEW_RECEIVER(NSUndoManager)
  ADD_UNARY_METHOD(NSUndoManager, setActionName, 0)
  ADD_UNARY_METHOD(NSUndoManager, undoMenuTitleForUndoActionName, 0)
  ADD_UNARY_METHOD(NSUndoManager, redoMenuTitleForUndoActionName, 0)

  NEW_RECEIVER(NSMenuItem)
  IdentifierInfo *initWithTitleNSMenuItem[] = {
      &Ctx.Idents.get("initWithTitle"), &Ctx.Idents.get("action"),
      &Ctx.Idents.get("keyEquivalent")};
  ADD_METHOD(NSMenuItem, initWithTitleNSMenuItem, 3, 0)
  ADD_UNARY_METHOD(NSMenuItem, setTitle, 0)
  ADD_UNARY_METHOD(NSMenuItem, setToolTip, 0)

  NEW_RECEIVER(NSPopUpButtonCell)
  IdentifierInfo *initTextCellNSPopUpButtonCell[] = {
      &Ctx.Idents.get("initTextCell"), &Ctx.Idents.get("pullsDown")};
  ADD_METHOD(NSPopUpButtonCell, initTextCellNSPopUpButtonCell, 2, 0)
  ADD_UNARY_METHOD(NSPopUpButtonCell, addItemWithTitle, 0)
  IdentifierInfo *insertItemWithTitleNSPopUpButtonCell[] = {
      &Ctx.Idents.get("insertItemWithTitle"), &Ctx.Idents.get("atIndex")};
  ADD_METHOD(NSPopUpButtonCell, insertItemWithTitleNSPopUpButtonCell, 2, 0)
  ADD_UNARY_METHOD(NSPopUpButtonCell, removeItemWithTitle, 0)
  ADD_UNARY_METHOD(NSPopUpButtonCell, selectItemWithTitle, 0)
  ADD_UNARY_METHOD(NSPopUpButtonCell, setTitle, 0)

  NEW_RECEIVER(NSViewController)
  ADD_UNARY_METHOD(NSViewController, setTitle, 0)

  NEW_RECEIVER(NSMenu)
  ADD_UNARY_METHOD(NSMenu, initWithTitle, 0)
  IdentifierInfo *insertItemWithTitleNSMenu[] = {
      &Ctx.Idents.get("insertItemWithTitle"), &Ctx.Idents.get("action"),
      &Ctx.Idents.get("keyEquivalent"), &Ctx.Idents.get("atIndex")};
  ADD_METHOD(NSMenu, insertItemWithTitleNSMenu, 4, 0)
  IdentifierInfo *addItemWithTitleNSMenu[] = {
      &Ctx.Idents.get("addItemWithTitle"), &Ctx.Idents.get("action"),
      &Ctx.Idents.get("keyEquivalent")};
  ADD_METHOD(NSMenu, addItemWithTitleNSMenu, 3, 0)
  ADD_UNARY_METHOD(NSMenu, setTitle, 0)

  NEW_RECEIVER(UIMutableUserNotificationAction)
  ADD_UNARY_METHOD(UIMutableUserNotificationAction, setTitle, 0)

  NEW_RECEIVER(NSForm)
  ADD_UNARY_METHOD(NSForm, addEntry, 0)
  IdentifierInfo *insertEntryNSForm[] = {&Ctx.Idents.get("insertEntry"),
                                         &Ctx.Idents.get("atIndex")};
  ADD_METHOD(NSForm, insertEntryNSForm, 2, 0)

  NEW_RECEIVER(NSTextFieldCell)
  ADD_UNARY_METHOD(NSTextFieldCell, setPlaceholderString, 0)

  NEW_RECEIVER(NSUserNotificationAction)
  IdentifierInfo *actionWithIdentifierNSUserNotificationAction[] = {
      &Ctx.Idents.get("actionWithIdentifier"), &Ctx.Idents.get("title")};
  ADD_METHOD(NSUserNotificationAction,
             actionWithIdentifierNSUserNotificationAction, 2, 1)

  NEW_RECEIVER(UITextField)
  ADD_UNARY_METHOD(UITextField, setText, 0)
  ADD_UNARY_METHOD(UITextField, setPlaceholder, 0)

  NEW_RECEIVER(UIBarButtonItem)
  IdentifierInfo *initWithTitleUIBarButtonItem[] = {
      &Ctx.Idents.get("initWithTitle"), &Ctx.Idents.get("style"),
      &Ctx.Idents.get("target"), &Ctx.Idents.get("action")};
  ADD_METHOD(UIBarButtonItem, initWithTitleUIBarButtonItem, 4, 0)

  NEW_RECEIVER(UIViewController)
  ADD_UNARY_METHOD(UIViewController, setTitle, 0)

  NEW_RECEIVER(UISegmentedControl)
  IdentifierInfo *insertSegmentWithTitleUISegmentedControl[] = {
      &Ctx.Idents.get("insertSegmentWithTitle"), &Ctx.Idents.get("atIndex"),
      &Ctx.Idents.get("animated")};
  ADD_METHOD(UISegmentedControl, insertSegmentWithTitleUISegmentedControl, 3, 0)
  IdentifierInfo *setTitleUISegmentedControl[] = {
      &Ctx.Idents.get("setTitle"), &Ctx.Idents.get("forSegmentAtIndex")};
  ADD_METHOD(UISegmentedControl, setTitleUISegmentedControl, 2, 0)

  NEW_RECEIVER(NSAccessibilityCustomRotorItemResult)
  IdentifierInfo
      *initWithItemLoadingTokenNSAccessibilityCustomRotorItemResult[] = {
          &Ctx.Idents.get("initWithItemLoadingToken"),
          &Ctx.Idents.get("customLabel")};
  ADD_METHOD(NSAccessibilityCustomRotorItemResult,
             initWithItemLoadingTokenNSAccessibilityCustomRotorItemResult, 2, 1)
  ADD_UNARY_METHOD(NSAccessibilityCustomRotorItemResult, setCustomLabel, 0)

  NEW_RECEIVER(UIContextualAction)
  IdentifierInfo *contextualActionWithStyleUIContextualAction[] = {
      &Ctx.Idents.get("contextualActionWithStyle"), &Ctx.Idents.get("title"),
      &Ctx.Idents.get("handler")};
  ADD_METHOD(UIContextualAction, contextualActionWithStyleUIContextualAction, 3,
             1)
  ADD_UNARY_METHOD(UIContextualAction, setTitle, 0)

  NEW_RECEIVER(NSAccessibilityCustomRotor)
  IdentifierInfo *initWithLabelNSAccessibilityCustomRotor[] = {
      &Ctx.Idents.get("initWithLabel"), &Ctx.Idents.get("itemSearchDelegate")};
  ADD_METHOD(NSAccessibilityCustomRotor,
             initWithLabelNSAccessibilityCustomRotor, 2, 0)
  ADD_UNARY_METHOD(NSAccessibilityCustomRotor, setLabel, 0)

  NEW_RECEIVER(NSWindowTab)
  ADD_UNARY_METHOD(NSWindowTab, setTitle, 0)
  ADD_UNARY_METHOD(NSWindowTab, setToolTip, 0)

  NEW_RECEIVER(NSAccessibilityCustomAction)
  IdentifierInfo *initWithNameNSAccessibilityCustomAction[] = {
      &Ctx.Idents.get("initWithName"), &Ctx.Idents.get("handler")};
  ADD_METHOD(NSAccessibilityCustomAction,
             initWithNameNSAccessibilityCustomAction, 2, 0)
  IdentifierInfo *initWithNameTargetNSAccessibilityCustomAction[] = {
      &Ctx.Idents.get("initWithName"), &Ctx.Idents.get("target"),
      &Ctx.Idents.get("selector")};
  ADD_METHOD(NSAccessibilityCustomAction,
             initWithNameTargetNSAccessibilityCustomAction, 3, 0)
  ADD_UNARY_METHOD(NSAccessibilityCustomAction, setName, 0)
}

#define LSF_INSERT(function_name) LSF.insert(&Ctx.Idents.get(function_name));
#define LSM_INSERT_NULLARY(receiver, method_name)                              \
  LSM.insert({&Ctx.Idents.get(receiver), Ctx.Selectors.getNullarySelector(     \
                                             &Ctx.Idents.get(method_name))});
#define LSM_INSERT_UNARY(receiver, method_name)                                \
  LSM.insert({&Ctx.Idents.get(receiver),                                       \
              Ctx.Selectors.getUnarySelector(&Ctx.Idents.get(method_name))});
#define LSM_INSERT_SELECTOR(receiver, method_list, arguments)                  \
  LSM.insert({&Ctx.Idents.get(receiver),                                       \
              Ctx.Selectors.getSelector(arguments, method_list)});

/// Initializes a list of methods and C functions that return a localized string
void NonLocalizedStringChecker::initLocStringsMethods(ASTContext &Ctx) const {
  if (!LSM.empty())
    return;

  IdentifierInfo *LocalizedStringMacro[] = {
      &Ctx.Idents.get("localizedStringForKey"), &Ctx.Idents.get("value"),
      &Ctx.Idents.get("table")};
  LSM_INSERT_SELECTOR("NSBundle", LocalizedStringMacro, 3)
  LSM_INSERT_UNARY("NSDateFormatter", "stringFromDate")
  IdentifierInfo *LocalizedStringFromDate[] = {
      &Ctx.Idents.get("localizedStringFromDate"), &Ctx.Idents.get("dateStyle"),
      &Ctx.Idents.get("timeStyle")};
  LSM_INSERT_SELECTOR("NSDateFormatter", LocalizedStringFromDate, 3)
  LSM_INSERT_UNARY("NSNumberFormatter", "stringFromNumber")
  LSM_INSERT_NULLARY("UITextField", "text")
  LSM_INSERT_NULLARY("UITextView", "text")
  LSM_INSERT_NULLARY("UILabel", "text")

  LSF_INSERT("CFDateFormatterCreateStringWithDate");
  LSF_INSERT("CFDateFormatterCreateStringWithAbsoluteTime");
  LSF_INSERT("CFNumberFormatterCreateStringWithNumber");
}

/// Checks to see if the method / function declaration includes
/// __attribute__((annotate("returns_localized_nsstring")))
bool NonLocalizedStringChecker::isAnnotatedAsReturningLocalized(
    const Decl *D) const {
  if (!D)
    return false;
  return std::any_of(
      D->specific_attr_begin<AnnotateAttr>(),
      D->specific_attr_end<AnnotateAttr>(), [](const AnnotateAttr *Ann) {
        return Ann->getAnnotation() == "returns_localized_nsstring";
      });
}

/// Checks to see if the method / function declaration includes
/// __attribute__((annotate("takes_localized_nsstring")))
bool NonLocalizedStringChecker::isAnnotatedAsTakingLocalized(
    const Decl *D) const {
  if (!D)
    return false;
  return std::any_of(
      D->specific_attr_begin<AnnotateAttr>(),
      D->specific_attr_end<AnnotateAttr>(), [](const AnnotateAttr *Ann) {
        return Ann->getAnnotation() == "takes_localized_nsstring";
      });
}

/// Returns true if the given SVal is marked as Localized in the program state
bool NonLocalizedStringChecker::hasLocalizedState(SVal S,
                                                  CheckerContext &C) const {
  const MemRegion *mt = S.getAsRegion();
  if (mt) {
    const LocalizedState *LS = C.getState()->get<LocalizedMemMap>(mt);
    if (LS && LS->isLocalized())
      return true;
  }
  return false;
}

/// Returns true if the given SVal is marked as NonLocalized in the program
/// state
bool NonLocalizedStringChecker::hasNonLocalizedState(SVal S,
                                                     CheckerContext &C) const {
  const MemRegion *mt = S.getAsRegion();
  if (mt) {
    const LocalizedState *LS = C.getState()->get<LocalizedMemMap>(mt);
    if (LS && LS->isNonLocalized())
      return true;
  }
  return false;
}

/// Marks the given SVal as Localized in the program state
void NonLocalizedStringChecker::setLocalizedState(const SVal S,
                                                  CheckerContext &C) const {
  const MemRegion *mt = S.getAsRegion();
  if (mt) {
    ProgramStateRef State =
        C.getState()->set<LocalizedMemMap>(mt, LocalizedState::getLocalized());
    C.addTransition(State);
  }
}

/// Marks the given SVal as NonLocalized in the program state
void NonLocalizedStringChecker::setNonLocalizedState(const SVal S,
                                                     CheckerContext &C) const {
  const MemRegion *mt = S.getAsRegion();
  if (mt) {
    ProgramStateRef State = C.getState()->set<LocalizedMemMap>(
        mt, LocalizedState::getNonLocalized());
    C.addTransition(State);
  }
}


static bool isDebuggingName(std::string name) {
  return StringRef(name).lower().find("debug") != StringRef::npos;
}

/// Returns true when, heuristically, the analyzer may be analyzing debugging
/// code. We use this to suppress localization diagnostics in un-localized user
/// interfaces that are only used for debugging and are therefore not user
/// facing.
static bool isDebuggingContext(CheckerContext &C) {
  const Decl *D = C.getCurrentAnalysisDeclContext()->getDecl();
  if (!D)
    return false;

  if (auto *ND = dyn_cast<NamedDecl>(D)) {
    if (isDebuggingName(ND->getNameAsString()))
      return true;
  }

  const DeclContext *DC = D->getDeclContext();

  if (auto *CD = dyn_cast<ObjCContainerDecl>(DC)) {
    if (isDebuggingName(CD->getNameAsString()))
      return true;
  }

  return false;
}


/// Reports a localization error for the passed in method call and SVal
void NonLocalizedStringChecker::reportLocalizationError(
    SVal S, const CallEvent &M, CheckerContext &C, int argumentNumber) const {

  // Don't warn about localization errors in classes and methods that
  // may be debug code.
  if (isDebuggingContext(C))
    return;

  ExplodedNode *ErrNode = C.getPredecessor();
  static CheckerProgramPointTag Tag("NonLocalizedStringChecker",
                                    "UnlocalizedString");
  ErrNode = C.addTransition(C.getState(), C.getPredecessor(), &Tag);

  if (!ErrNode)
    return;

  // Generate the bug report.
  std::unique_ptr<BugReport> R(new BugReport(
      *BT, "User-facing text should use localized string macro", ErrNode));
  if (argumentNumber) {
    R->addRange(M.getArgExpr(argumentNumber - 1)->getSourceRange());
  } else {
    R->addRange(M.getSourceRange());
  }
  R->markInteresting(S);

  const MemRegion *StringRegion = S.getAsRegion();
  if (StringRegion)
    R->addVisitor(llvm::make_unique<NonLocalizedStringBRVisitor>(StringRegion));

  C.emitReport(std::move(R));
}

/// Returns the argument number requiring localized string if it exists
/// otherwise, returns -1
int NonLocalizedStringChecker::getLocalizedArgumentForSelector(
    const IdentifierInfo *Receiver, Selector S) const {
  auto method = UIMethods.find(Receiver);

  if (method == UIMethods.end())
    return -1;

  auto argumentIterator = method->getSecond().find(S);

  if (argumentIterator == method->getSecond().end())
    return -1;

  int argumentNumber = argumentIterator->getSecond();
  return argumentNumber;
}

/// Check if the string being passed in has NonLocalized state
void NonLocalizedStringChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
                                                    CheckerContext &C) const {
  initUIMethods(C.getASTContext());

  const ObjCInterfaceDecl *OD = msg.getReceiverInterface();
  if (!OD)
    return;
  const IdentifierInfo *odInfo = OD->getIdentifier();

  Selector S = msg.getSelector();

  std::string SelectorString = S.getAsString();
  StringRef SelectorName = SelectorString;
  assert(!SelectorName.empty());

  if (odInfo->isStr("NSString")) {
    // Handle the case where the receiver is an NSString
    // These special NSString methods draw to the screen

    if (!(SelectorName.startswith("drawAtPoint") ||
          SelectorName.startswith("drawInRect") ||
          SelectorName.startswith("drawWithRect")))
      return;

    SVal svTitle = msg.getReceiverSVal();

    bool isNonLocalized = hasNonLocalizedState(svTitle, C);

    if (isNonLocalized) {
      reportLocalizationError(svTitle, msg, C);
    }
  }

  int argumentNumber = getLocalizedArgumentForSelector(odInfo, S);
  // Go up each hierarchy of superclasses and their protocols
  while (argumentNumber < 0 && OD->getSuperClass() != nullptr) {
    for (const auto *P : OD->all_referenced_protocols()) {
      argumentNumber = getLocalizedArgumentForSelector(P->getIdentifier(), S);
      if (argumentNumber >= 0)
        break;
    }
    if (argumentNumber < 0) {
      OD = OD->getSuperClass();
      argumentNumber = getLocalizedArgumentForSelector(OD->getIdentifier(), S);
    }
  }

  if (argumentNumber < 0) { // There was no match in UIMethods
    if (const Decl *D = msg.getDecl()) {
      if (const ObjCMethodDecl *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
        auto formals = OMD->parameters();
        for (unsigned i = 0, ei = formals.size(); i != ei; ++i) {
          if (isAnnotatedAsTakingLocalized(formals[i])) {
            argumentNumber = i;
            break;
          }
        }
      }
    }
  }

  if (argumentNumber < 0) // Still no match
    return;

  SVal svTitle = msg.getArgSVal(argumentNumber);

  if (const ObjCStringRegion *SR =
          dyn_cast_or_null<ObjCStringRegion>(svTitle.getAsRegion())) {
    StringRef stringValue =
        SR->getObjCStringLiteral()->getString()->getString();
    if ((stringValue.trim().size() == 0 && stringValue.size() > 0) ||
        stringValue.empty())
      return;
    if (!IsAggressive && llvm::sys::unicode::columnWidthUTF8(stringValue) < 2)
      return;
  }

  bool isNonLocalized = hasNonLocalizedState(svTitle, C);

  if (isNonLocalized) {
    reportLocalizationError(svTitle, msg, C, argumentNumber + 1);
  }
}

void NonLocalizedStringChecker::checkPreCall(const CallEvent &Call,
                                             CheckerContext &C) const {
  const Decl *D = Call.getDecl();
  if (D && isa<FunctionDecl>(D)) {
    const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
    auto formals = FD->parameters();
    for (unsigned i = 0,
                  ei = std::min(unsigned(formals.size()), Call.getNumArgs());
         i != ei; ++i) {
      if (isAnnotatedAsTakingLocalized(formals[i])) {
        auto actual = Call.getArgSVal(i);
        if (hasNonLocalizedState(actual, C)) {
          reportLocalizationError(actual, Call, C, i + 1);
        }
      }
    }
  }
}

static inline bool isNSStringType(QualType T, ASTContext &Ctx) {

  const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
  if (!PT)
    return false;

  ObjCInterfaceDecl *Cls = PT->getObjectType()->getInterface();
  if (!Cls)
    return false;

  IdentifierInfo *ClsName = Cls->getIdentifier();

  // FIXME: Should we walk the chain of classes?
  return ClsName == &Ctx.Idents.get("NSString") ||
         ClsName == &Ctx.Idents.get("NSMutableString");
}

/// Marks a string being returned by any call as localized
/// if it is in LocStringFunctions (LSF) or the function is annotated.
/// Otherwise, we mark it as NonLocalized (Aggressive) or
/// NonLocalized only if it is not backed by a SymRegion (Non-Aggressive),
/// basically leaving only string literals as NonLocalized.
void NonLocalizedStringChecker::checkPostCall(const CallEvent &Call,
                                              CheckerContext &C) const {
  initLocStringsMethods(C.getASTContext());

  if (!Call.getOriginExpr())
    return;

  // Anything that takes in a localized NSString as an argument
  // and returns an NSString will be assumed to be returning a
  // localized NSString. (Counter: Incorrectly combining two LocalizedStrings)
  const QualType RT = Call.getResultType();
  if (isNSStringType(RT, C.getASTContext())) {
    for (unsigned i = 0; i < Call.getNumArgs(); ++i) {
      SVal argValue = Call.getArgSVal(i);
      if (hasLocalizedState(argValue, C)) {
        SVal sv = Call.getReturnValue();
        setLocalizedState(sv, C);
        return;
      }
    }
  }

  const Decl *D = Call.getDecl();
  if (!D)
    return;

  const IdentifierInfo *Identifier = Call.getCalleeIdentifier();

  SVal sv = Call.getReturnValue();
  if (isAnnotatedAsReturningLocalized(D) || LSF.count(Identifier) != 0) {
    setLocalizedState(sv, C);
  } else if (isNSStringType(RT, C.getASTContext()) &&
             !hasLocalizedState(sv, C)) {
    if (IsAggressive) {
      setNonLocalizedState(sv, C);
    } else {
      const SymbolicRegion *SymReg =
          dyn_cast_or_null<SymbolicRegion>(sv.getAsRegion());
      if (!SymReg)
        setNonLocalizedState(sv, C);
    }
  }
}

/// Marks a string being returned by an ObjC method as localized
/// if it is in LocStringMethods or the method is annotated
void NonLocalizedStringChecker::checkPostObjCMessage(const ObjCMethodCall &msg,
                                                     CheckerContext &C) const {
  initLocStringsMethods(C.getASTContext());

  if (!msg.isInstanceMessage())
    return;

  const ObjCInterfaceDecl *OD = msg.getReceiverInterface();
  if (!OD)
    return;
  const IdentifierInfo *odInfo = OD->getIdentifier();

  Selector S = msg.getSelector();
  std::string SelectorName = S.getAsString();

  std::pair<const IdentifierInfo *, Selector> MethodDescription = {odInfo, S};

  if (LSM.count(MethodDescription) ||
      isAnnotatedAsReturningLocalized(msg.getDecl())) {
    SVal sv = msg.getReturnValue();
    setLocalizedState(sv, C);
  }
}

/// Marks all empty string literals as localized
void NonLocalizedStringChecker::checkPostStmt(const ObjCStringLiteral *SL,
                                              CheckerContext &C) const {
  SVal sv = C.getSVal(SL);
  setNonLocalizedState(sv, C);
}

std::shared_ptr<PathDiagnosticPiece>
NonLocalizedStringBRVisitor::VisitNode(const ExplodedNode *Succ,
                                       BugReporterContext &BRC, BugReport &BR) {
  if (Satisfied)
    return nullptr;

  Optional<StmtPoint> Point = Succ->getLocation().getAs<StmtPoint>();
  if (!Point.hasValue())
    return nullptr;

  auto *LiteralExpr = dyn_cast<ObjCStringLiteral>(Point->getStmt());
  if (!LiteralExpr)
    return nullptr;

  SVal LiteralSVal = Succ->getSVal(LiteralExpr);
  if (LiteralSVal.getAsRegion() != NonLocalizedString)
    return nullptr;

  Satisfied = true;

  PathDiagnosticLocation L =
      PathDiagnosticLocation::create(*Point, BRC.getSourceManager());

  if (!L.isValid() || !L.asLocation().isValid())
    return nullptr;

  auto Piece = std::make_shared<PathDiagnosticEventPiece>(
      L, "Non-localized string literal here");
  Piece->addRange(LiteralExpr->getSourceRange());

  return std::move(Piece);
}

namespace {
class EmptyLocalizationContextChecker
    : public Checker<check::ASTDecl<ObjCImplementationDecl>> {

  // A helper class, which walks the AST
  class MethodCrawler : public ConstStmtVisitor<MethodCrawler> {
    const ObjCMethodDecl *MD;
    BugReporter &BR;
    AnalysisManager &Mgr;
    const CheckerBase *Checker;
    LocationOrAnalysisDeclContext DCtx;

  public:
    MethodCrawler(const ObjCMethodDecl *InMD, BugReporter &InBR,
                  const CheckerBase *Checker, AnalysisManager &InMgr,
                  AnalysisDeclContext *InDCtx)
        : MD(InMD), BR(InBR), Mgr(InMgr), Checker(Checker), DCtx(InDCtx) {}

    void VisitStmt(const Stmt *S) { VisitChildren(S); }

    void VisitObjCMessageExpr(const ObjCMessageExpr *ME);

    void reportEmptyContextError(const ObjCMessageExpr *M) const;

    void VisitChildren(const Stmt *S) {
      for (const Stmt *Child : S->children()) {
        if (Child)
          this->Visit(Child);
      }
    }
  };

public:
  void checkASTDecl(const ObjCImplementationDecl *D, AnalysisManager &Mgr,
                    BugReporter &BR) const;
};
} // end anonymous namespace

void EmptyLocalizationContextChecker::checkASTDecl(
    const ObjCImplementationDecl *D, AnalysisManager &Mgr,
    BugReporter &BR) const {

  for (const ObjCMethodDecl *M : D->methods()) {
    AnalysisDeclContext *DCtx = Mgr.getAnalysisDeclContext(M);

    const Stmt *Body = M->getBody();
    assert(Body);

    MethodCrawler MC(M->getCanonicalDecl(), BR, this, Mgr, DCtx);
    MC.VisitStmt(Body);
  }
}

/// This check attempts to match these macros, assuming they are defined as
/// follows:
///
/// #define NSLocalizedString(key, comment) \
/// [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:nil]
/// #define NSLocalizedStringFromTable(key, tbl, comment) \
/// [[NSBundle mainBundle] localizedStringForKey:(key) value:@"" table:(tbl)]
/// #define NSLocalizedStringFromTableInBundle(key, tbl, bundle, comment) \
/// [bundle localizedStringForKey:(key) value:@"" table:(tbl)]
/// #define NSLocalizedStringWithDefaultValue(key, tbl, bundle, val, comment)
///
/// We cannot use the path sensitive check because the macro argument we are
/// checking for (comment) is not used and thus not present in the AST,
/// so we use Lexer on the original macro call and retrieve the value of
/// the comment. If it's empty or nil, we raise a warning.
void EmptyLocalizationContextChecker::MethodCrawler::VisitObjCMessageExpr(
    const ObjCMessageExpr *ME) {

  // FIXME: We may be able to use PPCallbacks to check for empty context
  // comments as part of preprocessing and avoid this re-lexing hack.
  const ObjCInterfaceDecl *OD = ME->getReceiverInterface();
  if (!OD)
    return;

  const IdentifierInfo *odInfo = OD->getIdentifier();

  if (!(odInfo->isStr("NSBundle") &&
        ME->getSelector().getAsString() ==
            "localizedStringForKey:value:table:")) {
    return;
  }

  SourceRange R = ME->getSourceRange();
  if (!R.getBegin().isMacroID())
    return;

  // getImmediateMacroCallerLoc gets the location of the immediate macro
  // caller, one level up the stack toward the initial macro typed into the
  // source, so SL should point to the NSLocalizedString macro.
  SourceLocation SL =
      Mgr.getSourceManager().getImmediateMacroCallerLoc(R.getBegin());
  std::pair<FileID, unsigned> SLInfo =
      Mgr.getSourceManager().getDecomposedLoc(SL);

  SrcMgr::SLocEntry SE = Mgr.getSourceManager().getSLocEntry(SLInfo.first);

  // If NSLocalizedString macro is wrapped in another macro, we need to
  // unwrap the expansion until we get to the NSLocalizedStringMacro.
  while (SE.isExpansion()) {
    SL = SE.getExpansion().getSpellingLoc();
    SLInfo = Mgr.getSourceManager().getDecomposedLoc(SL);
    SE = Mgr.getSourceManager().getSLocEntry(SLInfo.first);
  }

  bool Invalid = false;
  llvm::MemoryBuffer *BF =
      Mgr.getSourceManager().getBuffer(SLInfo.first, SL, &Invalid);
  if (Invalid)
    return;

  Lexer TheLexer(SL, LangOptions(), BF->getBufferStart(),
                 BF->getBufferStart() + SLInfo.second, BF->getBufferEnd());

  Token I;
  Token Result;    // This will hold the token just before the last ')'
  int p_count = 0; // This is for parenthesis matching
  while (!TheLexer.LexFromRawLexer(I)) {
    if (I.getKind() == tok::l_paren)
      ++p_count;
    if (I.getKind() == tok::r_paren) {
      if (p_count == 1)
        break;
      --p_count;
    }
    Result = I;
  }

  if (isAnyIdentifier(Result.getKind())) {
    if (Result.getRawIdentifier().equals("nil")) {
      reportEmptyContextError(ME);
      return;
    }
  }

  if (!isStringLiteral(Result.getKind()))
    return;

  StringRef Comment =
      StringRef(Result.getLiteralData(), Result.getLength()).trim('"');

  if ((Comment.trim().size() == 0 && Comment.size() > 0) || // Is Whitespace
      Comment.empty()) {
    reportEmptyContextError(ME);
  }
}

void EmptyLocalizationContextChecker::MethodCrawler::reportEmptyContextError(
    const ObjCMessageExpr *ME) const {
  // Generate the bug report.
  BR.EmitBasicReport(MD, Checker, "Context Missing",
                     "Localizability Issue (Apple)",
                     "Localized string macro should include a non-empty "
                     "comment for translators",
                     PathDiagnosticLocation(ME, BR.getSourceManager(), DCtx));
}

namespace {
class PluralMisuseChecker : public Checker<check::ASTCodeBody> {

  // A helper class, which walks the AST
  class MethodCrawler : public RecursiveASTVisitor<MethodCrawler> {
    BugReporter &BR;
    const CheckerBase *Checker;
    AnalysisDeclContext *AC;

    // This functions like a stack. We push on any IfStmt or
    // ConditionalOperator that matches the condition
    // and pop it off when we leave that statement
    llvm::SmallVector<const clang::Stmt *, 8> MatchingStatements;
    // This is true when we are the direct-child of a
    // matching statement
    bool InMatchingStatement = false;

  public:
    explicit MethodCrawler(BugReporter &InBR, const CheckerBase *Checker,
                           AnalysisDeclContext *InAC)
        : BR(InBR), Checker(Checker), AC(InAC) {}

    bool VisitIfStmt(const IfStmt *I);
    bool EndVisitIfStmt(IfStmt *I);
    bool TraverseIfStmt(IfStmt *x);
    bool VisitConditionalOperator(const ConditionalOperator *C);
    bool TraverseConditionalOperator(ConditionalOperator *C);
    bool VisitCallExpr(const CallExpr *CE);
    bool VisitObjCMessageExpr(const ObjCMessageExpr *ME);

  private:
    void reportPluralMisuseError(const Stmt *S) const;
    bool isCheckingPlurality(const Expr *E) const;
  };

public:
  void checkASTCodeBody(const Decl *D, AnalysisManager &Mgr,
                        BugReporter &BR) const {
    MethodCrawler Visitor(BR, this, Mgr.getAnalysisDeclContext(D));
    Visitor.TraverseDecl(const_cast<Decl *>(D));
  }
};
} // end anonymous namespace

// Checks the condition of the IfStmt and returns true if one
// of the following heuristics are met:
// 1) The conidtion is a variable with "singular" or "plural" in the name
// 2) The condition is a binary operator with 1 or 2 on the right-hand side
bool PluralMisuseChecker::MethodCrawler::isCheckingPlurality(
    const Expr *Condition) const {
  const BinaryOperator *BO = nullptr;
  // Accounts for when a VarDecl represents a BinaryOperator
  if (const DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Condition)) {
    if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
      const Expr *InitExpr = VD->getInit();
      if (InitExpr) {
        if (const BinaryOperator *B =
                dyn_cast<BinaryOperator>(InitExpr->IgnoreParenImpCasts())) {
          BO = B;
        }
      }
      if (VD->getName().lower().find("plural") != StringRef::npos ||
          VD->getName().lower().find("singular") != StringRef::npos) {
        return true;
      }
    }
  } else if (const BinaryOperator *B = dyn_cast<BinaryOperator>(Condition)) {
    BO = B;
  }

  if (BO == nullptr)
    return false;

  if (IntegerLiteral *IL = dyn_cast_or_null<IntegerLiteral>(
          BO->getRHS()->IgnoreParenImpCasts())) {
    llvm::APInt Value = IL->getValue();
    if (Value == 1 || Value == 2) {
      return true;
    }
  }
  return false;
}

// A CallExpr with "LOC" in its identifier that takes in a string literal
// has been shown to almost always be a function that returns a localized
// string. Raise a diagnostic when this is in a statement that matches
// the condition.
bool PluralMisuseChecker::MethodCrawler::VisitCallExpr(const CallExpr *CE) {
  if (InMatchingStatement) {
    if (const FunctionDecl *FD = CE->getDirectCallee()) {
      std::string NormalizedName =
          StringRef(FD->getNameInfo().getAsString()).lower();
      if (NormalizedName.find("loc") != std::string::npos) {
        for (const Expr *Arg : CE->arguments()) {
          if (isa<ObjCStringLiteral>(Arg))
            reportPluralMisuseError(CE);
        }
      }
    }
  }
  return true;
}

// The other case is for NSLocalizedString which also returns
// a localized string. It's a macro for the ObjCMessageExpr
// [NSBundle localizedStringForKey:value:table:] Raise a
// diagnostic when this is in a statement that matches
// the condition.
bool PluralMisuseChecker::MethodCrawler::VisitObjCMessageExpr(
    const ObjCMessageExpr *ME) {
  const ObjCInterfaceDecl *OD = ME->getReceiverInterface();
  if (!OD)
    return true;

  const IdentifierInfo *odInfo = OD->getIdentifier();

  if (odInfo->isStr("NSBundle") &&
      ME->getSelector().getAsString() == "localizedStringForKey:value:table:") {
    if (InMatchingStatement) {
      reportPluralMisuseError(ME);
    }
  }
  return true;
}

/// Override TraverseIfStmt so we know when we are done traversing an IfStmt
bool PluralMisuseChecker::MethodCrawler::TraverseIfStmt(IfStmt *I) {
  RecursiveASTVisitor<MethodCrawler>::TraverseIfStmt(I);
  return EndVisitIfStmt(I);
}

// EndVisit callbacks are not provided by the RecursiveASTVisitor
// so we override TraverseIfStmt and make a call to EndVisitIfStmt
// after traversing the IfStmt
bool PluralMisuseChecker::MethodCrawler::EndVisitIfStmt(IfStmt *I) {
  MatchingStatements.pop_back();
  if (!MatchingStatements.empty()) {
    if (MatchingStatements.back() != nullptr) {
      InMatchingStatement = true;
      return true;
    }
  }
  InMatchingStatement = false;
  return true;
}

bool PluralMisuseChecker::MethodCrawler::VisitIfStmt(const IfStmt *I) {
  const Expr *Condition = I->getCond()->IgnoreParenImpCasts();
  if (isCheckingPlurality(Condition)) {
    MatchingStatements.push_back(I);
    InMatchingStatement = true;
  } else {
    MatchingStatements.push_back(nullptr);
    InMatchingStatement = false;
  }

  return true;
}

// Preliminary support for conditional operators.
bool PluralMisuseChecker::MethodCrawler::TraverseConditionalOperator(
    ConditionalOperator *C) {
  RecursiveASTVisitor<MethodCrawler>::TraverseConditionalOperator(C);
  MatchingStatements.pop_back();
  if (!MatchingStatements.empty()) {
    if (MatchingStatements.back() != nullptr)
      InMatchingStatement = true;
    else
      InMatchingStatement = false;
  } else {
    InMatchingStatement = false;
  }
  return true;
}

bool PluralMisuseChecker::MethodCrawler::VisitConditionalOperator(
    const ConditionalOperator *C) {
  const Expr *Condition = C->getCond()->IgnoreParenImpCasts();
  if (isCheckingPlurality(Condition)) {
    MatchingStatements.push_back(C);
    InMatchingStatement = true;
  } else {
    MatchingStatements.push_back(nullptr);
    InMatchingStatement = false;
  }
  return true;
}

void PluralMisuseChecker::MethodCrawler::reportPluralMisuseError(
    const Stmt *S) const {
  // Generate the bug report.
  BR.EmitBasicReport(AC->getDecl(), Checker, "Plural Misuse",
                     "Localizability Issue (Apple)",
                     "Plural cases are not supported across all languages. "
                     "Use a .stringsdict file instead",
                     PathDiagnosticLocation(S, BR.getSourceManager(), AC));
}

//===----------------------------------------------------------------------===//
// Checker registration.
//===----------------------------------------------------------------------===//

void ento::registerNonLocalizedStringChecker(CheckerManager &mgr) {
  NonLocalizedStringChecker *checker =
      mgr.registerChecker<NonLocalizedStringChecker>();
  checker->IsAggressive =
      mgr.getAnalyzerOptions().getCheckerBooleanOption("AggressiveReport",
                                                       false, checker);
}

void ento::registerEmptyLocalizationContextChecker(CheckerManager &mgr) {
  mgr.registerChecker<EmptyLocalizationContextChecker>();
}

void ento::registerPluralMisuseChecker(CheckerManager &mgr) {
  mgr.registerChecker<PluralMisuseChecker>();
}
