-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[clang-tidy] Replace /* ... */ single-line comments with // ... comments #124319
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 32 commits
581cc0e
8bf94c6
eb4dd90
4a87afe
44d208e
c9a20ef
ec6a689
c815e43
47217aa
7150e04
ba3c7bb
3d02ecd
7b657c4
2deb9d2
e9c899f
21d6a41
375ebce
369aff7
1f9a781
0f7b71f
a02263f
b5f255f
e93a072
7e5439d
0dfe661
cc9249d
43aff62
2d4aee8
5ffdc17
78fc4c9
cdb6b9a
d027247
84caead
0935e58
317ee60
d8d3d2c
884356f
eb05ff8
5e91004
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,188 @@ | ||
| //===--- 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 <optional> | ||
|
|
||
| using namespace clang::ast_matchers; | ||
|
|
||
| namespace clang::tidy::readability { | ||
| class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler { | ||
| public: | ||
| CStyleCommentHandler(UseCppStyleCommentsCheck &Check, bool ExcludeDoxygen, | ||
| StringRef ExcludedComments) | ||
| : Check(Check), ExcludeDoxygen(ExcludeDoxygen), | ||
| ExcludedComments(ExcludedComments), | ||
| ExcludedCommentMatch(ExcludedComments), | ||
| CStyleCommentMatch( | ||
| "^[ \t]*/\\*+[ \t\r\n]*(.*[ \t\r\n]*)*[ \t\r\n]*\\*+/[ \t\r\n]*$") { | ||
| } | ||
|
|
||
| StringRef getExcludedCommentsRegex() const { return ExcludedComments; } | ||
|
|
||
| bool isExcludeDoxygen() const { return ExcludeDoxygen; } | ||
|
|
||
| void convertToCppStyleCommentFixes(const SourceManager &SM, | ||
| const SourceRange &Range, | ||
| SmallVectorImpl<FixItHint> &FixIts) { | ||
| StringRef CommentText = Lexer::getSourceText( | ||
| CharSourceRange::getTokenRange(Range), SM, LangOptions()); | ||
|
|
||
| CommentText = CommentText.drop_front(2).drop_back(2); | ||
| const SourceLocation StartLoc = Range.getBegin(); | ||
| const FileID FID = SM.getFileID(StartLoc); | ||
| unsigned LineNo = SM.getSpellingLineNumber(StartLoc); | ||
| const unsigned StartCol = SM.getSpellingColumnNumber(StartLoc); | ||
| if (!CommentText.empty()) { | ||
| const size_t NewlinePos = CommentText.find('\n'); | ||
|
|
||
| const StringRef Line = (NewlinePos == StringRef::npos) | ||
| ? CommentText | ||
| : CommentText.substr(0, NewlinePos); | ||
|
|
||
| const SourceLocation LineStart = | ||
| SM.translateLineCol(FID, LineNo, StartCol); | ||
| const SourceLocation LineEnd = SM.translateLineCol( | ||
| FID, LineNo, std::numeric_limits<unsigned>::max()); | ||
|
|
||
| FixIts.push_back(FixItHint::CreateReplacement( | ||
| CharSourceRange::getCharRange(LineStart, LineEnd), | ||
| "//" + Line.str())); | ||
|
|
||
| if (NewlinePos != StringRef::npos) { | ||
| CommentText = CommentText.substr(NewlinePos + 1); | ||
| LineNo++; | ||
| } else { | ||
| CommentText = ""; | ||
| } | ||
| } | ||
| while (!CommentText.empty()) { | ||
| const size_t NewlinePos = CommentText.find('\n'); | ||
|
|
||
| StringRef Line = (NewlinePos == StringRef::npos) | ||
| ? CommentText | ||
| : CommentText.substr(0, NewlinePos); | ||
|
|
||
| const SourceLocation LineStart = SM.translateLineCol(FID, LineNo, 1); | ||
| const SourceLocation LineEnd = SM.translateLineCol( | ||
| FID, LineNo, std::numeric_limits<unsigned>::max()); | ||
|
|
||
| if (Line.substr(0, 2) == " ") { | ||
| Line = Line.drop_front(2); | ||
| FixIts.push_back(FixItHint::CreateReplacement( | ||
| CharSourceRange::getCharRange(LineStart, LineEnd), | ||
| "//" + Line.str())); | ||
| } else { | ||
| FixIts.push_back(FixItHint::CreateReplacement( | ||
| CharSourceRange::getCharRange(LineStart, LineEnd), | ||
| "//" + Line.str())); | ||
| } | ||
|
|
||
| if (NewlinePos == StringRef::npos) | ||
| break; | ||
|
|
||
| CommentText = CommentText.substr(NewlinePos + 1); | ||
| LineNo++; | ||
| } | ||
| } | ||
|
|
||
| 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 CheckForCodeAfterComment(Preprocessor &PP, SourceRange Range) { | ||
| const SourceManager &SM = PP.getSourceManager(); | ||
| const SourceLocation CommentStart = Range.getBegin(), | ||
| CommentEnd = Range.getEnd(); | ||
| const std::optional<Token> NextTok = | ||
| Lexer::findNextToken(CommentStart, SM, PP.getLangOpts()); | ||
| if (!NextTok.has_value()) | ||
| return false; | ||
|
|
||
| const std::string tokenSpelling = | ||
| Lexer::getSpelling(*NextTok, SM, PP.getLangOpts()); | ||
| const unsigned lineNo = SM.getSpellingLineNumber(CommentEnd); | ||
| const SourceLocation loc = NextTok->getLocation(); | ||
| const unsigned tokenLine = SM.getSpellingLineNumber(loc); | ||
| return lineNo == tokenLine; | ||
| } | ||
|
|
||
| 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()); | ||
|
|
||
| if (!ExcludedCommentMatch.isValid()) { | ||
| llvm::errs() << "Warning: Invalid regex pattern:" << ExcludedComments | ||
| << ":for ExcludedComments\n"; | ||
| } else if (ExcludedCommentMatch.match(Text)) { | ||
| return false; | ||
| } | ||
| if (ExcludeDoxygen && isDoxygenStyleComment(Text)) | ||
| return false; | ||
|
|
||
| SmallVector<StringRef> Matches; | ||
| if (!CStyleCommentMatch.match(Text, &Matches)) | ||
| return false; | ||
|
|
||
| if (CheckForCodeAfterComment(PP, Range)) | ||
| return false; | ||
|
|
||
| SmallVector<FixItHint, 4> FixIts; | ||
| convertToCppStyleCommentFixes(SM, Range, FixIts); | ||
|
|
||
| auto D = Check.diag( | ||
| Range.getBegin(), | ||
| "use C++ style comments '//' instead of C style comments '/*...*/'"); | ||
|
|
||
| for (const auto &Fix : FixIts) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
| D << Fix; | ||
|
|
||
| return false; | ||
| } | ||
|
|
||
| private: | ||
| UseCppStyleCommentsCheck &Check; | ||
| bool ExcludeDoxygen; | ||
| StringRef ExcludedComments; | ||
| llvm::Regex ExcludedCommentMatch; | ||
| llvm::Regex CStyleCommentMatch; | ||
| }; | ||
|
|
||
| UseCppStyleCommentsCheck::UseCppStyleCommentsCheck(StringRef Name, | ||
| ClangTidyContext *Context) | ||
| : ClangTidyCheck(Name, Context), | ||
| Handler(std::make_unique<CStyleCommentHandler>( | ||
| *this, Options.get("ExcludeDoxygenStyleComments", false), | ||
| Options.get("ExcludedComments", "^$"))) {} | ||
|
|
||
| void UseCppStyleCommentsCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) { | ||
| Options.store(Opts, "ExcludeDoxygenStyleComments", | ||
| Handler->isExcludeDoxygen()); | ||
| Options.store(Opts, "ExcludedComments", Handler->getExcludedCommentsRegex()); | ||
| } | ||
| 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 | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,45 @@ | ||
| //===--- 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" | ||
| #include <memory> | ||
|
|
||
| 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; | ||
HerrCai0907 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| 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; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remove, since it's empty? Same for the .cpp file. |
||
|
|
||
| void storeOptions(ClangTidyOptions::OptionMap &Opts) override; | ||
|
|
||
| private: | ||
| class CStyleCommentHandler; | ||
| std::unique_ptr<CStyleCommentHandler> Handler; | ||
4m4n-x-B4w4ne marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| const bool ExcludeDoxygenStyleComments = | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Typically these are initialized in the constructor initializer list |
||
| Options.get("ExcludeDoxygenStyleComments", false); | ||
| const StringRef ExcludedComments = Options.get("ExcludedComments", "^$"); | ||
| }; | ||
| } // namespace clang::tidy::readability | ||
|
|
||
| #endif // LLVM_CLANG_TOOLS_EXTRA_CLANG_TIDY_READABILITY_USECPPSTYLECOMMENTSCHECK_H | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,57 @@ | ||
| .. title:: clang-tidy - use-cpp-style-comments | ||
|
|
||
| readability-use-cpp-style-comments | ||
| ================================== | ||
4m4n-x-B4w4ne marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| Replace C-style comments with C++-style comments. | ||
4m4n-x-B4w4ne marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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++ | ||
4m4n-x-B4w4ne marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| /* This is a single-line comment */ | ||
| int x = 42; /* Inline comment */ | ||
| /* This is a | ||
| multi-line comment */ | ||
| Output: | ||
|
|
||
| .. code-block::c++ | ||
4m4n-x-B4w4ne marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| // 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. | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. warned about |
||
|
|
||
| Example: | ||
4m4n-x-B4w4ne marked this conversation as resolved.
Show resolved
Hide resolved
4m4n-x-B4w4ne marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| .. code-block:: c++ | ||
|
|
||
| int a = /* this is a comment */ 5; | ||
| Options | ||
| ------- | ||
|
|
||
| .. option:: ExcludeDoxygenStyleComments | ||
|
|
||
| A boolean option that determines whether Doxygen-style comments should be excluded. | ||
| Default is `false`. | ||
|
|
||
| .. option:: ExcludedComments | ||
|
|
||
| A regex pattern that allows specifying certain comments to exclude from transformation. | ||
4m4n-x-B4w4ne marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| By default, this option is set to `^$`, which means no comments are excluded. | ||
| You can provide a custom regex to exclude specific comments based on your needs. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,34 @@ | ||
| // 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}]}" | ||
|
|
||
| // 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(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.