[clang-tools-extra] [clang-tidy] Replace /* ... */ single-line comments with // ... comments (PR #124319)
via cfe-commits
cfe-commits at lists.llvm.org
Sun Feb 2 04:20:36 PST 2025
https://github.com/4m4n-x-B4w4ne updated https://github.com/llvm/llvm-project/pull/124319
>From 581cc0eda9d42458ff71f2c913a2e03d2de0b5f2 Mon Sep 17 00:00:00 2001
From: NagaChaitanya Vellanki <pnagato at protonmail.com>
Date: Fri, 19 Jul 2024 14:26:23 -0700
Subject: [PATCH 01/14] This commit is to resolve the issue #24841
---
.../clang-tidy/modernize/CMakeLists.txt | 1 +
.../modernize/ModernizeTidyModule.cpp | 3 +
.../modernize/UseCppStyleCommentsCheck.cpp | 126 ++++++
.../modernize/UseCppStyleCommentsCheck.h | 40 ++
.../ImplicitBoolConversionCheck.cpp | 428 ------------------
.../readability/ImplicitBoolConversionCheck.h | 44 --
clang-tools-extra/docs/ReleaseNotes.rst | 79 +++-
.../modernize/use-cpp-style-comments.rst | 38 ++
.../modernize/use-cpp-style-comments.cpp | 68 +++
9 files changed, 337 insertions(+), 490 deletions(-)
create mode 100644 clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.h
delete mode 100644 clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
delete mode 100644 clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
create mode 100644 clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
create mode 100644 clang-tools-extra/test/clang-tidy/checkers/modernize/use-cpp-style-comments.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index bab1167fb15ff2..f07dd5efecc58e 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -31,6 +31,7 @@ add_clang_library(clangTidyModernizeModule STATIC
UseAutoCheck.cpp
UseBoolLiteralsCheck.cpp
UseConstraintsCheck.cpp
+ UseCppStyleCommentsCheck.cpp
UseDefaultMemberInitCheck.cpp
UseDesignatedInitializersCheck.cpp
UseEmplaceCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index fc46c72982fdce..1917d562f7ce8d 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -32,6 +32,7 @@
#include "UseAutoCheck.h"
#include "UseBoolLiteralsCheck.h"
#include "UseConstraintsCheck.h"
+#include "UseCppStyleCommentsCheck.h"
#include "UseDefaultMemberInitCheck.h"
#include "UseDesignatedInitializersCheck.h"
#include "UseEmplaceCheck.h"
@@ -107,6 +108,8 @@ class ModernizeModule : public ClangTidyModule {
"modernize-use-bool-literals");
CheckFactories.registerCheck<UseConstraintsCheck>(
"modernize-use-constraints");
+ CheckFactories.registerCheck<UseCppStyleCommentsCheck>(
+ "modernize-use-cpp-style-comments");
CheckFactories.registerCheck<UseDefaultMemberInitCheck>(
"modernize-use-default-member-init");
CheckFactories.registerCheck<UseEmplaceCheck>("modernize-use-emplace");
diff --git a/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp
new file mode 100644
index 00000000000000..3c25c50bab759c
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp
@@ -0,0 +1,126 @@
+//===--- UseCppStyleCommentsCheck.cpp - clang-tidy-------------------------===//
+
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "UseCppStyleCommentsCheck.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/Preprocessor.h"
+#include <iostream>
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::modernize {
+class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
+public:
+ CStyleCommentHandler(UseCppStyleCommentsCheck &Check)
+ : Check(Check),
+ CStyleCommentMatch(
+ "^[ \t]*/\\*+[ \t\r\n]*(.*[ \t\r\n]*)*[ \t\r\n]*\\*+/[ \t\r\n]*$"){}
+
+ std::string convertToCppStyleComment(const SourceManager &SM, const SourceRange &Range) {
+ StringRef CommentText = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(Range), SM, LangOptions());
+
+ std::string InnerText = CommentText.str();
+ InnerText.erase(0, 2);
+ InnerText.erase(InnerText.size() - 2, 2);
+
+ std::string Result;
+ std::istringstream Stream(InnerText);
+ std::string Line;
+
+ if (std::getline(Stream, Line)) {
+ size_t startPos = Line.find_first_not_of(" \t");
+ if (startPos != std::string::npos) {
+ Line = Line.substr(startPos);
+ } else {
+ Line.clear();
+ }
+ Result += "// " + Line;
+ }
+
+ while (std::getline(Stream, Line)) {
+ size_t startPos = Line.find_first_not_of(" \t");
+ if (startPos != std::string::npos) {
+ Line = Line.substr(startPos);
+ } else {
+ Line.clear();
+ }
+ Result += "\n// " + Line;
+ }
+ return Result;
+ }
+
+ bool HandleComment(Preprocessor &PP, SourceRange Range) override {
+ const SourceManager &SM = PP.getSourceManager();
+
+ if (Range.getBegin().isMacroID() ||
+ SM.isInSystemHeader(Range.getBegin())) {
+ return false;
+ }
+
+ const StringRef Text =
+ Lexer::getSourceText(CharSourceRange::getCharRange(Range),
+ SM, PP.getLangOpts());
+
+ SmallVector<StringRef> Matches;
+ if (!CStyleCommentMatch.match(Text, &Matches)) {
+ return false;
+ }
+
+ SourceLocation CommentStart = Range.getBegin();
+ SourceLocation CommentEnd = Range.getEnd();
+
+ unsigned StartLine = SM.getSpellingLineNumber(CommentStart);
+ unsigned EndLine = SM.getSpellingLineNumber(CommentEnd);
+
+
+ if (StartLine == EndLine) {
+ SourceLocation LineBegin = SM.translateLineCol(
+ SM.getFileID(CommentStart), StartLine, 1);
+ SourceLocation LineEnd = SM.translateLineCol(SM.getFileID(CommentEnd), EndLine, std::numeric_limits<unsigned>::max());
+ StringRef LineContent =
+ Lexer::getSourceText(CharSourceRange::getCharRange(LineBegin, LineEnd),
+ SM, PP.getLangOpts());
+ size_t CommentStartOffset = SM.getSpellingColumnNumber(CommentStart) - 1;
+ StringRef AfterComment = LineContent.drop_front(CommentStartOffset + Text.size());
+
+ if (!AfterComment.trim().empty()) {
+ return false;
+ }
+ }
+
+ Check.diag(
+ Range.getBegin(),
+ "use C++ style comments '//' instead of C style comments '/*...*/'")
+ << clang::FixItHint::CreateReplacement(
+ Range, convertToCppStyleComment(SM, Range));
+
+ return false;
+}
+
+
+private:
+ UseCppStyleCommentsCheck &Check;
+ llvm::Regex CStyleCommentMatch;
+};
+
+UseCppStyleCommentsCheck::UseCppStyleCommentsCheck(StringRef Name,
+ ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ Handler(std::make_unique<CStyleCommentHandler>(*this)) {}
+
+void UseCppStyleCommentsCheck::registerPPCallbacks(
+ const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+ PP->addCommentHandler(Handler.get());
+}
+
+void UseCppStyleCommentsCheck::check(const MatchFinder::MatchResult &Result) {}
+
+UseCppStyleCommentsCheck::~UseCppStyleCommentsCheck() = default;
+} // namespace clang::tidy::modernize
diff --git a/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.h b/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.h
new file mode 100644
index 00000000000000..3d604683de5a24
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.h
@@ -0,0 +1,40 @@
+//===--- UseCppStyleCommentsCheck.h - clang-tidy---------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_CPP_STYLE_COMMENTS_CHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_CPP_STYLE_COMMENTS_CHECK_H
+
+#include "../ClangTidyCheck.h"
+#include <sstream>
+namespace clang::tidy::modernize {
+/// Detects C Style comments and suggests to use C++ style comments instead.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-cpp-style-comments.html
+class UseCppStyleCommentsCheck : public ClangTidyCheck {
+public:
+ UseCppStyleCommentsCheck(StringRef Name, ClangTidyContext *Context);
+
+ ~UseCppStyleCommentsCheck() override;
+
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus;
+ }
+
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+ class CStyleCommentHandler;
+ std::unique_ptr<CStyleCommentHandler> Handler;
+};
+} // namespace clang::tidy::modernize
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_CPP_STYLE_COMMENTS_CHECK_H
diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
deleted file mode 100644
index f9fd1d903e231e..00000000000000
--- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
+++ /dev/null
@@ -1,428 +0,0 @@
-//===--- ImplicitBoolConversionCheck.cpp - clang-tidy----------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "ImplicitBoolConversionCheck.h"
-#include "../utils/FixItHintUtils.h"
-#include "clang/AST/ASTContext.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/ASTMatchers/ASTMatchers.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Tooling/FixIt.h"
-#include <queue>
-
-using namespace clang::ast_matchers;
-
-namespace clang::tidy::readability {
-
-namespace {
-
-AST_MATCHER(Stmt, isMacroExpansion) {
- SourceManager &SM = Finder->getASTContext().getSourceManager();
- SourceLocation Loc = Node.getBeginLoc();
- return SM.isMacroBodyExpansion(Loc) || SM.isMacroArgExpansion(Loc);
-}
-
-AST_MATCHER(Stmt, isC23) { return Finder->getASTContext().getLangOpts().C23; }
-
-bool isNULLMacroExpansion(const Stmt *Statement, ASTContext &Context) {
- SourceManager &SM = Context.getSourceManager();
- const LangOptions &LO = Context.getLangOpts();
- SourceLocation Loc = Statement->getBeginLoc();
- return SM.isMacroBodyExpansion(Loc) &&
- Lexer::getImmediateMacroName(Loc, SM, LO) == "NULL";
-}
-
-AST_MATCHER(Stmt, isNULLMacroExpansion) {
- return isNULLMacroExpansion(&Node, Finder->getASTContext());
-}
-
-StringRef getZeroLiteralToCompareWithForType(CastKind CastExprKind,
- QualType Type,
- ASTContext &Context) {
- switch (CastExprKind) {
- case CK_IntegralToBoolean:
- return Type->isUnsignedIntegerType() ? "0u" : "0";
-
- case CK_FloatingToBoolean:
- return Context.hasSameType(Type, Context.FloatTy) ? "0.0f" : "0.0";
-
- case CK_PointerToBoolean:
- case CK_MemberPointerToBoolean: // Fall-through on purpose.
- return (Context.getLangOpts().CPlusPlus11 || Context.getLangOpts().C23)
- ? "nullptr"
- : "0";
-
- default:
- llvm_unreachable("Unexpected cast kind");
- }
-}
-
-bool isUnaryLogicalNotOperator(const Stmt *Statement) {
- const auto *UnaryOperatorExpr = dyn_cast<UnaryOperator>(Statement);
- return UnaryOperatorExpr && UnaryOperatorExpr->getOpcode() == UO_LNot;
-}
-
-void fixGenericExprCastToBool(DiagnosticBuilder &Diag,
- const ImplicitCastExpr *Cast, const Stmt *Parent,
- ASTContext &Context,
- bool UseUpperCaseLiteralSuffix) {
- // In case of expressions like (! integer), we should remove the redundant not
- // operator and use inverted comparison (integer == 0).
- bool InvertComparison =
- Parent != nullptr && isUnaryLogicalNotOperator(Parent);
- if (InvertComparison) {
- SourceLocation ParentStartLoc = Parent->getBeginLoc();
- SourceLocation ParentEndLoc =
- cast<UnaryOperator>(Parent)->getSubExpr()->getBeginLoc();
- Diag << FixItHint::CreateRemoval(
- CharSourceRange::getCharRange(ParentStartLoc, ParentEndLoc));
-
- Parent = Context.getParents(*Parent)[0].get<Stmt>();
- }
-
- const Expr *SubExpr = Cast->getSubExpr();
-
- bool NeedInnerParens = utils::fixit::areParensNeededForStatement(*SubExpr);
- bool NeedOuterParens =
- Parent != nullptr && utils::fixit::areParensNeededForStatement(*Parent);
-
- std::string StartLocInsertion;
-
- if (NeedOuterParens) {
- StartLocInsertion += "(";
- }
- if (NeedInnerParens) {
- StartLocInsertion += "(";
- }
-
- if (!StartLocInsertion.empty()) {
- Diag << FixItHint::CreateInsertion(Cast->getBeginLoc(), StartLocInsertion);
- }
-
- std::string EndLocInsertion;
-
- if (NeedInnerParens) {
- EndLocInsertion += ")";
- }
-
- if (InvertComparison) {
- EndLocInsertion += " == ";
- } else {
- EndLocInsertion += " != ";
- }
-
- const StringRef ZeroLiteral = getZeroLiteralToCompareWithForType(
- Cast->getCastKind(), SubExpr->getType(), Context);
-
- if (UseUpperCaseLiteralSuffix)
- EndLocInsertion += ZeroLiteral.upper();
- else
- EndLocInsertion += ZeroLiteral;
-
- if (NeedOuterParens) {
- EndLocInsertion += ")";
- }
-
- SourceLocation EndLoc = Lexer::getLocForEndOfToken(
- Cast->getEndLoc(), 0, Context.getSourceManager(), Context.getLangOpts());
- Diag << FixItHint::CreateInsertion(EndLoc, EndLocInsertion);
-}
-
-StringRef getEquivalentBoolLiteralForExpr(const Expr *Expression,
- ASTContext &Context) {
- if (isNULLMacroExpansion(Expression, Context)) {
- return "false";
- }
-
- if (const auto *IntLit =
- dyn_cast<IntegerLiteral>(Expression->IgnoreParens())) {
- return (IntLit->getValue() == 0) ? "false" : "true";
- }
-
- if (const auto *FloatLit = dyn_cast<FloatingLiteral>(Expression)) {
- llvm::APFloat FloatLitAbsValue = FloatLit->getValue();
- FloatLitAbsValue.clearSign();
- return (FloatLitAbsValue.bitcastToAPInt() == 0) ? "false" : "true";
- }
-
- if (const auto *CharLit = dyn_cast<CharacterLiteral>(Expression)) {
- return (CharLit->getValue() == 0) ? "false" : "true";
- }
-
- if (isa<StringLiteral>(Expression->IgnoreCasts())) {
- return "true";
- }
-
- return {};
-}
-
-bool needsSpacePrefix(SourceLocation Loc, ASTContext &Context) {
- SourceRange PrefixRange(Loc.getLocWithOffset(-1), Loc);
- StringRef SpaceBeforeStmtStr = Lexer::getSourceText(
- CharSourceRange::getCharRange(PrefixRange), Context.getSourceManager(),
- Context.getLangOpts(), nullptr);
- if (SpaceBeforeStmtStr.empty())
- return true;
-
- const StringRef AllowedCharacters(" \t\n\v\f\r(){}[]<>;,+=-|&~!^*/");
- return !AllowedCharacters.contains(SpaceBeforeStmtStr.back());
-}
-
-void fixGenericExprCastFromBool(DiagnosticBuilder &Diag,
- const ImplicitCastExpr *Cast,
- ASTContext &Context, StringRef OtherType) {
- if (!Context.getLangOpts().CPlusPlus) {
- Diag << FixItHint::CreateInsertion(Cast->getBeginLoc(),
- (Twine("(") + OtherType + ")").str());
- return;
- }
-
- const Expr *SubExpr = Cast->getSubExpr();
- const bool NeedParens = !isa<ParenExpr>(SubExpr->IgnoreImplicit());
- const bool NeedSpace = needsSpacePrefix(Cast->getBeginLoc(), Context);
-
- Diag << FixItHint::CreateInsertion(
- Cast->getBeginLoc(), (Twine() + (NeedSpace ? " " : "") + "static_cast<" +
- OtherType + ">" + (NeedParens ? "(" : ""))
- .str());
-
- if (NeedParens) {
- SourceLocation EndLoc = Lexer::getLocForEndOfToken(
- Cast->getEndLoc(), 0, Context.getSourceManager(),
- Context.getLangOpts());
-
- Diag << FixItHint::CreateInsertion(EndLoc, ")");
- }
-}
-
-StringRef getEquivalentForBoolLiteral(const CXXBoolLiteralExpr *BoolLiteral,
- QualType DestType, ASTContext &Context) {
- // Prior to C++11, false literal could be implicitly converted to pointer.
- if (!Context.getLangOpts().CPlusPlus11 &&
- (DestType->isPointerType() || DestType->isMemberPointerType()) &&
- BoolLiteral->getValue() == false) {
- return "0";
- }
-
- if (DestType->isFloatingType()) {
- if (Context.hasSameType(DestType, Context.FloatTy)) {
- return BoolLiteral->getValue() ? "1.0f" : "0.0f";
- }
- return BoolLiteral->getValue() ? "1.0" : "0.0";
- }
-
- if (DestType->isUnsignedIntegerType()) {
- return BoolLiteral->getValue() ? "1u" : "0u";
- }
- return BoolLiteral->getValue() ? "1" : "0";
-}
-
-bool isCastAllowedInCondition(const ImplicitCastExpr *Cast,
- ASTContext &Context) {
- std::queue<const Stmt *> Q;
- Q.push(Cast);
-
- TraversalKindScope RAII(Context, TK_AsIs);
-
- while (!Q.empty()) {
- for (const auto &N : Context.getParents(*Q.front())) {
- const Stmt *S = N.get<Stmt>();
- if (!S)
- return false;
- if (isa<IfStmt>(S) || isa<ConditionalOperator>(S) || isa<ForStmt>(S) ||
- isa<WhileStmt>(S) || isa<DoStmt>(S) ||
- isa<BinaryConditionalOperator>(S))
- return true;
- if (isa<ParenExpr>(S) || isa<ImplicitCastExpr>(S) ||
- isUnaryLogicalNotOperator(S) ||
- (isa<BinaryOperator>(S) && cast<BinaryOperator>(S)->isLogicalOp())) {
- Q.push(S);
- } else {
- return false;
- }
- }
- Q.pop();
- }
- return false;
-}
-
-} // anonymous namespace
-
-ImplicitBoolConversionCheck::ImplicitBoolConversionCheck(
- StringRef Name, ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context),
- AllowIntegerConditions(Options.get("AllowIntegerConditions", false)),
- AllowPointerConditions(Options.get("AllowPointerConditions", false)),
- UseUpperCaseLiteralSuffix(
- Options.get("UseUpperCaseLiteralSuffix", false)) {}
-
-void ImplicitBoolConversionCheck::storeOptions(
- ClangTidyOptions::OptionMap &Opts) {
- Options.store(Opts, "AllowIntegerConditions", AllowIntegerConditions);
- Options.store(Opts, "AllowPointerConditions", AllowPointerConditions);
- Options.store(Opts, "UseUpperCaseLiteralSuffix", UseUpperCaseLiteralSuffix);
-}
-
-void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
- auto ExceptionCases =
- expr(anyOf(allOf(isMacroExpansion(), unless(isNULLMacroExpansion())),
- has(ignoringImplicit(
- memberExpr(hasDeclaration(fieldDecl(hasBitWidth(1)))))),
- hasParent(explicitCastExpr()),
- expr(hasType(qualType().bind("type")),
- hasParent(initListExpr(hasParent(explicitCastExpr(
- hasType(qualType(equalsBoundNode("type"))))))))));
- auto ImplicitCastFromBool = implicitCastExpr(
- anyOf(hasCastKind(CK_IntegralCast), hasCastKind(CK_IntegralToFloating),
- // Prior to C++11 cast from bool literal to pointer was allowed.
- allOf(anyOf(hasCastKind(CK_NullToPointer),
- hasCastKind(CK_NullToMemberPointer)),
- hasSourceExpression(cxxBoolLiteral()))),
- hasSourceExpression(expr(hasType(booleanType()))));
- auto BoolXor =
- binaryOperator(hasOperatorName("^"), hasLHS(ImplicitCastFromBool),
- hasRHS(ImplicitCastFromBool));
- auto ComparisonInCall = allOf(
- hasParent(callExpr()),
- hasSourceExpression(binaryOperator(hasAnyOperatorName("==", "!="))));
-
- auto IsInCompilerGeneratedFunction = hasAncestor(namedDecl(anyOf(
- isImplicit(), functionDecl(isDefaulted()), functionTemplateDecl())));
-
- Finder->addMatcher(
- traverse(TK_AsIs,
- implicitCastExpr(
- anyOf(hasCastKind(CK_IntegralToBoolean),
- hasCastKind(CK_FloatingToBoolean),
- hasCastKind(CK_PointerToBoolean),
- hasCastKind(CK_MemberPointerToBoolean)),
- // Exclude cases of C23 comparison result.
- unless(allOf(isC23(),
- hasSourceExpression(ignoringParens(
- binaryOperator(hasAnyOperatorName(
- ">", ">=", "==", "!=", "<", "<=")))))),
- // Exclude case of using if or while statements with variable
- // declaration, e.g.:
- // if (int var = functionCall()) {}
- unless(hasParent(
- stmt(anyOf(ifStmt(), whileStmt()), has(declStmt())))),
- // Exclude cases common to implicit cast to and from bool.
- unless(ExceptionCases), unless(has(BoolXor)),
- // Exclude C23 cases common to implicit cast to bool.
- unless(ComparisonInCall),
- // Retrieve also parent statement, to check if we need
- // additional parens in replacement.
- optionally(hasParent(stmt().bind("parentStmt"))),
- unless(isInTemplateInstantiation()),
- unless(IsInCompilerGeneratedFunction))
- .bind("implicitCastToBool")),
- this);
-
- auto BoolComparison = binaryOperator(hasAnyOperatorName("==", "!="),
- hasLHS(ImplicitCastFromBool),
- hasRHS(ImplicitCastFromBool));
- auto BoolOpAssignment = binaryOperator(hasAnyOperatorName("|=", "&="),
- hasLHS(expr(hasType(booleanType()))));
- auto BitfieldAssignment = binaryOperator(
- hasLHS(memberExpr(hasDeclaration(fieldDecl(hasBitWidth(1))))));
- auto BitfieldConstruct = cxxConstructorDecl(hasDescendant(cxxCtorInitializer(
- withInitializer(equalsBoundNode("implicitCastFromBool")),
- forField(hasBitWidth(1)))));
- Finder->addMatcher(
- traverse(
- TK_AsIs,
- implicitCastExpr(
- ImplicitCastFromBool, unless(ExceptionCases),
- // Exclude comparisons of bools, as they are always cast to
- // integers in such context:
- // bool_expr_a == bool_expr_b
- // bool_expr_a != bool_expr_b
- unless(hasParent(
- binaryOperator(anyOf(BoolComparison, BoolXor,
- BoolOpAssignment, BitfieldAssignment)))),
- implicitCastExpr().bind("implicitCastFromBool"),
- unless(hasParent(BitfieldConstruct)),
- // Check also for nested casts, for example: bool -> int -> float.
- anyOf(hasParent(implicitCastExpr().bind("furtherImplicitCast")),
- anything()),
- unless(isInTemplateInstantiation()),
- unless(IsInCompilerGeneratedFunction))),
- this);
-}
-
-void ImplicitBoolConversionCheck::check(
- const MatchFinder::MatchResult &Result) {
-
- if (const auto *CastToBool =
- Result.Nodes.getNodeAs<ImplicitCastExpr>("implicitCastToBool")) {
- const auto *Parent = Result.Nodes.getNodeAs<Stmt>("parentStmt");
- return handleCastToBool(CastToBool, Parent, *Result.Context);
- }
-
- if (const auto *CastFromBool =
- Result.Nodes.getNodeAs<ImplicitCastExpr>("implicitCastFromBool")) {
- const auto *NextImplicitCast =
- Result.Nodes.getNodeAs<ImplicitCastExpr>("furtherImplicitCast");
- return handleCastFromBool(CastFromBool, NextImplicitCast, *Result.Context);
- }
-}
-
-void ImplicitBoolConversionCheck::handleCastToBool(const ImplicitCastExpr *Cast,
- const Stmt *Parent,
- ASTContext &Context) {
- if (AllowPointerConditions &&
- (Cast->getCastKind() == CK_PointerToBoolean ||
- Cast->getCastKind() == CK_MemberPointerToBoolean) &&
- isCastAllowedInCondition(Cast, Context)) {
- return;
- }
-
- if (AllowIntegerConditions && Cast->getCastKind() == CK_IntegralToBoolean &&
- isCastAllowedInCondition(Cast, Context)) {
- return;
- }
-
- auto Diag = diag(Cast->getBeginLoc(), "implicit conversion %0 -> 'bool'")
- << Cast->getSubExpr()->getType();
-
- StringRef EquivalentLiteral =
- getEquivalentBoolLiteralForExpr(Cast->getSubExpr(), Context);
- if (!EquivalentLiteral.empty()) {
- Diag << tooling::fixit::createReplacement(*Cast, EquivalentLiteral);
- } else {
- fixGenericExprCastToBool(Diag, Cast, Parent, Context,
- UseUpperCaseLiteralSuffix);
- }
-}
-
-void ImplicitBoolConversionCheck::handleCastFromBool(
- const ImplicitCastExpr *Cast, const ImplicitCastExpr *NextImplicitCast,
- ASTContext &Context) {
- QualType DestType =
- NextImplicitCast ? NextImplicitCast->getType() : Cast->getType();
- auto Diag = diag(Cast->getBeginLoc(), "implicit conversion 'bool' -> %0")
- << DestType;
-
- if (const auto *BoolLiteral =
- dyn_cast<CXXBoolLiteralExpr>(Cast->getSubExpr()->IgnoreParens())) {
-
- const auto EquivalentForBoolLiteral =
- getEquivalentForBoolLiteral(BoolLiteral, DestType, Context);
- if (UseUpperCaseLiteralSuffix)
- Diag << tooling::fixit::createReplacement(
- *Cast, EquivalentForBoolLiteral.upper());
- else
- Diag << tooling::fixit::createReplacement(*Cast,
- EquivalentForBoolLiteral);
-
- } else {
- fixGenericExprCastFromBool(Diag, Cast, Context, DestType.getAsString());
- }
-}
-
-} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
deleted file mode 100644
index 5947f7316e67cc..00000000000000
--- a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===--- ImplicitBoolConversionCheck.h - clang-tidy--------------*- C++ -*-===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CONVERSION_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CONVERSION_H
-
-#include "../ClangTidyCheck.h"
-
-namespace clang::tidy::readability {
-
-/// Checks for use of implicit bool conversions in expressions.
-///
-/// For the user-facing documentation see:
-/// http://clang.llvm.org/extra/clang-tidy/checks/readability/implicit-bool-conversion.html
-class ImplicitBoolConversionCheck : public ClangTidyCheck {
-public:
- ImplicitBoolConversionCheck(StringRef Name, ClangTidyContext *Context);
- bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
- return LangOpts.Bool;
- }
- void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
- void registerMatchers(ast_matchers::MatchFinder *Finder) override;
- void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-
-private:
- void handleCastToBool(const ImplicitCastExpr *CastExpression,
- const Stmt *ParentStatement, ASTContext &Context);
- void handleCastFromBool(const ImplicitCastExpr *Cast,
- const ImplicitCastExpr *NextImplicitCast,
- ASTContext &Context);
-
- const bool AllowIntegerConditions;
- const bool AllowPointerConditions;
- const bool UseUpperCaseLiteralSuffix;
-};
-
-} // namespace clang::tidy::readability
-
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CONVERSION_H
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 94e15639c4a92e..a89cd1a8b80e50 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -108,19 +108,23 @@ Improvements to clang-query
Improvements to clang-tidy
--------------------------
-- Improved :program:`clang-tidy`'s `--verify-config` flag by adding support for
- the configuration options of the `Clang Static Analyzer Checks
- <https://clang.llvm.org/docs/analyzer/checkers.html>`_.
+- Improved :program:`clang-tidy-diff.py` script. Add the `-only-check-in-db`
+ option to exclude files not present in the compilation database, avoiding
+ false-negative results.
- Improved :program:`run-clang-tidy.py` script. Fixed minor shutdown noise
happening on certain platforms when interrupting the script.
-- Improved :program:`clang-tidy` by accepting parameters file in command line.
+- Improved :program:`clang-tidy`:
-- Removed :program:`clang-tidy`'s global options for most of checks. All options
- are changed to local options except `IncludeStyle`, `StrictMode` and
- `IgnoreMacros`. Global scoped `StrictMode` and `IgnoreMacros` are deprecated
- and will be removed in further releases.
+ - add support for `--verify-config` flag to check the configuration options of
+ the `Clang Static Analyzer Checks <https://clang.llvm.org/docs/analyzer/checkers.html>`_.
+ - accept parameters file in command line.
+ - fix incorrect configuration file path resolving when file paths contain ``..``.
+ - remove global options for most of checks. All options are changed to local
+ options except `IncludeStyle`, `StrictMode` and `IgnoreMacros`. Global scoped
+ `StrictMode` and `IgnoreMacros` are deprecated and will be removed in further
+ releases.
.. csv-table::
:header: "Check", "Options removed from global option"
@@ -145,6 +149,13 @@ New checks
Warns about code that tries to cast between pointers by means of
``std::bit_cast`` or ``memcpy``.
+- New :doc:`bugprone-incorrect-enable-shared-from-this
+ <clang-tidy/checks/bugprone/incorrect-enable-shared-from-this>` check.
+
+ Detect classes or structs that do not publicly inherit from
+ ``std::enable_shared_from_this``, because unintended behavior will
+ otherwise occur when calling ``shared_from_this``.
+
- New :doc:`bugprone-nondeterministic-pointer-iteration-order
<clang-tidy/checks/bugprone/nondeterministic-pointer-iteration-order>`
check.
@@ -162,6 +173,11 @@ New checks
Replace comparisons between signed and unsigned integers with their safe
C++20 ``std::cmp_*`` alternative, if available.
+
+- New :doc:`modernize-use-cpp-style-comments
+ <clang-tidy/checks/modernize/use-cpp-style-comments>` check.
+
+ Detects C Style comments and suggests to use C++ style comments instead.
- New :doc:`portability-template-virtual-member-function
<clang-tidy/checks/portability/template-virtual-member-function>` check.
@@ -192,7 +208,7 @@ Changes in existing checks
the offending code with ``reinterpret_cast``, to more clearly express intent.
- Improved :doc:`bugprone-dangling-handle
- <clang-tidy/checks/bugprone/dangling-handle>` check to treat `std::span` as a
+ <clang-tidy/checks/bugprone/dangling-handle>` check to treat ``std::span`` as a
handle class.
- Improved :doc:`bugprone-exception-escape
@@ -203,6 +219,11 @@ Changes in existing checks
<clang-tidy/checks/bugprone/forwarding-reference-overload>` check by fixing
a crash when determining if an ``enable_if[_t]`` was found.
+- Improve :doc:`bugprone-narrowing-conversions
+ <clang-tidy/checks/bugprone/narrowing-conversions>` to avoid incorrect check
+ results when floating point type is not ``float``, ``double`` and
+ ``long double``.
+
- Improved :doc:`bugprone-optional-value-conversion
<clang-tidy/checks/bugprone/optional-value-conversion>` to support detecting
conversion directly by ``std::make_unique`` and ``std::make_shared``.
@@ -230,7 +251,7 @@ Changes in existing checks
- Improved :doc:`bugprone-unchecked-optional-access
<clang-tidy/checks/bugprone/unchecked-optional-access>` to support
- `bsl::optional` and `bdlb::NullableValue` from
+ ``bsl::optional`` and ``bdlb::NullableValue`` from
<https://github.com/bloomberg/bde>_.
- Improved :doc:`bugprone-unhandled-self-assignment
@@ -286,13 +307,13 @@ Changes in existing checks
- Improved :doc:`misc-use-internal-linkage
<clang-tidy/checks/misc/use-internal-linkage>` check to insert ``static``
- keyword before type qualifiers such as ``const`` and ``volatile`` and fix
- false positives for function declaration without body and fix false positives
- for C++20 export declarations and fix false positives for global scoped
+ keyword before type qualifiers such as ``const`` and ``volatile``. Also, fix
+ false positives for function declaration without body, C++20 consteval
+ functions, C++20 export declarations, and global scoped
overloaded ``operator new`` and ``operator delete``.
- Improved :doc:`modernize-avoid-c-arrays
- <clang-tidy/checks/modernize/avoid-c-arrays>` check to suggest using
+ <clang-tidy/checks/modernize/avoid-c-arrays>` check to suggest using
``std::span`` as a replacement for parameters of incomplete C array type in
C++20 and ``std::array`` or ``std::vector`` before C++20.
@@ -305,10 +326,19 @@ Changes in existing checks
a false positive when only an implicit conversion happened inside an
initializer list.
+- Improved :doc:`modernize-raw-string-literal
+ <clang-tidy/checks/modernize/raw-string-literal>` check to fix incorrect
+ fix-it when the string contains a user-defined suffix.
+
- Improved :doc:`modernize-use-designated-initializers
<clang-tidy/checks/modernize/use-designated-initializers>` check to fix a
crash when a class is declared but not defined.
+- Improved :doc:`modernize-use-integer-sign-comparison
+ <clang-tidy/checks/modernize/use-integer-sign-comparison>` check to
+ add an option ``EnableQtSupport``, that makes C++17 ``q20::cmp_*`` alternative
+ available for Qt-based applications.
+
- Improved :doc:`modernize-use-nullptr
<clang-tidy/checks/modernize/use-nullptr>` check to also recognize
``NULL``/``__null`` (but not ``0``) when used with a templated type.
@@ -339,6 +369,10 @@ Changes in existing checks
<clang-tidy/checks/performance/move-const-arg>` check to fix a crash when
an argument type is declared but not defined.
+- Improved :doc:`performance-unnecessary-copy-initialization
+ <clang-tidy/checks/performance/unnecessary-copy-initialization>` check
+ to consider static member functions the same way as free functions.
+
- Improved :doc:`readability-container-contains
<clang-tidy/checks/readability/container-contains>` check to let it work on
any class that has a ``contains`` method. Fix some false negatives in the
@@ -350,19 +384,28 @@ Changes in existing checks
file path for anonymous enums in the diagnostic, and by fixing a typo in the
diagnostic.
+- Improved :doc:`readability-identifier-naming
+ <clang-tidy/checks/readability/identifier-naming>` check to
+ validate ``namespace`` aliases.
+
- Improved :doc:`readability-implicit-bool-conversion
<clang-tidy/checks/readability/implicit-bool-conversion>` check
by adding the option `UseUpperCaseLiteralSuffix` to select the
case of the literal suffix in fixes and fixing false positive for implicit
conversion of comparison result in C23.
+- Improved :doc:`readability-redundant-casting
+ <clang-tidy/checks/readability/redundant-casting>` check
+ by addressing a false positive in aggregate initialization through
+ parenthesized list.
+
- Improved :doc:`readability-redundant-smartptr-get
<clang-tidy/checks/readability/redundant-smartptr-get>` check to
- remove `->`, when redundant `get()` is removed.
+ remove ``->``, when redundant ``get()`` is removed.
-- Improved :doc:`readability-identifier-naming
- <clang-tidy/checks/readability/identifier-naming>` check to
- validate ``namespace`` aliases.
+- Improved :doc:`readability-use-std-min-max
+ <clang-tidy/checks/readability/use-std-min-max>` check to use correct template
+ type in ``std::min`` and ``std::max`` when operand is integer literal.
Removed checks
^^^^^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
new file mode 100644
index 00000000000000..5eaf759a3db6d6
--- /dev/null
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
@@ -0,0 +1,38 @@
+.. title:: clang-tidy - use-cpp-style-comments
+
+modernize-use-cpp-style-comments
+=======================
+
+Replace C-style comments with C++-style comments.
+C-style comments (`/* ... */`) are inherited from C, while C++ introduces
+`//` as a more concise, readable, and less error-prone alternative. Modern C++
+guidelines recommend using C++-style comments for consistency and
+maintainability. This check identifies and replaces C-style comments with
+equivalent C++-style comments.
+
+Examples:
+
+Input:
+.. code-block::c++
+ /* This is a single-line comment */
+ int x = 42; /* Inline comment */
+
+ /* This is a
+ multi-line comment */
+
+
+Output:
+.. code-block::c++
+ // This is a single-line comment
+ int x = 42; // Inline comment
+
+ // This is a
+ // multi-line comment
+
+.. note::
+
+ Inline Comments are neither fixed nor warned.
+ Example:
+ .. code-block:: c++
+ int a = /* this is a comment */ 5;
+
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-cpp-style-comments.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-cpp-style-comments.cpp
new file mode 100644
index 00000000000000..f56750591e035f
--- /dev/null
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize/use-cpp-style-comments.cpp
@@ -0,0 +1,68 @@
+// RUN: %check_clang_tidy -std=c++11 %s modernize-use-cpp-style-comments %t -- --
+
+// Single-line full C-style comment
+static const int CONSTANT = 42; /* Important constant value */
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+// CHECK-FIXES: static const int CONSTANT = 42; // Important constant value
+
+// Inline comment that should NOT be transformed
+int a = /* inline comment */ 5;
+
+// Multiline full-line comment
+/* This is a multiline comment
+ that spans several lines
+ and should be converted to C++ style */
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+// CHECK-FIXES: // This is a multiline comment
+// CHECK-FIXES: // that spans several lines
+// CHECK-FIXES: // and should be converted to C++ style
+void fnWithSomeBools(bool A,bool B) {}
+// Function with parameter inline comments
+void processData(int data /* input data */,
+ bool validate /* perform validation */) {
+ // These inline comments should NOT be transformed
+ fnWithSomeBools(/*ControlsA=*/ true, /*ControlsB=*/ false);
+}
+
+// Multiline comment with asterisk styling
+/*******************************
+ * Block comment with asterisks
+ * Should be converted to C++ style
+ *******************************/
+// CHECK-MESSAGES: :[[@LINE-4]]:1: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+// CHECK-FIXES: // ******************************
+// CHECK-FIXES: // * Block comment with asterisks
+// CHECK-FIXES: // * Should be converted to C++ style
+// CHECK-FIXES: // ******************************
+int calculateSomething() { return 1;}
+// Comment at end of complex line
+int complexCalculation = calculateSomething(); /* Result of complex calculation */
+// CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+// CHECK-FIXES: int complexCalculation = calculateSomething(); // Result of complex calculation
+
+// Nested comments and edge cases
+void edgeCaseFunction() {
+ int x = 10 /* First value */ + 20 /* Second value */; // Inline comments should not transform
+
+ /* Comment with special characters !@#$%^&*()_+ */
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+ // CHECK-FIXES: // Comment with special characters !@#$%^&*()_+
+}
+
+// Multiline comment with various indentations
+ /* This comment is indented
+ and should preserve indentation when converted */
+// CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+// CHECK-FIXES: // This comment is indented
+// CHECK-FIXES: // and should preserve indentation when converted
+
+// Complex function with mixed comment types
+void complexFunction() {
+ /* Full line comment at start of block */
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+ // CHECK-FIXES: // Full line comment at start of block
+
+ int x = 10; /* Inline comment not to be transformed */
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+ // CHECK-FIXES: int x = 10; // Inline comment not to be transformed
+}
\ No newline at end of file
>From 8bf94c6e3a4202f22efbcb7d1988c9b234c4e172 Mon Sep 17 00:00:00 2001
From: 4m4n-x-b4w4ne <amanmbawane at gmail.com>
Date: Fri, 24 Jan 2025 23:13:22 +0530
Subject: [PATCH 02/14] Revert "Added options to
readability-implicit-bool-conversion (#120087)"
This reverts commit 5bec2b71b44ddff44aa4d8534b58a5561389bb1d.
reverting previous commits on this branch
---
.../ImplicitBoolConversionCheck.cpp | 428 ++++++++++++++++++
.../readability/ImplicitBoolConversionCheck.h | 44 ++
2 files changed, 472 insertions(+)
create mode 100644 clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
new file mode 100644
index 00000000000000..f9fd1d903e231e
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.cpp
@@ -0,0 +1,428 @@
+//===--- ImplicitBoolConversionCheck.cpp - clang-tidy----------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "ImplicitBoolConversionCheck.h"
+#include "../utils/FixItHintUtils.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/FixIt.h"
+#include <queue>
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+
+namespace {
+
+AST_MATCHER(Stmt, isMacroExpansion) {
+ SourceManager &SM = Finder->getASTContext().getSourceManager();
+ SourceLocation Loc = Node.getBeginLoc();
+ return SM.isMacroBodyExpansion(Loc) || SM.isMacroArgExpansion(Loc);
+}
+
+AST_MATCHER(Stmt, isC23) { return Finder->getASTContext().getLangOpts().C23; }
+
+bool isNULLMacroExpansion(const Stmt *Statement, ASTContext &Context) {
+ SourceManager &SM = Context.getSourceManager();
+ const LangOptions &LO = Context.getLangOpts();
+ SourceLocation Loc = Statement->getBeginLoc();
+ return SM.isMacroBodyExpansion(Loc) &&
+ Lexer::getImmediateMacroName(Loc, SM, LO) == "NULL";
+}
+
+AST_MATCHER(Stmt, isNULLMacroExpansion) {
+ return isNULLMacroExpansion(&Node, Finder->getASTContext());
+}
+
+StringRef getZeroLiteralToCompareWithForType(CastKind CastExprKind,
+ QualType Type,
+ ASTContext &Context) {
+ switch (CastExprKind) {
+ case CK_IntegralToBoolean:
+ return Type->isUnsignedIntegerType() ? "0u" : "0";
+
+ case CK_FloatingToBoolean:
+ return Context.hasSameType(Type, Context.FloatTy) ? "0.0f" : "0.0";
+
+ case CK_PointerToBoolean:
+ case CK_MemberPointerToBoolean: // Fall-through on purpose.
+ return (Context.getLangOpts().CPlusPlus11 || Context.getLangOpts().C23)
+ ? "nullptr"
+ : "0";
+
+ default:
+ llvm_unreachable("Unexpected cast kind");
+ }
+}
+
+bool isUnaryLogicalNotOperator(const Stmt *Statement) {
+ const auto *UnaryOperatorExpr = dyn_cast<UnaryOperator>(Statement);
+ return UnaryOperatorExpr && UnaryOperatorExpr->getOpcode() == UO_LNot;
+}
+
+void fixGenericExprCastToBool(DiagnosticBuilder &Diag,
+ const ImplicitCastExpr *Cast, const Stmt *Parent,
+ ASTContext &Context,
+ bool UseUpperCaseLiteralSuffix) {
+ // In case of expressions like (! integer), we should remove the redundant not
+ // operator and use inverted comparison (integer == 0).
+ bool InvertComparison =
+ Parent != nullptr && isUnaryLogicalNotOperator(Parent);
+ if (InvertComparison) {
+ SourceLocation ParentStartLoc = Parent->getBeginLoc();
+ SourceLocation ParentEndLoc =
+ cast<UnaryOperator>(Parent)->getSubExpr()->getBeginLoc();
+ Diag << FixItHint::CreateRemoval(
+ CharSourceRange::getCharRange(ParentStartLoc, ParentEndLoc));
+
+ Parent = Context.getParents(*Parent)[0].get<Stmt>();
+ }
+
+ const Expr *SubExpr = Cast->getSubExpr();
+
+ bool NeedInnerParens = utils::fixit::areParensNeededForStatement(*SubExpr);
+ bool NeedOuterParens =
+ Parent != nullptr && utils::fixit::areParensNeededForStatement(*Parent);
+
+ std::string StartLocInsertion;
+
+ if (NeedOuterParens) {
+ StartLocInsertion += "(";
+ }
+ if (NeedInnerParens) {
+ StartLocInsertion += "(";
+ }
+
+ if (!StartLocInsertion.empty()) {
+ Diag << FixItHint::CreateInsertion(Cast->getBeginLoc(), StartLocInsertion);
+ }
+
+ std::string EndLocInsertion;
+
+ if (NeedInnerParens) {
+ EndLocInsertion += ")";
+ }
+
+ if (InvertComparison) {
+ EndLocInsertion += " == ";
+ } else {
+ EndLocInsertion += " != ";
+ }
+
+ const StringRef ZeroLiteral = getZeroLiteralToCompareWithForType(
+ Cast->getCastKind(), SubExpr->getType(), Context);
+
+ if (UseUpperCaseLiteralSuffix)
+ EndLocInsertion += ZeroLiteral.upper();
+ else
+ EndLocInsertion += ZeroLiteral;
+
+ if (NeedOuterParens) {
+ EndLocInsertion += ")";
+ }
+
+ SourceLocation EndLoc = Lexer::getLocForEndOfToken(
+ Cast->getEndLoc(), 0, Context.getSourceManager(), Context.getLangOpts());
+ Diag << FixItHint::CreateInsertion(EndLoc, EndLocInsertion);
+}
+
+StringRef getEquivalentBoolLiteralForExpr(const Expr *Expression,
+ ASTContext &Context) {
+ if (isNULLMacroExpansion(Expression, Context)) {
+ return "false";
+ }
+
+ if (const auto *IntLit =
+ dyn_cast<IntegerLiteral>(Expression->IgnoreParens())) {
+ return (IntLit->getValue() == 0) ? "false" : "true";
+ }
+
+ if (const auto *FloatLit = dyn_cast<FloatingLiteral>(Expression)) {
+ llvm::APFloat FloatLitAbsValue = FloatLit->getValue();
+ FloatLitAbsValue.clearSign();
+ return (FloatLitAbsValue.bitcastToAPInt() == 0) ? "false" : "true";
+ }
+
+ if (const auto *CharLit = dyn_cast<CharacterLiteral>(Expression)) {
+ return (CharLit->getValue() == 0) ? "false" : "true";
+ }
+
+ if (isa<StringLiteral>(Expression->IgnoreCasts())) {
+ return "true";
+ }
+
+ return {};
+}
+
+bool needsSpacePrefix(SourceLocation Loc, ASTContext &Context) {
+ SourceRange PrefixRange(Loc.getLocWithOffset(-1), Loc);
+ StringRef SpaceBeforeStmtStr = Lexer::getSourceText(
+ CharSourceRange::getCharRange(PrefixRange), Context.getSourceManager(),
+ Context.getLangOpts(), nullptr);
+ if (SpaceBeforeStmtStr.empty())
+ return true;
+
+ const StringRef AllowedCharacters(" \t\n\v\f\r(){}[]<>;,+=-|&~!^*/");
+ return !AllowedCharacters.contains(SpaceBeforeStmtStr.back());
+}
+
+void fixGenericExprCastFromBool(DiagnosticBuilder &Diag,
+ const ImplicitCastExpr *Cast,
+ ASTContext &Context, StringRef OtherType) {
+ if (!Context.getLangOpts().CPlusPlus) {
+ Diag << FixItHint::CreateInsertion(Cast->getBeginLoc(),
+ (Twine("(") + OtherType + ")").str());
+ return;
+ }
+
+ const Expr *SubExpr = Cast->getSubExpr();
+ const bool NeedParens = !isa<ParenExpr>(SubExpr->IgnoreImplicit());
+ const bool NeedSpace = needsSpacePrefix(Cast->getBeginLoc(), Context);
+
+ Diag << FixItHint::CreateInsertion(
+ Cast->getBeginLoc(), (Twine() + (NeedSpace ? " " : "") + "static_cast<" +
+ OtherType + ">" + (NeedParens ? "(" : ""))
+ .str());
+
+ if (NeedParens) {
+ SourceLocation EndLoc = Lexer::getLocForEndOfToken(
+ Cast->getEndLoc(), 0, Context.getSourceManager(),
+ Context.getLangOpts());
+
+ Diag << FixItHint::CreateInsertion(EndLoc, ")");
+ }
+}
+
+StringRef getEquivalentForBoolLiteral(const CXXBoolLiteralExpr *BoolLiteral,
+ QualType DestType, ASTContext &Context) {
+ // Prior to C++11, false literal could be implicitly converted to pointer.
+ if (!Context.getLangOpts().CPlusPlus11 &&
+ (DestType->isPointerType() || DestType->isMemberPointerType()) &&
+ BoolLiteral->getValue() == false) {
+ return "0";
+ }
+
+ if (DestType->isFloatingType()) {
+ if (Context.hasSameType(DestType, Context.FloatTy)) {
+ return BoolLiteral->getValue() ? "1.0f" : "0.0f";
+ }
+ return BoolLiteral->getValue() ? "1.0" : "0.0";
+ }
+
+ if (DestType->isUnsignedIntegerType()) {
+ return BoolLiteral->getValue() ? "1u" : "0u";
+ }
+ return BoolLiteral->getValue() ? "1" : "0";
+}
+
+bool isCastAllowedInCondition(const ImplicitCastExpr *Cast,
+ ASTContext &Context) {
+ std::queue<const Stmt *> Q;
+ Q.push(Cast);
+
+ TraversalKindScope RAII(Context, TK_AsIs);
+
+ while (!Q.empty()) {
+ for (const auto &N : Context.getParents(*Q.front())) {
+ const Stmt *S = N.get<Stmt>();
+ if (!S)
+ return false;
+ if (isa<IfStmt>(S) || isa<ConditionalOperator>(S) || isa<ForStmt>(S) ||
+ isa<WhileStmt>(S) || isa<DoStmt>(S) ||
+ isa<BinaryConditionalOperator>(S))
+ return true;
+ if (isa<ParenExpr>(S) || isa<ImplicitCastExpr>(S) ||
+ isUnaryLogicalNotOperator(S) ||
+ (isa<BinaryOperator>(S) && cast<BinaryOperator>(S)->isLogicalOp())) {
+ Q.push(S);
+ } else {
+ return false;
+ }
+ }
+ Q.pop();
+ }
+ return false;
+}
+
+} // anonymous namespace
+
+ImplicitBoolConversionCheck::ImplicitBoolConversionCheck(
+ StringRef Name, ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ AllowIntegerConditions(Options.get("AllowIntegerConditions", false)),
+ AllowPointerConditions(Options.get("AllowPointerConditions", false)),
+ UseUpperCaseLiteralSuffix(
+ Options.get("UseUpperCaseLiteralSuffix", false)) {}
+
+void ImplicitBoolConversionCheck::storeOptions(
+ ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "AllowIntegerConditions", AllowIntegerConditions);
+ Options.store(Opts, "AllowPointerConditions", AllowPointerConditions);
+ Options.store(Opts, "UseUpperCaseLiteralSuffix", UseUpperCaseLiteralSuffix);
+}
+
+void ImplicitBoolConversionCheck::registerMatchers(MatchFinder *Finder) {
+ auto ExceptionCases =
+ expr(anyOf(allOf(isMacroExpansion(), unless(isNULLMacroExpansion())),
+ has(ignoringImplicit(
+ memberExpr(hasDeclaration(fieldDecl(hasBitWidth(1)))))),
+ hasParent(explicitCastExpr()),
+ expr(hasType(qualType().bind("type")),
+ hasParent(initListExpr(hasParent(explicitCastExpr(
+ hasType(qualType(equalsBoundNode("type"))))))))));
+ auto ImplicitCastFromBool = implicitCastExpr(
+ anyOf(hasCastKind(CK_IntegralCast), hasCastKind(CK_IntegralToFloating),
+ // Prior to C++11 cast from bool literal to pointer was allowed.
+ allOf(anyOf(hasCastKind(CK_NullToPointer),
+ hasCastKind(CK_NullToMemberPointer)),
+ hasSourceExpression(cxxBoolLiteral()))),
+ hasSourceExpression(expr(hasType(booleanType()))));
+ auto BoolXor =
+ binaryOperator(hasOperatorName("^"), hasLHS(ImplicitCastFromBool),
+ hasRHS(ImplicitCastFromBool));
+ auto ComparisonInCall = allOf(
+ hasParent(callExpr()),
+ hasSourceExpression(binaryOperator(hasAnyOperatorName("==", "!="))));
+
+ auto IsInCompilerGeneratedFunction = hasAncestor(namedDecl(anyOf(
+ isImplicit(), functionDecl(isDefaulted()), functionTemplateDecl())));
+
+ Finder->addMatcher(
+ traverse(TK_AsIs,
+ implicitCastExpr(
+ anyOf(hasCastKind(CK_IntegralToBoolean),
+ hasCastKind(CK_FloatingToBoolean),
+ hasCastKind(CK_PointerToBoolean),
+ hasCastKind(CK_MemberPointerToBoolean)),
+ // Exclude cases of C23 comparison result.
+ unless(allOf(isC23(),
+ hasSourceExpression(ignoringParens(
+ binaryOperator(hasAnyOperatorName(
+ ">", ">=", "==", "!=", "<", "<=")))))),
+ // Exclude case of using if or while statements with variable
+ // declaration, e.g.:
+ // if (int var = functionCall()) {}
+ unless(hasParent(
+ stmt(anyOf(ifStmt(), whileStmt()), has(declStmt())))),
+ // Exclude cases common to implicit cast to and from bool.
+ unless(ExceptionCases), unless(has(BoolXor)),
+ // Exclude C23 cases common to implicit cast to bool.
+ unless(ComparisonInCall),
+ // Retrieve also parent statement, to check if we need
+ // additional parens in replacement.
+ optionally(hasParent(stmt().bind("parentStmt"))),
+ unless(isInTemplateInstantiation()),
+ unless(IsInCompilerGeneratedFunction))
+ .bind("implicitCastToBool")),
+ this);
+
+ auto BoolComparison = binaryOperator(hasAnyOperatorName("==", "!="),
+ hasLHS(ImplicitCastFromBool),
+ hasRHS(ImplicitCastFromBool));
+ auto BoolOpAssignment = binaryOperator(hasAnyOperatorName("|=", "&="),
+ hasLHS(expr(hasType(booleanType()))));
+ auto BitfieldAssignment = binaryOperator(
+ hasLHS(memberExpr(hasDeclaration(fieldDecl(hasBitWidth(1))))));
+ auto BitfieldConstruct = cxxConstructorDecl(hasDescendant(cxxCtorInitializer(
+ withInitializer(equalsBoundNode("implicitCastFromBool")),
+ forField(hasBitWidth(1)))));
+ Finder->addMatcher(
+ traverse(
+ TK_AsIs,
+ implicitCastExpr(
+ ImplicitCastFromBool, unless(ExceptionCases),
+ // Exclude comparisons of bools, as they are always cast to
+ // integers in such context:
+ // bool_expr_a == bool_expr_b
+ // bool_expr_a != bool_expr_b
+ unless(hasParent(
+ binaryOperator(anyOf(BoolComparison, BoolXor,
+ BoolOpAssignment, BitfieldAssignment)))),
+ implicitCastExpr().bind("implicitCastFromBool"),
+ unless(hasParent(BitfieldConstruct)),
+ // Check also for nested casts, for example: bool -> int -> float.
+ anyOf(hasParent(implicitCastExpr().bind("furtherImplicitCast")),
+ anything()),
+ unless(isInTemplateInstantiation()),
+ unless(IsInCompilerGeneratedFunction))),
+ this);
+}
+
+void ImplicitBoolConversionCheck::check(
+ const MatchFinder::MatchResult &Result) {
+
+ if (const auto *CastToBool =
+ Result.Nodes.getNodeAs<ImplicitCastExpr>("implicitCastToBool")) {
+ const auto *Parent = Result.Nodes.getNodeAs<Stmt>("parentStmt");
+ return handleCastToBool(CastToBool, Parent, *Result.Context);
+ }
+
+ if (const auto *CastFromBool =
+ Result.Nodes.getNodeAs<ImplicitCastExpr>("implicitCastFromBool")) {
+ const auto *NextImplicitCast =
+ Result.Nodes.getNodeAs<ImplicitCastExpr>("furtherImplicitCast");
+ return handleCastFromBool(CastFromBool, NextImplicitCast, *Result.Context);
+ }
+}
+
+void ImplicitBoolConversionCheck::handleCastToBool(const ImplicitCastExpr *Cast,
+ const Stmt *Parent,
+ ASTContext &Context) {
+ if (AllowPointerConditions &&
+ (Cast->getCastKind() == CK_PointerToBoolean ||
+ Cast->getCastKind() == CK_MemberPointerToBoolean) &&
+ isCastAllowedInCondition(Cast, Context)) {
+ return;
+ }
+
+ if (AllowIntegerConditions && Cast->getCastKind() == CK_IntegralToBoolean &&
+ isCastAllowedInCondition(Cast, Context)) {
+ return;
+ }
+
+ auto Diag = diag(Cast->getBeginLoc(), "implicit conversion %0 -> 'bool'")
+ << Cast->getSubExpr()->getType();
+
+ StringRef EquivalentLiteral =
+ getEquivalentBoolLiteralForExpr(Cast->getSubExpr(), Context);
+ if (!EquivalentLiteral.empty()) {
+ Diag << tooling::fixit::createReplacement(*Cast, EquivalentLiteral);
+ } else {
+ fixGenericExprCastToBool(Diag, Cast, Parent, Context,
+ UseUpperCaseLiteralSuffix);
+ }
+}
+
+void ImplicitBoolConversionCheck::handleCastFromBool(
+ const ImplicitCastExpr *Cast, const ImplicitCastExpr *NextImplicitCast,
+ ASTContext &Context) {
+ QualType DestType =
+ NextImplicitCast ? NextImplicitCast->getType() : Cast->getType();
+ auto Diag = diag(Cast->getBeginLoc(), "implicit conversion 'bool' -> %0")
+ << DestType;
+
+ if (const auto *BoolLiteral =
+ dyn_cast<CXXBoolLiteralExpr>(Cast->getSubExpr()->IgnoreParens())) {
+
+ const auto EquivalentForBoolLiteral =
+ getEquivalentForBoolLiteral(BoolLiteral, DestType, Context);
+ if (UseUpperCaseLiteralSuffix)
+ Diag << tooling::fixit::createReplacement(
+ *Cast, EquivalentForBoolLiteral.upper());
+ else
+ Diag << tooling::fixit::createReplacement(*Cast,
+ EquivalentForBoolLiteral);
+
+ } else {
+ fixGenericExprCastFromBool(Diag, Cast, Context, DestType.getAsString());
+ }
+}
+
+} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
new file mode 100644
index 00000000000000..5947f7316e67cc
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/ImplicitBoolConversionCheck.h
@@ -0,0 +1,44 @@
+//===--- ImplicitBoolConversionCheck.h - clang-tidy--------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CONVERSION_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CONVERSION_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::readability {
+
+/// Checks for use of implicit bool conversions in expressions.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability/implicit-bool-conversion.html
+class ImplicitBoolConversionCheck : public ClangTidyCheck {
+public:
+ ImplicitBoolConversionCheck(StringRef Name, ClangTidyContext *Context);
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.Bool;
+ }
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+ void registerMatchers(ast_matchers::MatchFinder *Finder) override;
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+ void handleCastToBool(const ImplicitCastExpr *CastExpression,
+ const Stmt *ParentStatement, ASTContext &Context);
+ void handleCastFromBool(const ImplicitCastExpr *Cast,
+ const ImplicitCastExpr *NextImplicitCast,
+ ASTContext &Context);
+
+ const bool AllowIntegerConditions;
+ const bool AllowPointerConditions;
+ const bool UseUpperCaseLiteralSuffix;
+};
+
+} // namespace clang::tidy::readability
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_IMPLICIT_BOOL_CONVERSION_H
>From 4a87afe94340d8866a2b7362f3384919f184be7f Mon Sep 17 00:00:00 2001
From: 4m4n-x-b4w4ne <amanmbawane at gmail.com>
Date: Fri, 24 Jan 2025 23:48:09 +0530
Subject: [PATCH 03/14] Fixed formatting issues
---
.../modernize/UseCppStyleCommentsCheck.cpp | 53 ++++++++++---------
.../modernize/use-cpp-style-comments.rst | 2 +-
2 files changed, 28 insertions(+), 27 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp
index 3c25c50bab759c..ce0a6e9cc6c83b 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp
@@ -20,9 +20,11 @@ class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
CStyleCommentHandler(UseCppStyleCommentsCheck &Check)
: Check(Check),
CStyleCommentMatch(
- "^[ \t]*/\\*+[ \t\r\n]*(.*[ \t\r\n]*)*[ \t\r\n]*\\*+/[ \t\r\n]*$"){}
+ "^[ \t]*/\\*+[ \t\r\n]*(.*[ \t\r\n]*)*[ \t\r\n]*\\*+/[ \t\r\n]*$") {
+ }
- std::string convertToCppStyleComment(const SourceManager &SM, const SourceRange &Range) {
+ std::string convertToCppStyleComment(const SourceManager &SM,
+ const SourceRange &Range) {
StringRef CommentText = Lexer::getSourceText(
CharSourceRange::getTokenRange(Range), SM, LangOptions());
@@ -37,19 +39,19 @@ class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
if (std::getline(Stream, Line)) {
size_t startPos = Line.find_first_not_of(" \t");
if (startPos != std::string::npos) {
- Line = Line.substr(startPos);
+ Line = Line.substr(startPos);
} else {
- Line.clear();
+ Line.clear();
}
Result += "// " + Line;
}
while (std::getline(Stream, Line)) {
- size_t startPos = Line.find_first_not_of(" \t");
+ size_t startPos = Line.find_first_not_of(" \t");
if (startPos != std::string::npos) {
- Line = Line.substr(startPos);
+ Line = Line.substr(startPos);
} else {
- Line.clear();
+ Line.clear();
}
Result += "\n// " + Line;
}
@@ -59,18 +61,16 @@ class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
bool HandleComment(Preprocessor &PP, SourceRange Range) override {
const SourceManager &SM = PP.getSourceManager();
- if (Range.getBegin().isMacroID() ||
- SM.isInSystemHeader(Range.getBegin())) {
- return false;
+ if (Range.getBegin().isMacroID() || SM.isInSystemHeader(Range.getBegin())) {
+ return false;
}
- const StringRef Text =
- Lexer::getSourceText(CharSourceRange::getCharRange(Range),
- SM, PP.getLangOpts());
+ const StringRef Text = Lexer::getSourceText(
+ CharSourceRange::getCharRange(Range), SM, PP.getLangOpts());
SmallVector<StringRef> Matches;
if (!CStyleCommentMatch.match(Text, &Matches)) {
- return false;
+ return false;
}
SourceLocation CommentStart = Range.getBegin();
@@ -79,22 +79,24 @@ class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
unsigned StartLine = SM.getSpellingLineNumber(CommentStart);
unsigned EndLine = SM.getSpellingLineNumber(CommentEnd);
-
if (StartLine == EndLine) {
- SourceLocation LineBegin = SM.translateLineCol(
- SM.getFileID(CommentStart), StartLine, 1);
- SourceLocation LineEnd = SM.translateLineCol(SM.getFileID(CommentEnd), EndLine, std::numeric_limits<unsigned>::max());
- StringRef LineContent =
- Lexer::getSourceText(CharSourceRange::getCharRange(LineBegin, LineEnd),
- SM, PP.getLangOpts());
+ SourceLocation LineBegin =
+ SM.translateLineCol(SM.getFileID(CommentStart), StartLine, 1);
+ SourceLocation LineEnd =
+ SM.translateLineCol(SM.getFileID(CommentEnd), EndLine,
+ std::numeric_limits<unsigned>::max());
+ StringRef LineContent = Lexer::getSourceText(
+ CharSourceRange::getCharRange(LineBegin, LineEnd), SM,
+ PP.getLangOpts());
size_t CommentStartOffset = SM.getSpellingColumnNumber(CommentStart) - 1;
- StringRef AfterComment = LineContent.drop_front(CommentStartOffset + Text.size());
+ StringRef AfterComment =
+ LineContent.drop_front(CommentStartOffset + Text.size());
if (!AfterComment.trim().empty()) {
- return false;
+ return false;
}
}
-
+
Check.diag(
Range.getBegin(),
"use C++ style comments '//' instead of C style comments '/*...*/'")
@@ -102,8 +104,7 @@ class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
Range, convertToCppStyleComment(SM, Range));
return false;
-}
-
+ }
private:
UseCppStyleCommentsCheck &Check;
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
index 5eaf759a3db6d6..2d92f7b956c658 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
@@ -1,7 +1,7 @@
.. title:: clang-tidy - use-cpp-style-comments
modernize-use-cpp-style-comments
-=======================
+================================
Replace C-style comments with C++-style comments.
C-style comments (`/* ... */`) are inherited from C, while C++ introduces
>From 44d208e5991087e6c895cf9bb65e3c4ca5699d7d Mon Sep 17 00:00:00 2001
From: 4m4n-x-b4w4ne <amanmbawane at gmail.com>
Date: Fri, 24 Jan 2025 23:56:53 +0530
Subject: [PATCH 04/14] Fixed Formatting issues
---
.../docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst | 2 ++
1 file changed, 2 insertions(+)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
index 2d92f7b956c658..2bbbe1fdf1e2ba 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
@@ -14,6 +14,7 @@ Examples:
Input:
.. code-block::c++
+
/* This is a single-line comment */
int x = 42; /* Inline comment */
@@ -23,6 +24,7 @@ Input:
Output:
.. code-block::c++
+
// This is a single-line comment
int x = 42; // Inline comment
>From c9a20efa47aa0f7de8d6d84b6b231aa8f05b3d88 Mon Sep 17 00:00:00 2001
From: 4m4n-x-b4w4ne <amanmbawane at gmail.com>
Date: Sat, 25 Jan 2025 00:08:08 +0530
Subject: [PATCH 05/14] Fixed Formatting issue
---
.../clang-tidy/checks/modernize/use-cpp-style-comments.rst | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
index 2bbbe1fdf1e2ba..d1a793d97bb6de 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
@@ -4,8 +4,8 @@ modernize-use-cpp-style-comments
================================
Replace C-style comments with C++-style comments.
-C-style comments (`/* ... */`) are inherited from C, while C++ introduces
-`//` as a more concise, readable, and less error-prone alternative. Modern C++
+C-style comments (``/* ... */``) are inherited from C, while C++ introduces
+``//`` as a more concise, readable, and less error-prone alternative. Modern C++
guidelines recommend using C++-style comments for consistency and
maintainability. This check identifies and replaces C-style comments with
equivalent C++-style comments.
>From ec6a689f0c4178f841923426a70c54137e1933aa Mon Sep 17 00:00:00 2001
From: 4m4n-x-b4w4ne <amanmbawane at gmail.com>
Date: Sat, 25 Jan 2025 00:42:59 +0530
Subject: [PATCH 06/14] Fixed Formating issues
---
.../modernize/use-cpp-style-comments.rst | 26 +++++++++----------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
index d1a793d97bb6de..befc82245f4ded 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
@@ -14,27 +14,27 @@ Examples:
Input:
.. code-block::c++
+
+ /* This is a single-line comment */
+ int x = 42; /* Inline comment */
- /* This is a single-line comment */
- int x = 42; /* Inline comment */
-
- /* This is a
- multi-line comment */
+ /* This is a
+ multi-line comment */
Output:
.. code-block::c++
- // This is a single-line comment
- int x = 42; // Inline comment
+ // This is a single-line comment
+ int x = 42; // Inline comment
- // This is a
- // multi-line comment
+ // This is a
+ // multi-line comment
.. note::
- Inline Comments are neither fixed nor warned.
- Example:
- .. code-block:: c++
- int a = /* this is a comment */ 5;
+ Inline Comments are neither fixed nor warned.
+ Example:
+ .. code-block:: c++
+ int a = /* this is a comment */ 5;
>From c815e434769254d8ca03a821275e4ae378d43793 Mon Sep 17 00:00:00 2001
From: 4m4n-x-b4w4ne <amanmbawane at gmail.com>
Date: Mon, 27 Jan 2025 22:22:23 +0530
Subject: [PATCH 07/14] further improvements as suggested
---
.../clang-tidy/readability/CMakeLists.txt | 1 +
.../readability/ReadabilityTidyModule.cpp | 3 +
.../readability/UseCppStyleCommentsCheck.cpp | 136 ++++++++++++++++++
.../readability/UseCppStyleCommentsCheck.h | 40 ++++++
4 files changed, 180 insertions(+)
create mode 100644 clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp
create mode 100644 clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.h
diff --git a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
index 8f303c51e1b0da..ffdd5468650501 100644
--- a/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/readability/CMakeLists.txt
@@ -57,6 +57,7 @@ add_clang_library(clangTidyReadabilityModule STATIC
UniqueptrDeleteReleaseCheck.cpp
UppercaseLiteralSuffixCheck.cpp
UseAnyOfAllOfCheck.cpp
+ UseCppStyleCommentsCheck.cpp
UseStdMinMaxCheck.cpp
LINK_LIBS
diff --git a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
index d61c0ba39658e5..8d029682e4ff35 100644
--- a/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/readability/ReadabilityTidyModule.cpp
@@ -60,6 +60,7 @@
#include "UniqueptrDeleteReleaseCheck.h"
#include "UppercaseLiteralSuffixCheck.h"
#include "UseAnyOfAllOfCheck.h"
+#include "UseCppStyleCommentsCheck.h"
#include "UseStdMinMaxCheck.h"
namespace clang::tidy {
@@ -146,6 +147,8 @@ class ReadabilityModule : public ClangTidyModule {
"readability-static-definition-in-anonymous-namespace");
CheckFactories.registerCheck<StringCompareCheck>(
"readability-string-compare");
+ CheckFactories.registerCheck<UseCppStyleCommentsCheck>(
+ "readability-use-cpp-style-comments");
CheckFactories.registerCheck<readability::NamedParameterCheck>(
"readability-named-parameter");
CheckFactories.registerCheck<NonConstParameterCheck>(
diff --git a/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp
new file mode 100644
index 00000000000000..f410fc7ba68f7c
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp
@@ -0,0 +1,136 @@
+//===--- UseCppStyleCommentsCheck.cpp - clang-tidy-------------------------===//
+
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#include "UseCppStyleCommentsCheck.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Lex/Lexer.h"
+#include "clang/Lex/Preprocessor.h"
+#include <sstream.h>
+
+using namespace clang::ast_matchers;
+
+namespace clang::tidy::readability {
+class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
+public:
+ CStyleCommentHandler(UseCppStyleCommentsCheck &Check)
+ : Check(Check),
+ CStyleCommentMatch(
+ "^[ \t]*/\\*+[ \t\r\n]*(.*[ \t\r\n]*)*[ \t\r\n]*\\*+/[ \t\r\n]*$") {
+ }
+
+ std::string convertToCppStyleComment(const SourceManager &SM,
+ const SourceRange &Range) {
+ const StringRef CommentText = Lexer::getSourceText(
+ CharSourceRange::getTokenRange(Range), SM, LangOptions());
+
+ std::string InnerText = CommentText.str();
+ InnerText.erase(0, 2);
+ InnerText.erase(InnerText.size() - 2, 2);
+
+ std::string Result;
+ std::istringstream Stream(InnerText);
+ std::string Line;
+
+ if (std::getline(Stream, Line)) {
+ const size_t StartPos = Line.find_first_not_of(" \t");
+ if (StartPos != std::string::npos) {
+ Line = Line.substr(StartPos);
+ } else {
+ Line.clear();
+ }
+ Result += "// " + Line;
+ }
+
+ while (std::getline(Stream, Line)) {
+ const size_t StartPos = Line.find_first_not_of(" \t");
+ if (StartPos != std::string::npos) {
+ Line = Line.substr(StartPos);
+ } else {
+ Line.clear();
+ }
+ Result += "\n// " + Line;
+ }
+ return Result;
+ }
+
+ bool CheckForInlineComments(Preprocessor &PP, SourceRange Range) {
+ const SourceManager &SM = PP.getSourceManager();
+ const SourceLocation CommentStart = Range.getBegin();
+ const SourceLocation CommentEnd = Range.getEnd();
+
+ unsigned StartLine = SM.getSpellingLineNumber(CommentStart);
+ unsigned EndLine = SM.getSpellingLineNumber(CommentEnd);
+
+ if (StartLine == EndLine) {
+ SourceLocation LineBegin =
+ SM.translateLineCol(SM.getFileID(CommentStart), StartLine, 1);
+ SourceLocation LineEnd =
+ SM.translateLineCol(SM.getFileID(CommentEnd), EndLine,
+ std::numeric_limits<unsigned>::max());
+ StringRef LineContent = Lexer::getSourceText(
+ CharSourceRange::getCharRange(LineBegin, LineEnd), SM,
+ PP.getLangOpts());
+ size_t CommentStartOffset = SM.getSpellingColumnNumber(CommentStart) - 1;
+ StringRef AfterComment =
+ LineContent.drop_front(CommentStartOffset + Text.size());
+
+ if (!AfterComment.trim().empty()) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ bool HandleComment(Preprocessor &PP, SourceRange Range) override {
+ const SourceManager &SM = PP.getSourceManager();
+
+ if (Range.getBegin().isMacroID() || SM.isInSystemHeader(Range.getBegin())) {
+ return false;
+ }
+
+ const StringRef Text = Lexer::getSourceText(
+ CharSourceRange::getCharRange(Range), SM, PP.getLangOpts());
+
+ SmallVector<StringRef> Matches;
+ if (!CStyleCommentMatch.match(Text, &Matches)) {
+ return false;
+ }
+
+ if (CheckForInlineComments(PP, Range)) {
+ return false;
+ }
+
+ Check.diag(
+ Range.getBegin(),
+ "use C++ style comments '//' instead of C style comments '/*...*/'")
+ << clang::FixItHint::CreateReplacement(
+ Range, convertToCppStyleComment(SM, Range));
+
+ return false;
+ }
+
+private:
+ UseCppStyleCommentsCheck &Check;
+ llvm::Regex CStyleCommentMatch;
+};
+
+UseCppStyleCommentsCheck::UseCppStyleCommentsCheck(StringRef Name,
+ ClangTidyContext *Context)
+ : ClangTidyCheck(Name, Context),
+ Handler(std::make_unique<CStyleCommentHandler>(*this)) {}
+
+void UseCppStyleCommentsCheck::registerPPCallbacks(
+ const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
+ PP->addCommentHandler(Handler.get());
+}
+
+void UseCppStyleCommentsCheck::check(const MatchFinder::MatchResult &Result) {}
+
+UseCppStyleCommentsCheck::~UseCppStyleCommentsCheck() = default;
+} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.h b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.h
new file mode 100644
index 00000000000000..dd4eb2a1e788a3
--- /dev/null
+++ b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.h
@@ -0,0 +1,40 @@
+//===--- UseCppStyleCommentsCheck.h - clang-tidy-----------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USECPPSTYLECOMMENTSCHECK_H
+#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USECPPSTYLECOMMENTSCHECK_H
+
+#include "../ClangTidyCheck.h"
+
+namespace clang::tidy::readability {
+/// Detects C Style comments and suggests to use C++ style comments instead.
+///
+/// For the user-facing documentation see:
+/// http://clang.llvm.org/extra/clang-tidy/checks/readability/use-cpp-style-comments.html
+class UseCppStyleCommentsCheck : public ClangTidyCheck {
+public:
+ UseCppStyleCommentsCheck(StringRef Name, ClangTidyContext *Context);
+
+ ~UseCppStyleCommentsCheck() override;
+
+ bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
+ return LangOpts.CPlusPlus;
+ }
+
+ void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
+ Preprocessor *ModuleExpanderPP) override;
+
+ void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+ class CStyleCommentHandler;
+ std::unique_ptr<CStyleCommentHandler> Handler;
+};
+} // namespace clang::tidy::readability
+
+#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USECPPSTYLECOMMENTSCHECK_H
>From 47217aaa6c81653c57b07555133c1a5cdca659c2 Mon Sep 17 00:00:00 2001
From: 4m4n-x-B4w4ne <amanmbawane at gmail.com>
Date: Mon, 27 Jan 2025 22:35:33 +0530
Subject: [PATCH 08/14] Delete
clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp
---
.../modernize/UseCppStyleCommentsCheck.cpp | 127 ------------------
1 file changed, 127 deletions(-)
delete mode 100644 clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp
deleted file mode 100644
index ce0a6e9cc6c83b..00000000000000
--- a/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-//===--- UseCppStyleCommentsCheck.cpp - clang-tidy-------------------------===//
-
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#include "UseCppStyleCommentsCheck.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/Lex/Lexer.h"
-#include "clang/Lex/Preprocessor.h"
-#include <iostream>
-using namespace clang::ast_matchers;
-
-namespace clang::tidy::modernize {
-class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
-public:
- CStyleCommentHandler(UseCppStyleCommentsCheck &Check)
- : Check(Check),
- CStyleCommentMatch(
- "^[ \t]*/\\*+[ \t\r\n]*(.*[ \t\r\n]*)*[ \t\r\n]*\\*+/[ \t\r\n]*$") {
- }
-
- std::string convertToCppStyleComment(const SourceManager &SM,
- const SourceRange &Range) {
- StringRef CommentText = Lexer::getSourceText(
- CharSourceRange::getTokenRange(Range), SM, LangOptions());
-
- std::string InnerText = CommentText.str();
- InnerText.erase(0, 2);
- InnerText.erase(InnerText.size() - 2, 2);
-
- std::string Result;
- std::istringstream Stream(InnerText);
- std::string Line;
-
- if (std::getline(Stream, Line)) {
- size_t startPos = Line.find_first_not_of(" \t");
- if (startPos != std::string::npos) {
- Line = Line.substr(startPos);
- } else {
- Line.clear();
- }
- Result += "// " + Line;
- }
-
- while (std::getline(Stream, Line)) {
- size_t startPos = Line.find_first_not_of(" \t");
- if (startPos != std::string::npos) {
- Line = Line.substr(startPos);
- } else {
- Line.clear();
- }
- Result += "\n// " + Line;
- }
- return Result;
- }
-
- bool HandleComment(Preprocessor &PP, SourceRange Range) override {
- const SourceManager &SM = PP.getSourceManager();
-
- if (Range.getBegin().isMacroID() || SM.isInSystemHeader(Range.getBegin())) {
- return false;
- }
-
- const StringRef Text = Lexer::getSourceText(
- CharSourceRange::getCharRange(Range), SM, PP.getLangOpts());
-
- SmallVector<StringRef> Matches;
- if (!CStyleCommentMatch.match(Text, &Matches)) {
- return false;
- }
-
- SourceLocation CommentStart = Range.getBegin();
- SourceLocation CommentEnd = Range.getEnd();
-
- unsigned StartLine = SM.getSpellingLineNumber(CommentStart);
- unsigned EndLine = SM.getSpellingLineNumber(CommentEnd);
-
- if (StartLine == EndLine) {
- SourceLocation LineBegin =
- SM.translateLineCol(SM.getFileID(CommentStart), StartLine, 1);
- SourceLocation LineEnd =
- SM.translateLineCol(SM.getFileID(CommentEnd), EndLine,
- std::numeric_limits<unsigned>::max());
- StringRef LineContent = Lexer::getSourceText(
- CharSourceRange::getCharRange(LineBegin, LineEnd), SM,
- PP.getLangOpts());
- size_t CommentStartOffset = SM.getSpellingColumnNumber(CommentStart) - 1;
- StringRef AfterComment =
- LineContent.drop_front(CommentStartOffset + Text.size());
-
- if (!AfterComment.trim().empty()) {
- return false;
- }
- }
-
- Check.diag(
- Range.getBegin(),
- "use C++ style comments '//' instead of C style comments '/*...*/'")
- << clang::FixItHint::CreateReplacement(
- Range, convertToCppStyleComment(SM, Range));
-
- return false;
- }
-
-private:
- UseCppStyleCommentsCheck &Check;
- llvm::Regex CStyleCommentMatch;
-};
-
-UseCppStyleCommentsCheck::UseCppStyleCommentsCheck(StringRef Name,
- ClangTidyContext *Context)
- : ClangTidyCheck(Name, Context),
- Handler(std::make_unique<CStyleCommentHandler>(*this)) {}
-
-void UseCppStyleCommentsCheck::registerPPCallbacks(
- const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
- PP->addCommentHandler(Handler.get());
-}
-
-void UseCppStyleCommentsCheck::check(const MatchFinder::MatchResult &Result) {}
-
-UseCppStyleCommentsCheck::~UseCppStyleCommentsCheck() = default;
-} // namespace clang::tidy::modernize
>From 7150e04339923f08880d24429d3383032aee20f8 Mon Sep 17 00:00:00 2001
From: 4m4n-x-B4w4ne <amanmbawane at gmail.com>
Date: Mon, 27 Jan 2025 22:36:15 +0530
Subject: [PATCH 09/14] Delete
clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.h
---
.../modernize/UseCppStyleCommentsCheck.h | 40 -------------------
1 file changed, 40 deletions(-)
delete mode 100644 clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.h
diff --git a/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.h b/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.h
deleted file mode 100644
index 3d604683de5a24..00000000000000
--- a/clang-tools-extra/clang-tidy/modernize/UseCppStyleCommentsCheck.h
+++ /dev/null
@@ -1,40 +0,0 @@
-//===--- UseCppStyleCommentsCheck.h - clang-tidy---------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_CPP_STYLE_COMMENTS_CHECK_H
-#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_CPP_STYLE_COMMENTS_CHECK_H
-
-#include "../ClangTidyCheck.h"
-#include <sstream>
-namespace clang::tidy::modernize {
-/// Detects C Style comments and suggests to use C++ style comments instead.
-///
-/// For the user-facing documentation see:
-/// http://clang.llvm.org/extra/clang-tidy/checks/modernize/use-cpp-style-comments.html
-class UseCppStyleCommentsCheck : public ClangTidyCheck {
-public:
- UseCppStyleCommentsCheck(StringRef Name, ClangTidyContext *Context);
-
- ~UseCppStyleCommentsCheck() override;
-
- bool isLanguageVersionSupported(const LangOptions &LangOpts) const override {
- return LangOpts.CPlusPlus;
- }
-
- void registerPPCallbacks(const SourceManager &SM, Preprocessor *PP,
- Preprocessor *ModuleExpanderPP) override;
-
- void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
-
-private:
- class CStyleCommentHandler;
- std::unique_ptr<CStyleCommentHandler> Handler;
-};
-} // namespace clang::tidy::modernize
-
-#endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_MODERNIZE_USE_CPP_STYLE_COMMENTS_CHECK_H
>From ba3c7bbd975ff9760af7f9913dfdcef8fbfd8f69 Mon Sep 17 00:00:00 2001
From: 4m4n-x-b4w4ne <amanmbawane at gmail.com>
Date: Mon, 27 Jan 2025 23:59:54 +0530
Subject: [PATCH 10/14] improvements as suggested
---
.../clang-tidy/modernize/CMakeLists.txt | 1 -
.../modernize/ModernizeTidyModule.cpp | 3 ---
.../readability/UseCppStyleCommentsCheck.cpp | 16 ++++++++-------
.../readability/UseCppStyleCommentsCheck.h | 1 +
clang-tools-extra/docs/ReleaseNotes.rst | 10 +++++-----
.../docs/clang-tidy/checks/list.rst | 1 +
.../use-cpp-style-comments.rst | 5 ++---
.../use-cpp-style-comments.cpp | 20 +++++++++----------
8 files changed, 28 insertions(+), 29 deletions(-)
rename clang-tools-extra/docs/clang-tidy/checks/{modernize => readability}/use-cpp-style-comments.rst (92%)
rename clang-tools-extra/test/clang-tidy/checkers/{modernize => readability}/use-cpp-style-comments.cpp (78%)
diff --git a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
index f07dd5efecc58e..bab1167fb15ff2 100644
--- a/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
+++ b/clang-tools-extra/clang-tidy/modernize/CMakeLists.txt
@@ -31,7 +31,6 @@ add_clang_library(clangTidyModernizeModule STATIC
UseAutoCheck.cpp
UseBoolLiteralsCheck.cpp
UseConstraintsCheck.cpp
- UseCppStyleCommentsCheck.cpp
UseDefaultMemberInitCheck.cpp
UseDesignatedInitializersCheck.cpp
UseEmplaceCheck.cpp
diff --git a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
index 1917d562f7ce8d..fc46c72982fdce 100644
--- a/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ModernizeTidyModule.cpp
@@ -32,7 +32,6 @@
#include "UseAutoCheck.h"
#include "UseBoolLiteralsCheck.h"
#include "UseConstraintsCheck.h"
-#include "UseCppStyleCommentsCheck.h"
#include "UseDefaultMemberInitCheck.h"
#include "UseDesignatedInitializersCheck.h"
#include "UseEmplaceCheck.h"
@@ -108,8 +107,6 @@ class ModernizeModule : public ClangTidyModule {
"modernize-use-bool-literals");
CheckFactories.registerCheck<UseConstraintsCheck>(
"modernize-use-constraints");
- CheckFactories.registerCheck<UseCppStyleCommentsCheck>(
- "modernize-use-cpp-style-comments");
CheckFactories.registerCheck<UseDefaultMemberInitCheck>(
"modernize-use-default-member-init");
CheckFactories.registerCheck<UseEmplaceCheck>("modernize-use-emplace");
diff --git a/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp
index f410fc7ba68f7c..3ce894a44c87d5 100644
--- a/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp
@@ -1,5 +1,4 @@
//===--- UseCppStyleCommentsCheck.cpp - clang-tidy-------------------------===//
-
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@@ -11,7 +10,7 @@
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"
#include "clang/Lex/Preprocessor.h"
-#include <sstream.h>
+#include <sstream>
using namespace clang::ast_matchers;
@@ -67,17 +66,20 @@ class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
unsigned StartLine = SM.getSpellingLineNumber(CommentStart);
unsigned EndLine = SM.getSpellingLineNumber(CommentEnd);
+ const StringRef Text = Lexer::getSourceText(
+ CharSourceRange::getCharRange(Range), SM, PP.getLangOpts());
+
if (StartLine == EndLine) {
- SourceLocation LineBegin =
+ const SourceLocation LineBegin =
SM.translateLineCol(SM.getFileID(CommentStart), StartLine, 1);
- SourceLocation LineEnd =
+ const SourceLocation LineEnd =
SM.translateLineCol(SM.getFileID(CommentEnd), EndLine,
std::numeric_limits<unsigned>::max());
- StringRef LineContent = Lexer::getSourceText(
+ const StringRef LineContent = Lexer::getSourceText(
CharSourceRange::getCharRange(LineBegin, LineEnd), SM,
PP.getLangOpts());
- size_t CommentStartOffset = SM.getSpellingColumnNumber(CommentStart) - 1;
- StringRef AfterComment =
+ const size_t CommentStartOffset = SM.getSpellingColumnNumber(CommentStart) - 1;
+ const StringRef AfterComment =
LineContent.drop_front(CommentStartOffset + Text.size());
if (!AfterComment.trim().empty()) {
diff --git a/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.h b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.h
index dd4eb2a1e788a3..c7c6bfb6e85090 100644
--- a/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.h
@@ -10,6 +10,7 @@
#define LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USECPPSTYLECOMMENTSCHECK_H
#include "../ClangTidyCheck.h"
+#include <memory>
namespace clang::tidy::readability {
/// Detects C Style comments and suggests to use C++ style comments instead.
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index a89cd1a8b80e50..4d30d0bae9ebeb 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -174,17 +174,17 @@ New checks
Replace comparisons between signed and unsigned integers with their safe
C++20 ``std::cmp_*`` alternative, if available.
-- New :doc:`modernize-use-cpp-style-comments
- <clang-tidy/checks/modernize/use-cpp-style-comments>` check.
-
- Detects C Style comments and suggests to use C++ style comments instead.
-
- New :doc:`portability-template-virtual-member-function
<clang-tidy/checks/portability/template-virtual-member-function>` check.
Finds cases when an uninstantiated virtual member function in a template class
causes cross-compiler incompatibility.
+- New :doc:`readability-use-cpp-style-comments
+ <clang-tidy/checks/readability/use-cpp-style-comments>` check.
+
+ Replace C-style comments with C++-style comments.
+
New check aliases
^^^^^^^^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/checks/list.rst b/clang-tools-extra/docs/clang-tidy/checks/list.rst
index 7b9b905ef76715..b25dc53b328cb1 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/list.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/list.rst
@@ -403,6 +403,7 @@ Clang-Tidy Checks
:doc:`readability-uniqueptr-delete-release <readability/uniqueptr-delete-release>`, "Yes"
:doc:`readability-uppercase-literal-suffix <readability/uppercase-literal-suffix>`, "Yes"
:doc:`readability-use-anyofallof <readability/use-anyofallof>`,
+ :doc:`readability-use-cpp-style-comments <readability/use-cpp-style-comments>`, "Yes"
:doc:`readability-use-std-min-max <readability/use-std-min-max>`, "Yes"
:doc:`zircon-temporary-objects <zircon/temporary-objects>`,
diff --git a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-cpp-style-comments.rst
similarity index 92%
rename from clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
rename to clang-tools-extra/docs/clang-tidy/checks/readability/use-cpp-style-comments.rst
index befc82245f4ded..871ffa67ea2f3a 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/modernize/use-cpp-style-comments.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-cpp-style-comments.rst
@@ -1,7 +1,7 @@
.. title:: clang-tidy - use-cpp-style-comments
-modernize-use-cpp-style-comments
-================================
+readability-use-cpp-style-comments
+==================================
Replace C-style comments with C++-style comments.
C-style comments (``/* ... */``) are inherited from C, while C++ introduces
@@ -37,4 +37,3 @@ Output:
Example:
.. code-block:: c++
int a = /* this is a comment */ 5;
-
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-cpp-style-comments.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-cpp-style-comments.cpp
similarity index 78%
rename from clang-tools-extra/test/clang-tidy/checkers/modernize/use-cpp-style-comments.cpp
rename to clang-tools-extra/test/clang-tidy/checkers/readability/use-cpp-style-comments.cpp
index f56750591e035f..382af8ff3a6d8e 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize/use-cpp-style-comments.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-cpp-style-comments.cpp
@@ -1,8 +1,8 @@
-// RUN: %check_clang_tidy -std=c++11 %s modernize-use-cpp-style-comments %t -- --
+// RUN: %check_clang_tidy -std=c++11 %s readability-use-cpp-style-comments %t -- --
// Single-line full C-style comment
static const int CONSTANT = 42; /* Important constant value */
-// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+// CHECK-MESSAGES: :[[@LINE-1]]:33: warning: use C++ style comments '//' instead of C style comments '/*...*/' [readability-use-cpp-style-comments]
// CHECK-FIXES: static const int CONSTANT = 42; // Important constant value
// Inline comment that should NOT be transformed
@@ -12,7 +12,7 @@ int a = /* inline comment */ 5;
/* This is a multiline comment
that spans several lines
and should be converted to C++ style */
-// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+// CHECK-MESSAGES: :[[@LINE-3]]:1: warning: use C++ style comments '//' instead of C style comments '/*...*/' [readability-use-cpp-style-comments]
// CHECK-FIXES: // This is a multiline comment
// CHECK-FIXES: // that spans several lines
// CHECK-FIXES: // and should be converted to C++ style
@@ -29,7 +29,7 @@ void processData(int data /* input data */,
* Block comment with asterisks
* Should be converted to C++ style
*******************************/
-// CHECK-MESSAGES: :[[@LINE-4]]:1: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+// CHECK-MESSAGES: :[[@LINE-4]]:1: warning: use C++ style comments '//' instead of C style comments '/*...*/' [readability-use-cpp-style-comments]
// CHECK-FIXES: // ******************************
// CHECK-FIXES: // * Block comment with asterisks
// CHECK-FIXES: // * Should be converted to C++ style
@@ -37,7 +37,7 @@ void processData(int data /* input data */,
int calculateSomething() { return 1;}
// Comment at end of complex line
int complexCalculation = calculateSomething(); /* Result of complex calculation */
-// CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+// CHECK-MESSAGES: :[[@LINE-1]]:48: warning: use C++ style comments '//' instead of C style comments '/*...*/' [readability-use-cpp-style-comments]
// CHECK-FIXES: int complexCalculation = calculateSomething(); // Result of complex calculation
// Nested comments and edge cases
@@ -45,24 +45,24 @@ void edgeCaseFunction() {
int x = 10 /* First value */ + 20 /* Second value */; // Inline comments should not transform
/* Comment with special characters !@#$%^&*()_+ */
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use C++ style comments '//' instead of C style comments '/*...*/' [readability-use-cpp-style-comments]
// CHECK-FIXES: // Comment with special characters !@#$%^&*()_+
}
// Multiline comment with various indentations
/* This comment is indented
and should preserve indentation when converted */
-// CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+// CHECK-MESSAGES: :[[@LINE-2]]:5: warning: use C++ style comments '//' instead of C style comments '/*...*/' [readability-use-cpp-style-comments]
// CHECK-FIXES: // This comment is indented
// CHECK-FIXES: // and should preserve indentation when converted
// Complex function with mixed comment types
void complexFunction() {
/* Full line comment at start of block */
- // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+ // CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use C++ style comments '//' instead of C style comments '/*...*/' [readability-use-cpp-style-comments]
// CHECK-FIXES: // Full line comment at start of block
int x = 10; /* Inline comment not to be transformed */
- // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use C++ style comments '//' instead of C style comments '/*...*/' [modernize-use-cpp-style-comments]
+ // CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use C++ style comments '//' instead of C style comments '/*...*/' [readability-use-cpp-style-comments]
// CHECK-FIXES: int x = 10; // Inline comment not to be transformed
-}
\ No newline at end of file
+}
>From 3d02ecdad93a8bc5a267dff089ebf3bba5e6d1e2 Mon Sep 17 00:00:00 2001
From: 4m4n-x-b4w4ne <amanmbawane at gmail.com>
Date: Tue, 28 Jan 2025 00:09:01 +0530
Subject: [PATCH 11/14] Fixed Formatting issues
---
.../clang-tidy/readability/UseCppStyleCommentsCheck.cpp | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp
index 3ce894a44c87d5..8d960921e1d304 100644
--- a/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp
@@ -68,7 +68,7 @@ class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
const StringRef Text = Lexer::getSourceText(
CharSourceRange::getCharRange(Range), SM, PP.getLangOpts());
-
+
if (StartLine == EndLine) {
const SourceLocation LineBegin =
SM.translateLineCol(SM.getFileID(CommentStart), StartLine, 1);
@@ -78,7 +78,8 @@ class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
const StringRef LineContent = Lexer::getSourceText(
CharSourceRange::getCharRange(LineBegin, LineEnd), SM,
PP.getLangOpts());
- const size_t CommentStartOffset = SM.getSpellingColumnNumber(CommentStart) - 1;
+ const size_t CommentStartOffset =
+ SM.getSpellingColumnNumber(CommentStart) - 1;
const StringRef AfterComment =
LineContent.drop_front(CommentStartOffset + Text.size());
>From 7b657c41746b85cc8af1bb8ba0a7c9f4d6e97fca Mon Sep 17 00:00:00 2001
From: 4m4n-x-b4w4ne <amanmbawane at gmail.com>
Date: Tue, 28 Jan 2025 00:31:56 +0530
Subject: [PATCH 12/14] Fixed Formatting issues
---
clang-tools-extra/docs/ReleaseNotes.rst | 4 ++--
.../clang-tidy/checks/readability/use-cpp-style-comments.rst | 5 +++--
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index 4d30d0bae9ebeb..a05de582c2b170 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -173,7 +173,7 @@ New checks
Replace comparisons between signed and unsigned integers with their safe
C++20 ``std::cmp_*`` alternative, if available.
-
+
- New :doc:`portability-template-virtual-member-function
<clang-tidy/checks/portability/template-virtual-member-function>` check.
@@ -184,7 +184,7 @@ New checks
<clang-tidy/checks/readability/use-cpp-style-comments>` check.
Replace C-style comments with C++-style comments.
-
+
New check aliases
^^^^^^^^^^^^^^^^^
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-cpp-style-comments.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-cpp-style-comments.rst
index 871ffa67ea2f3a..ba192e5f94277f 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/use-cpp-style-comments.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-cpp-style-comments.rst
@@ -14,14 +14,13 @@ Examples:
Input:
.. code-block::c++
-
+
/* This is a single-line comment */
int x = 42; /* Inline comment */
/* This is a
multi-line comment */
-
Output:
.. code-block::c++
@@ -34,6 +33,8 @@ Output:
.. note::
Inline Comments are neither fixed nor warned.
+
Example:
.. code-block:: c++
+
int a = /* this is a comment */ 5;
>From 2deb9d21233a650c02fa4df57f2b59232dd4f0dd Mon Sep 17 00:00:00 2001
From: 4m4n-x-b4w4ne <amanmbawane at gmail.com>
Date: Tue, 28 Jan 2025 21:30:29 +0530
Subject: [PATCH 13/14] Fixed more formatting issues
---
.../clang-tidy/checks/readability/use-cpp-style-comments.rst | 3 +++
1 file changed, 3 insertions(+)
diff --git a/clang-tools-extra/docs/clang-tidy/checks/readability/use-cpp-style-comments.rst b/clang-tools-extra/docs/clang-tidy/checks/readability/use-cpp-style-comments.rst
index ba192e5f94277f..c8fad2dd27f2ee 100644
--- a/clang-tools-extra/docs/clang-tidy/checks/readability/use-cpp-style-comments.rst
+++ b/clang-tools-extra/docs/clang-tidy/checks/readability/use-cpp-style-comments.rst
@@ -13,6 +13,7 @@ equivalent C++-style comments.
Examples:
Input:
+
.. code-block::c++
/* This is a single-line comment */
@@ -22,6 +23,7 @@ Input:
multi-line comment */
Output:
+
.. code-block::c++
// This is a single-line comment
@@ -35,6 +37,7 @@ Output:
Inline Comments are neither fixed nor warned.
Example:
+
.. code-block:: c++
int a = /* this is a comment */ 5;
>From e9c899f40d5a2353076c4992f5f4f2b1ea3e3aae Mon Sep 17 00:00:00 2001
From: 4m4n-x-b4w4ne <amanmbawane at gmail.com>
Date: Sun, 2 Feb 2025 17:50:06 +0530
Subject: [PATCH 14/14] Added Options for Doxygen Comments
---
.../readability/UseCppStyleCommentsCheck.cpp | 33 +++++++++++---
.../readability/UseCppStyleCommentsCheck.h | 6 +++
.../readability/use-cpp-style-comments.cpp | 45 ++++++++++++++-----
3 files changed, 68 insertions(+), 16 deletions(-)
diff --git a/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp
index 8d960921e1d304..18c445ba5fdcda 100644
--- a/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.cpp
@@ -17,11 +17,15 @@ using namespace clang::ast_matchers;
namespace clang::tidy::readability {
class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
public:
- CStyleCommentHandler(UseCppStyleCommentsCheck &Check)
+ CStyleCommentHandler(UseCppStyleCommentsCheck &Check, bool ExcludeDoxygen)
: Check(Check),
CStyleCommentMatch(
- "^[ \t]*/\\*+[ \t\r\n]*(.*[ \t\r\n]*)*[ \t\r\n]*\\*+/[ \t\r\n]*$") {
- }
+ "^[ \t]*/\\*+[ \t\r\n]*(.*[ \t\r\n]*)*[ \t\r\n]*\\*+/[ \t\r\n]*$"),
+ ExcludeDoxygen(ExcludeDoxygen) {}
+
+ void setExcludeDoxygen(bool Exclude) { ExcludeDoxygen = Exclude; }
+
+ bool isExcludeDoxygen() const { return ExcludeDoxygen; }
std::string convertToCppStyleComment(const SourceManager &SM,
const SourceRange &Range) {
@@ -58,6 +62,14 @@ class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
return Result;
}
+ bool isDoxygenStyleComment(const StringRef &Text) {
+ StringRef Trimmed = Text.ltrim();
+ return Trimmed.starts_with("/**") || Trimmed.starts_with("/*!") ||
+ Trimmed.starts_with("///") || Trimmed.starts_with("//!") ||
+ (Trimmed.starts_with("/*") &&
+ Trimmed.drop_front(2).starts_with("*"));
+ }
+
bool CheckForInlineComments(Preprocessor &PP, SourceRange Range) {
const SourceManager &SM = PP.getSourceManager();
const SourceLocation CommentStart = Range.getBegin();
@@ -100,6 +112,10 @@ class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
const StringRef Text = Lexer::getSourceText(
CharSourceRange::getCharRange(Range), SM, PP.getLangOpts());
+ if (ExcludeDoxygen && isDoxygenStyleComment(Text)) {
+ return false;
+ }
+
SmallVector<StringRef> Matches;
if (!CStyleCommentMatch.match(Text, &Matches)) {
return false;
@@ -120,13 +136,15 @@ class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler {
private:
UseCppStyleCommentsCheck &Check;
+ bool ExcludeDoxygen;
llvm::Regex CStyleCommentMatch;
};
UseCppStyleCommentsCheck::UseCppStyleCommentsCheck(StringRef Name,
ClangTidyContext *Context)
: ClangTidyCheck(Name, Context),
- Handler(std::make_unique<CStyleCommentHandler>(*this)) {}
+ Handler(std::make_unique<CStyleCommentHandler>(
+ *this, Options.get("ExcludeDoxygenStyleComments", false))) {}
void UseCppStyleCommentsCheck::registerPPCallbacks(
const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) {
@@ -135,5 +153,10 @@ void UseCppStyleCommentsCheck::registerPPCallbacks(
void UseCppStyleCommentsCheck::check(const MatchFinder::MatchResult &Result) {}
+void UseCppStyleCommentsCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
+ Options.store(Opts, "ExcludeDoxygenStyleComments",
+ Handler->isExcludeDoxygen());
+}
+
UseCppStyleCommentsCheck::~UseCppStyleCommentsCheck() = default;
-} // namespace clang::tidy::readability
+} // namespace clang::tidy::readability
\ No newline at end of file
diff --git a/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.h b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.h
index c7c6bfb6e85090..b641c444a8c90e 100644
--- a/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.h
+++ b/clang-tools-extra/clang-tidy/readability/UseCppStyleCommentsCheck.h
@@ -15,6 +15,8 @@
namespace clang::tidy::readability {
/// Detects C Style comments and suggests to use C++ style comments instead.
///
+/// Optionally excludes Doxygen-style comments.
+///
/// For the user-facing documentation see:
/// http://clang.llvm.org/extra/clang-tidy/checks/readability/use-cpp-style-comments.html
class UseCppStyleCommentsCheck : public ClangTidyCheck {
@@ -32,9 +34,13 @@ class UseCppStyleCommentsCheck : public ClangTidyCheck {
void check(const ast_matchers::MatchFinder::MatchResult &Result) override;
+ void storeOptions(ClangTidyOptions::OptionMap &Opts) override;
+
private:
class CStyleCommentHandler;
std::unique_ptr<CStyleCommentHandler> Handler;
+ const bool ExcludeDoxygenStyleComments =
+ Options.get("ExcludeDoxygenStyleComments", false);
};
} // namespace clang::tidy::readability
diff --git a/clang-tools-extra/test/clang-tidy/checkers/readability/use-cpp-style-comments.cpp b/clang-tools-extra/test/clang-tidy/checkers/readability/use-cpp-style-comments.cpp
index 382af8ff3a6d8e..d0280300d46af0 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/readability/use-cpp-style-comments.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/readability/use-cpp-style-comments.cpp
@@ -1,4 +1,4 @@
-// RUN: %check_clang_tidy -std=c++11 %s readability-use-cpp-style-comments %t -- --
+// RUN: %check_clang_tidy -std=c++11 %s readability-use-cpp-style-comments %t -config="{CheckOptions: [{key: readability-use-cpp-style-comments.ExcludeDoxygenStyleComments, value: true}]}"
// Single-line full C-style comment
static const int CONSTANT = 42; /* Important constant value */
@@ -24,16 +24,6 @@ void processData(int data /* input data */,
fnWithSomeBools(/*ControlsA=*/ true, /*ControlsB=*/ false);
}
-// Multiline comment with asterisk styling
-/*******************************
- * Block comment with asterisks
- * Should be converted to C++ style
- *******************************/
-// CHECK-MESSAGES: :[[@LINE-4]]:1: warning: use C++ style comments '//' instead of C style comments '/*...*/' [readability-use-cpp-style-comments]
-// CHECK-FIXES: // ******************************
-// CHECK-FIXES: // * Block comment with asterisks
-// CHECK-FIXES: // * Should be converted to C++ style
-// CHECK-FIXES: // ******************************
int calculateSomething() { return 1;}
// Comment at end of complex line
int complexCalculation = calculateSomething(); /* Result of complex calculation */
@@ -66,3 +56,36 @@ void complexFunction() {
// CHECK-MESSAGES: :[[@LINE-1]]:17: warning: use C++ style comments '//' instead of C style comments '/*...*/' [readability-use-cpp-style-comments]
// CHECK-FIXES: int x = 10; // Inline comment not to be transformed
}
+
+// Tests for Doxygen comments with ExcludeDoxygenStyleComments enabled
+/**
+ * This is a Doxygen comment for a function.
+ * It should NOT be transformed.
+ */
+void doxygenFunction1();
+
+/*!
+ * This is another Doxygen-style comment.
+ * It should also NOT be transformed.
+ */
+void doxygenFunction2();
+
+/**
+ * Multiline Doxygen comment describing parameters.
+ *
+ * @param x The first parameter.
+ * @param y The second parameter.
+ * @return A result value.
+ */
+int doxygenFunctionWithParams(int x, int y);
+
+/*******************************
+ * Non-Doxygen block comments without markers
+ *******************************/
+void DoxygenBlock();
+
+/*!
+ * This is a single-line Doxygen comment.
+ * Should NOT be transformed.
+ */
+void singleLineDoxygen();
More information about the cfe-commits
mailing list