-
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 24 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,149 @@ | ||||||
| //===--- 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> | ||||||
|
|
||||||
| using namespace clang::ast_matchers; | ||||||
|
|
||||||
| namespace clang::tidy::readability { | ||||||
| class UseCppStyleCommentsCheck::CStyleCommentHandler : public CommentHandler { | ||||||
| public: | ||||||
| CStyleCommentHandler(UseCppStyleCommentsCheck &Check, bool ExcludeDoxygen) | ||||||
| : Check(Check), ExcludeDoxygen(ExcludeDoxygen), | ||||||
| CStyleCommentMatch( | ||||||
| "^[ \t]*/\\*+[ \t\r\n]*(.*[ \t\r\n]*)*[ \t\r\n]*\\*+/[ \t\r\n]*$") { | ||||||
| } | ||||||
|
|
||||||
| void setExcludeDoxygen(bool Exclude) { ExcludeDoxygen = Exclude; } | ||||||
|
|
||||||
| bool isExcludeDoxygen() const { return ExcludeDoxygen; } | ||||||
|
|
||||||
| 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 isDoxygenStyleComment(const StringRef &Text) { | ||||||
| StringRef Trimmed = Text.ltrim(); | ||||||
|
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.
Suggested change
|
||||||
| return Trimmed.starts_with("/**") || Trimmed.starts_with("/*!") || | ||||||
| Trimmed.starts_with("///") || Trimmed.starts_with("//!") || | ||||||
| (Trimmed.starts_with("/*") && | ||||||
| Trimmed.drop_front(2).starts_with("*")); | ||||||
| } | ||||||
|
|
||||||
| bool CheckForTextAfterComment(Preprocessor &PP, SourceRange Range) { | ||||||
| const SourceManager &SM = PP.getSourceManager(); | ||||||
| const SourceLocation CommentEnd = Range.getEnd(); | ||||||
|
|
||||||
| unsigned EndLine = SM.getSpellingLineNumber(CommentEnd); | ||||||
| unsigned EndCol = SM.getSpellingColumnNumber(CommentEnd); | ||||||
|
|
||||||
| const SourceLocation LineBegin = | ||||||
| SM.translateLineCol(SM.getFileID(CommentEnd), EndLine, EndCol); | ||||||
| const SourceLocation LineEnd = | ||||||
| SM.translateLineCol(SM.getFileID(CommentEnd), EndLine, | ||||||
| std::numeric_limits<unsigned>::max()); | ||||||
| const StringRef AfterComment = | ||||||
| Lexer::getSourceText(CharSourceRange::getCharRange(LineBegin, LineEnd), | ||||||
| SM, PP.getLangOpts()); | ||||||
|
||||||
|
|
||||||
| return !AfterComment.trim().empty(); | ||||||
| } | ||||||
|
|
||||||
| 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 (ExcludeDoxygen && isDoxygenStyleComment(Text)) { | ||||||
| return false; | ||||||
| } | ||||||
|
|
||||||
4m4n-x-B4w4ne marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| SmallVector<StringRef> Matches; | ||||||
| if (!CStyleCommentMatch.match(Text, &Matches)) { | ||||||
|
||||||
| return false; | ||||||
| } | ||||||
|
|
||||||
| if (CheckForTextAfterComment(PP, Range)) { | ||||||
4m4n-x-B4w4ne marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||||||
| 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; | ||||||
| bool ExcludeDoxygen; | ||||||
| llvm::Regex CStyleCommentMatch; | ||||||
| }; | ||||||
|
|
||||||
| UseCppStyleCommentsCheck::UseCppStyleCommentsCheck(StringRef Name, | ||||||
| ClangTidyContext *Context) | ||||||
| : ClangTidyCheck(Name, Context), | ||||||
| Handler(std::make_unique<CStyleCommentHandler>( | ||||||
| *this, Options.get("ExcludeDoxygenStyleComments", false))) {} | ||||||
|
|
||||||
| void UseCppStyleCommentsCheck::registerPPCallbacks( | ||||||
| const SourceManager &SM, Preprocessor *PP, Preprocessor *ModuleExpanderPP) { | ||||||
| PP->addCommentHandler(Handler.get()); | ||||||
| } | ||||||
|
|
||||||
| 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 | ||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| //===--- 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. | ||
| /// | ||
| /// Optionally excludes Doxygen-style comments. | ||
4m4n-x-B4w4ne marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| /// | ||
| /// 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); | ||
| }; | ||
| } // 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,51 @@ | ||
| .. 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. | ||
| By default, this option is set to ``false``. | ||
4m4n-x-B4w4ne marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| 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(); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,68 @@ | ||
| // RUN: %check_clang_tidy -std=c++11 %s readability-use-cpp-style-comments %t | ||
4m4n-x-B4w4ne marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| // 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 '/*...*/' [readability-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 '/*...*/' [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 | ||
| 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); | ||
| } | ||
|
|
||
| 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 '/*...*/' [readability-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 '/*...*/' [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 '/*...*/' [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 '/*...*/' [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 '/*...*/' [readability-use-cpp-style-comments] | ||
| // CHECK-FIXES: int x = 10; // Inline comment not to be transformed | ||
| } | ||
|
|
||
| /* aaa | ||
| bbbb | ||
| ccc */ int z = 1; | ||
| // There is a text after the comment ends so it should be ignored. | ||
|
|
||
| int y = 10;/* aaa | ||
| bbbb | ||
| ccc */ int z1 = 1; | ||
| // There is a text after the comment ends so it should be ignored. | ||
4m4n-x-B4w4ne marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
Uh oh!
There was an error while loading. Please reload this page.