| 12
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
 100
 101
 102
 103
 104
 105
 106
 107
 108
 109
 110
 
 | // RUN: %check_clang_tidy %s performance-faster-string-find %t -- \
// RUN:   -config="{CheckOptions: \
// RUN:             [{key: performance-faster-string-find.StringLikeClasses, \
// RUN:               value: 'std::basic_string; ::llvm::StringRef;'}]}" --
namespace std {
template <typename Char>
struct basic_string {
  int find(const Char *, int = 0) const;
  int find(const Char *, int, int) const;
  int rfind(const Char *) const;
  int find_first_of(const Char *) const;
  int find_first_not_of(const Char *) const;
  int find_last_of(const Char *) const;
  int find_last_not_of(const Char *) const;
};
typedef basic_string<char> string;
typedef basic_string<wchar_t> wstring;
}  // namespace std
namespace llvm {
struct StringRef {
  int find(const char *) const;
};
}  // namespace llvm
struct NotStringRef {
  int find(const char *);
};
void StringFind() {
  std::string Str;
  Str.find("a");
  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal consisting of a single character; consider using the more effective overload accepting a character [performance-faster-string-find]
  // CHECK-FIXES: Str.find('a');
  // Works with the pos argument.
  Str.find("a", 1);
  // CHECK-MESSAGES: [[@LINE-1]]:12: warning: 'find' called with a string literal
  // CHECK-FIXES: Str.find('a', 1);
  // Doens't work with strings smaller or larger than 1 char.
  Str.find("");
  Str.find("ab");
  // Doesn't do anything with the 3 argument overload.
  Str.find("a", 1, 1);
  // Other methods that can also be replaced
  Str.rfind("a");
  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'rfind' called with a string literal
  // CHECK-FIXES: Str.rfind('a');
  Str.find_first_of("a");
  // CHECK-MESSAGES: [[@LINE-1]]:21: warning: 'find_first_of' called with a string
  // CHECK-FIXES: Str.find_first_of('a');
  Str.find_first_not_of("a");
  // CHECK-MESSAGES: [[@LINE-1]]:25: warning: 'find_first_not_of' called with a
  // CHECK-FIXES: Str.find_first_not_of('a');
  Str.find_last_of("a");
  // CHECK-MESSAGES: [[@LINE-1]]:20: warning: 'find_last_of' called with a string
  // CHECK-FIXES: Str.find_last_of('a');
  Str.find_last_not_of("a");
  // CHECK-MESSAGES: [[@LINE-1]]:24: warning: 'find_last_not_of' called with a
  // CHECK-FIXES: Str.find_last_not_of('a');
  // std::wstring should work.
  std::wstring WStr;
  WStr.find(L"n");
  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'find' called with a string literal
  // CHECK-FIXES: Str.find(L'n');
  // Even with unicode that fits in one wide char.
  WStr.find(L"\x3A9");
  // CHECK-MESSAGES: [[@LINE-1]]:13: warning: 'find' called with a string literal
  // CHECK-FIXES: Str.find(L'\x3A9');
  // Also with other types, but only if it was specified in the options.
  llvm::StringRef sr;
  sr.find("x");
  // CHECK-MESSAGES: [[@LINE-1]]:11: warning: 'find' called with a string literal
  // CHECK-FIXES: sr.find('x');
  NotStringRef nsr;
  nsr.find("x");
}
template <typename T>
int FindTemplateDependant(T value) {
  return value.find("A");
}
template <typename T>
int FindTemplateNotDependant(T pos) {
  return std::string().find("A", pos);
  // CHECK-MESSAGES: [[@LINE-1]]:29: warning: 'find' called with a string literal
  // CHECK-FIXES: return std::string().find('A', pos);
}
int FindStr() {
  return FindTemplateDependant(std::string()) + FindTemplateNotDependant(1);
}
#define STR_MACRO(str) str.find("A")
#define POS_MACRO(pos) std::string().find("A",pos)
int Macros() {
  return STR_MACRO(std::string()) + POS_MACRO(1);
  // CHECK-MESSAGES: [[@LINE-1]]:10: warning: 'find' called with a string literal
  // CHECK-MESSAGES: [[@LINE-2]]:37: warning: 'find' called with a string literal
}
 |