10#include "clang/ASTMatchers/ASTMatchFinder.h"
11#include "llvm/Support/Regex.h"
19std::string validFunctionNameRegex(
bool RequirePrefix) {
38 std::string FunctionNameMatcher =
39 std::string(RequirePrefix ?
"[A-Z][A-Z0-9]+" :
"") +
"[A-Z][a-zA-Z0-9]*";
40 return std::string(
"::(") + FunctionNameMatcher +
")$";
46FixItHint generateFixItHint(
const FunctionDecl *Decl) {
50 if (Decl->getStorageClass() != SC_Static)
53 StringRef Name = Decl->getName();
54 std::string NewName = Decl->getName().str();
57 bool AtWordBoundary =
true;
58 while (Index < NewName.size()) {
59 char Ch = NewName[Index];
63 NewName[Index] = toupper(NewName[Index]);
64 AtWordBoundary =
false;
71 NewName.erase(Index, 1);
72 AtWordBoundary =
true;
78 return FixItHint::CreateReplacement(
79 CharSourceRange::getTokenRange(SourceRange(Decl->getLocation())),
80 llvm::StringRef(NewName));
96 unless(anyOf(isExpansionInSystemHeader(), cxxMethodDecl(),
97 hasAncestor(namespaceDecl()), isMain(), isImplicit(),
98 matchesName(validFunctionNameRegex(
true)),
99 allOf(isStaticStorageClass(),
100 matchesName(validFunctionNameRegex(
false))))))
106 const auto *MatchedDecl = Result.Nodes.getNodeAs<FunctionDecl>(
"function");
108 bool IsGlobal = MatchedDecl->getStorageClass() != SC_Static;
109 diag(MatchedDecl->getLocation(),
110 "%select{static function|function in global namespace}1 named %0 must "
111 "%select{be in|have an appropriate prefix followed by}1 Pascal case as "
112 "required by Google Objective-C style guide")
113 << MatchedDecl << IsGlobal << generateFixItHint(MatchedDecl);
void registerMatchers(ast_matchers::MatchFinder *Finder) override
void check(const ast_matchers::MatchFinder::MatchResult &Result) override