diff --git a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp --- a/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp +++ b/clang-tools-extra/clang-tidy/readability/IdentifierNamingCheck.cpp @@ -324,6 +324,43 @@ return Fixup; } +static bool isParamInMainLikeFunction(const ParmVarDecl &ParmDecl) { + auto IsCharPtrPtr = [](QualType QType) { + if (QType.isNull()) + return false; + if (QType = QType->getPointeeType(), QType.isNull()) + return false; + if (QType = QType->getPointeeType(), QType.isNull()) + return false; + return QType->isCharType(); + }; + auto IsIntType = [](QualType QType) { + if (QType.isNull()) + return false; + if (const auto *Builtin = + dyn_cast(QType->getUnqualifiedDesugaredType())) { + return Builtin->getKind() == BuiltinType::Int; + } + return false; + }; + const auto *FDecl = + dyn_cast_or_null(ParmDecl.getParentFunctionOrMethod()); + if (!FDecl) + return false; + if (!IsIntType(FDecl->getReturnType())) + return false; + if (FDecl->getNumParams() < 2 || FDecl->getNumParams() > 3) + return false; + if (!IsIntType(FDecl->parameters()[0]->getType())) + return false; + if (!IsCharPtrPtr(FDecl->parameters()[1]->getType())) + return false; + if (FDecl->getNumParams() == 3 && + !IsCharPtrPtr(FDecl->parameters()[2]->getType())) + return false; + return true; +} + static std::string fixupWithStyle(StringRef Name, const IdentifierNamingCheck::NamingStyle &Style) { @@ -434,6 +471,8 @@ } if (const auto *Decl = dyn_cast(D)) { + if (isParamInMainLikeFunction(*Decl)) + return SK_Invalid; QualType Type = Decl->getType(); if (Decl->isConstexpr() && NamingStyles[SK_ConstexprVariable]) diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp new file mode 100644 --- /dev/null +++ b/clang-tools-extra/test/clang-tidy/checkers/readability-identifier-naming-main-like.cpp @@ -0,0 +1,51 @@ +// RUN: %check_clang_tidy %s readability-identifier-naming %t -- \ +// RUN: -config='{CheckOptions: [ \ +// RUN: {key: readability-identifier-naming.ParameterCase, value: CamelCase} \ +// RUN: ]}' + +int mainLike(int argc, char **argv); +int mainLike(int argc, char **argv, const char **env); +int mainLike(int argc, const char **argv); +int mainLike(int argc, const char **argv, const char **env); +int mainLike(int argc, char *argv[]); +int mainLike(int argc, const char *argv[]); +int mainLike(int argc, char *argv[], char *env[]); +int mainLike(int argc, const char *argv[], const char *env[]); +void notMain(int argc, char **argv); +// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc' +// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv' +void notMain(int argc, char **argv, char **env); +// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc' +// CHECK-MESSAGES: :[[@LINE-2]]:31: warning: invalid case style for parameter 'argv' +// CHECK-MESSAGES: :[[@LINE-3]]:44: warning: invalid case style for parameter 'env' +int notMain(int argc, char **argv, char **env, int Extra); +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc' +// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv' +// CHECK-MESSAGES: :[[@LINE-3]]:43: warning: invalid case style for parameter 'env' +int notMain(int argc, char **argv, int Extra); +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc' +// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv' +int notMain(int argc, char *argv); +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc' +// CHECK-MESSAGES: :[[@LINE-2]]:29: warning: invalid case style for parameter 'argv' +int notMain(unsigned argc, char **argv); +// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: invalid case style for parameter 'argc' +// CHECK-MESSAGES: :[[@LINE-2]]:35: warning: invalid case style for parameter 'argv' +int notMain(long argc, char *argv); +// CHECK-MESSAGES: :[[@LINE-1]]:18: warning: invalid case style for parameter 'argc' +// CHECK-MESSAGES: :[[@LINE-2]]:30: warning: invalid case style for parameter 'argv' +int notMain(int argc, char16_t **argv); +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc' +// CHECK-MESSAGES: :[[@LINE-2]]:34: warning: invalid case style for parameter 'argv' +int notMain(int argc, char argv[]); +// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: invalid case style for parameter 'argc' +// CHECK-MESSAGES: :[[@LINE-2]]:28: warning: invalid case style for parameter 'argv' +typedef char myFunChar; +typedef int myFunInt; +typedef char **myFunCharPtr; +typedef long myFunLong; +myFunInt mainLikeTypedef(myFunInt argc, myFunChar **argv); +int mainLikeTypedef(int argc, myFunCharPtr argv); +int notMainTypedef(myFunLong argc, char **argv); +// CHECK-MESSAGES: :[[@LINE-1]]:30: warning: invalid case style for parameter 'argc' +// CHECK-MESSAGES: :[[@LINE-2]]:43: warning: invalid case style for parameter 'argv'