summaryrefslogtreecommitdiffstats
path: root/clang-tidy/bugprone/ArgumentCommentCheck.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang-tidy/bugprone/ArgumentCommentCheck.cpp')
-rw-r--r--clang-tidy/bugprone/ArgumentCommentCheck.cpp74
1 files changed, 60 insertions, 14 deletions
diff --git a/clang-tidy/bugprone/ArgumentCommentCheck.cpp b/clang-tidy/bugprone/ArgumentCommentCheck.cpp
index 62f30f79..5d6c7c9a 100644
--- a/clang-tidy/bugprone/ArgumentCommentCheck.cpp
+++ b/clang-tidy/bugprone/ArgumentCommentCheck.cpp
@@ -1,9 +1,8 @@
//===--- ArgumentCommentCheck.cpp - clang-tidy ----------------------------===//
//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
@@ -12,6 +11,7 @@
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Token.h"
+
#include "../utils/LexerUtils.h"
using namespace clang::ast_matchers;
@@ -24,17 +24,37 @@ ArgumentCommentCheck::ArgumentCommentCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
StrictMode(Options.getLocalOrGlobal("StrictMode", 0) != 0),
+ CommentBoolLiterals(Options.getLocalOrGlobal("CommentBoolLiterals", 0) !=
+ 0),
+ CommentIntegerLiterals(
+ Options.getLocalOrGlobal("CommentIntegerLiterals", 0) != 0),
+ CommentFloatLiterals(
+ Options.getLocalOrGlobal("CommentFloatLiterals", 0) != 0),
+ CommentStringLiterals(
+ Options.getLocalOrGlobal("CommentStringLiterals", 0) != 0),
+ CommentUserDefinedLiterals(
+ Options.getLocalOrGlobal("CommentUserDefinedLiterals", 0) != 0),
+ CommentCharacterLiterals(
+ Options.getLocalOrGlobal("CommentCharacterLiterals", 0) != 0),
+ CommentNullPtrs(Options.getLocalOrGlobal("CommentNullPtrs", 0) != 0),
IdentRE("^(/\\* *)([_A-Za-z][_A-Za-z0-9]*)( *= *\\*/)$") {}
void ArgumentCommentCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
Options.store(Opts, "StrictMode", StrictMode);
+ Options.store(Opts, "CommentBoolLiterals", CommentBoolLiterals);
+ Options.store(Opts, "CommentIntegerLiterals", CommentIntegerLiterals);
+ Options.store(Opts, "CommentFloatLiterals", CommentFloatLiterals);
+ Options.store(Opts, "CommentStringLiterals", CommentStringLiterals);
+ Options.store(Opts, "CommentUserDefinedLiterals", CommentUserDefinedLiterals);
+ Options.store(Opts, "CommentCharacterLiterals", CommentCharacterLiterals);
+ Options.store(Opts, "CommentNullPtrs", CommentNullPtrs);
}
void ArgumentCommentCheck::registerMatchers(MatchFinder *Finder) {
Finder->addMatcher(
callExpr(unless(cxxOperatorCallExpr()),
- // NewCallback's arguments relate to the pointed function, don't
- // check them against NewCallback's parameter names.
+ // NewCallback's arguments relate to the pointed function,
+ // don't check them against NewCallback's parameter names.
// FIXME: Make this configurable.
unless(hasDeclaration(functionDecl(
hasAnyName("NewCallback", "NewPermanentCallback")))))
@@ -127,8 +147,8 @@ static bool isLikelyTypo(llvm::ArrayRef<ParmVarDecl *> Params,
const unsigned Threshold = 2;
// Other parameters must be an edit distance at least Threshold more away
- // from this parameter. This gives us greater confidence that this is a typo
- // of this parameter and not one with a similar name.
+ // from this parameter. This gives us greater confidence that this is a
+ // typo of this parameter and not one with a similar name.
unsigned OtherED = ArgNameLower.edit_distance(II->getName().lower(),
/*AllowReplacements=*/true,
ThisED + Threshold);
@@ -181,8 +201,8 @@ static const CXXMethodDecl *findMockedMethod(const CXXMethodDecl *Method) {
}
return nullptr;
}
- if (const auto *Next = dyn_cast_or_null<CXXMethodDecl>(
- Method->getNextDeclInContext())) {
+ if (const auto *Next =
+ dyn_cast_or_null<CXXMethodDecl>(Method->getNextDeclInContext())) {
if (looksLikeExpectMethod(Next) && areMockAndExpectMethods(Method, Next))
return Method;
}
@@ -207,6 +227,21 @@ static const FunctionDecl *resolveMocks(const FunctionDecl *Func) {
return Func;
}
+// Given the argument type and the options determine if we should
+// be adding an argument comment.
+bool ArgumentCommentCheck::shouldAddComment(const Expr *Arg) const {
+ if (Arg->getExprLoc().isMacroID())
+ return false;
+ Arg = Arg->IgnoreImpCasts();
+ return (CommentBoolLiterals && isa<CXXBoolLiteralExpr>(Arg)) ||
+ (CommentIntegerLiterals && isa<IntegerLiteral>(Arg)) ||
+ (CommentFloatLiterals && isa<FloatingLiteral>(Arg)) ||
+ (CommentUserDefinedLiterals && isa<UserDefinedLiteral>(Arg)) ||
+ (CommentCharacterLiterals && isa<CharacterLiteral>(Arg)) ||
+ (CommentStringLiterals && isa<StringLiteral>(Arg)) ||
+ (CommentNullPtrs && isa<CXXNullPtrLiteralExpr>(Arg));
+}
+
void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx,
const FunctionDecl *OriginalCallee,
SourceLocation ArgBeginLoc,
@@ -220,7 +255,7 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx,
if (NumArgs == 0)
return;
- auto makeFileCharRange = [Ctx](SourceLocation Begin, SourceLocation End) {
+ auto MakeFileCharRange = [Ctx](SourceLocation Begin, SourceLocation End) {
return Lexer::makeFileCharRange(CharSourceRange::getCharRange(Begin, End),
Ctx->getSourceManager(),
Ctx->getLangOpts());
@@ -243,7 +278,7 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx,
}
CharSourceRange BeforeArgument =
- makeFileCharRange(ArgBeginLoc, Args[I]->getBeginLoc());
+ MakeFileCharRange(ArgBeginLoc, Args[I]->getBeginLoc());
ArgBeginLoc = Args[I]->getEndLoc();
std::vector<std::pair<SourceLocation, StringRef>> Comments;
@@ -251,7 +286,7 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx,
Comments = getCommentsInRange(Ctx, BeforeArgument);
} else {
// Fall back to parsing back from the start of the argument.
- CharSourceRange ArgsRange = makeFileCharRange(
+ CharSourceRange ArgsRange = MakeFileCharRange(
Args[I]->getBeginLoc(), Args[NumArgs - 1]->getEndLoc());
Comments = getCommentsBeforeLoc(Ctx, ArgsRange.getBegin());
}
@@ -278,8 +313,19 @@ void ArgumentCommentCheck::checkCallArgs(ASTContext *Ctx,
}
}
}
+
+ // If the argument comments are missing for literals add them.
+ if (Comments.empty() && shouldAddComment(Args[I])) {
+ 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);
+ }
}
-}
+} // namespace bugprone
void ArgumentCommentCheck::check(const MatchFinder::MatchResult &Result) {
const auto *E = Result.Nodes.getNodeAs<Expr>("expr");