Index: clang-tidy/bugprone/ArgumentCommentCheck.h =================================================================== --- clang-tidy/bugprone/ArgumentCommentCheck.h +++ clang-tidy/bugprone/ArgumentCommentCheck.h @@ -26,7 +26,8 @@ /// /// ... /// f(/*bar=*/true); -/// // warning: argument name 'bar' in comment does not match parameter name 'foo' +/// // warning: argument name 'bar' in comment does not match parameter name +/// 'foo' /// \endcode /// /// The check tries to detect typos and suggest automated fixes for them. @@ -40,6 +41,9 @@ private: const bool StrictMode; + const bool AddCommentsToBoolLiterals; + const bool AddCommentsToIntegerLiterals; + const bool AddCommentsToFloatLiterals; llvm::Regex IdentRE; void checkCallArgs(ASTContext *Ctx, const FunctionDecl *Callee, Index: clang-tidy/bugprone/ArgumentCommentCheck.cpp =================================================================== --- clang-tidy/bugprone/ArgumentCommentCheck.cpp +++ clang-tidy/bugprone/ArgumentCommentCheck.cpp @@ -7,11 +7,11 @@ //===----------------------------------------------------------------------===// #include "ArgumentCommentCheck.h" +#include "../utils/LexerUtils.h" #include "clang/AST/ASTContext.h" #include "clang/ASTMatchers/ASTMatchFinder.h" #include "clang/Lex/Lexer.h" #include "clang/Lex/Token.h" -#include "../utils/LexerUtils.h" using namespace clang::ast_matchers; @@ -23,10 +23,20 @@ ClangTidyContext *Context) : ClangTidyCheck(Name, Context), StrictMode(Options.getLocalOrGlobal("StrictMode", 0) != 0), + AddCommentsToBoolLiterals( + Options.getLocalOrGlobal("AddCommentsToBoolLiterals", 0) != 0), + AddCommentsToIntegerLiterals( + Options.getLocalOrGlobal("AddCommentsToIntegerLiterals", 0) != 0), + AddCommentsToFloatLiterals( + Options.getLocalOrGlobal("AddCommentsToFloatLiterals", 0) != 0), IdentRE("^(/\\* *)([_A-Za-z][_A-Za-z0-9]*)( *= *\\*/)$") {} void ArgumentCommentCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { Options.store(Opts, "StrictMode", StrictMode); + Options.store(Opts, "AddCommentsToBoolLiterals", AddCommentsToBoolLiterals); + Options.store(Opts, "AddCommentsToIntegerLiterals", + AddCommentsToIntegerLiterals); + Options.store(Opts, "AddCommentsToFloatLiterals", AddCommentsToFloatLiterals); } void ArgumentCommentCheck::registerMatchers(MatchFinder *Finder) { @@ -180,8 +190,8 @@ } return nullptr; } - if (const auto *Next = dyn_cast_or_null( - Method->getNextDeclInContext())) { + if (const auto *Next = + dyn_cast_or_null(Method->getNextDeclInContext())) { if (looksLikeExpectMethod(Next) && areMockAndExpectMethods(Method, Next)) return Method; } @@ -277,6 +287,23 @@ } } } + + // If the argument comments are missing for literals add them. + if (Comments.empty()) { + if (((isa(Args[I]) && AddCommentsToBoolLiterals) || + (isa(Args[I]) && AddCommentsToIntegerLiterals) || + (isa(Args[I]) && AddCommentsToFloatLiterals))) { + std::string ArgComment = + (llvm::Twine("/*") + II->getName() + "=*/").str(); + DiagnosticBuilder Diag = + diag(Args[I]->getBeginLoc(), + "argument comment missing for literal argument" + " %0") + << II + << FixItHint::CreateInsertion(Args[I]->getBeginLoc(), ArgComment); + continue; + } + } } } Index: docs/ReleaseNotes.rst =================================================================== --- docs/ReleaseNotes.rst +++ docs/ReleaseNotes.rst @@ -79,6 +79,11 @@ Checks for casts of ``absl::Duration`` conversion functions, and recommends the right conversion function instead. +- The :doc:`bugprone-argument-comment + ` now supports + `AddCommentsToBoolLiterals`, `AddCommentsToIntegerLiterals` & + `AddCommentsToFloatLiterals` options. + - New :doc:`google-readability-avoid-underscore-in-googletest-name ` check. Index: docs/clang-tidy/checks/bugprone-argument-comment.rst =================================================================== --- docs/clang-tidy/checks/bugprone-argument-comment.rst +++ docs/clang-tidy/checks/bugprone-argument-comment.rst @@ -27,3 +27,66 @@ When zero (default value), the check will ignore leading and trailing underscores and case when comparing names -- otherwise they are taken into account. + +.. option:: AddCommentsToBoolLiterals + + When true, the check will add argument comments in the format + ``/*parameter_name=*/`` right before the boolean literal argument. + +Before: + +.. code-block:: c++ + + void foo(bool turn_key,bool press_button); + + foo(true,false); + +After: + +.. code-block:: c++ + + void foo(bool turn_key,bool press_button); + + foo(/*turn_key=*/true,/*press_button*/false); + +.. option:: AddCommentsToIntegerLiterals + + When true, the check will add argument comments in the format + ``/*parameter_name=*/`` right before the integer literal argument. + +Before: + +.. code-block:: c++ + + void foo(int meaning_of_life); + + foo(42); + +After: + +.. code-block:: c++ + + void foo(int meaning_of_life); + + foo(/*meaning_of_life=*/42); + +.. option:: AddCommentsToFloatLiterals + + When true, the check will add argument comments in the format + ``/*parameter_name=*/`` right before the float/double literal argument. + +Before: + +.. code-block:: c++ + + void foo(float pi); + + foo(3.14159); + +After: + +.. code-block:: c++ + + void foo(float pi); + + foo(/*pi=*/3.14159); Index: test/clang-tidy/bugprone-argument-comment-literals.cpp =================================================================== --- /dev/null +++ test/clang-tidy/bugprone-argument-comment-literals.cpp @@ -0,0 +1,81 @@ +// RUN: %check_clang_tidy %s bugprone-argument-comment %t -- \ +// RUN: -config="{CheckOptions: [{key: AddCommentsToBoolLiterals, value: 1},{key: AddCommentsToIntegerLiterals, value: 1},{key: AddCommentsToFloatLiterals, value: 1}]}" -- + +struct A { + void foo(bool abc); + void foo(bool abc, bool cde); + void foo(const char *, bool abc); + void foo(int iabc); + void foo(float fabc); + void foo(double dabc); +}; + +void test() { + A a; + + a.foo(true); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/true); + + a.foo(false); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/false); + + a.foo(true, false); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-MESSAGES: [[@LINE-2]]:15: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/true, /*cde=*/false); + + a.foo(false, true); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-MESSAGES: [[@LINE-2]]:16: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true); + + a.foo(/*abc=*/false, true); + // CHECK-MESSAGES: [[@LINE-1]]:24: warning: argument comment missing for literal argument 'cde' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true); + + a.foo(false, /*cde=*/true); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*abc=*/false, /*cde=*/true); + + bool val1 = true; + bool val2 = false; + a.foo(val1, val2); + + a.foo("", true); + // CHECK-MESSAGES: [[@LINE-1]]:13: warning: argument comment missing for literal argument 'abc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo("", /*abc=*/true); + + a.foo(0); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'iabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*iabc=*/0); + + a.foo(1.0f); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'fabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*fabc=*/1.0f); + + a.foo(1.0); + // CHECK-MESSAGES: [[@LINE-1]]:9: warning: argument comment missing for literal argument 'dabc' [bugprone-argument-comment] + // CHECK-FIXES: a.foo(/*dabc=*/1.0); + + int val3 = 10; + a.foo(val3); + + float val4 = 10.0; + a.foo(val4); + + double val5 = 10.0; + a.foo(val5); +} + +void f(bool _with_underscores_); +void ignores_underscores() { + f(false); + // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument '_with_underscores_' [bugprone-argument-comment] + // CHECK-FIXES: f(/*_with_underscores_=*/false); + + f(true); + // CHECK-MESSAGES: [[@LINE-1]]:5: warning: argument comment missing for literal argument + // CHECK-FIXES: f(/*_with_underscores_=*/true); +}