[clang-tools-extra] 24aafca - [clang-tidy] modernize-use-equals-default avoid adding redundant semicolons
Mitchell Balan via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 20 15:13:18 PST 2019
Author: Mitchell Balan
Date: 2019-11-20T18:08:37-05:00
New Revision: 24aafcadff3851ec3a0c42303fec63e815b19566
URL: https://github.com/llvm/llvm-project/commit/24aafcadff3851ec3a0c42303fec63e815b19566
DIFF: https://github.com/llvm/llvm-project/commit/24aafcadff3851ec3a0c42303fec63e815b19566.diff
LOG: [clang-tidy] modernize-use-equals-default avoid adding redundant semicolons
Summary:
`modernize-use-equals-default` replaces default constructors/destructors with `= default;`. When the optional semicolon after a member function is present, this results in two consecutive semicolons.
This patch checks to see if the next non-comment token after the code to be replaced is a semicolon, and if so offers a replacement of `= default` rather than `= default;`.
This patch adds trailing comments and semicolons to about 5 existing tests.
Reviewers: malcolm.parsons, angelgarcia, aaron.ballman, alexfh
Patch by: poelmanc
Subscribers: MyDeveloperDay, JonasToth, cfe-commits
Tags: #clang
Differential Revision: https://reviews.llvm.org/D70144
Added:
Modified:
clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
clang-tools-extra/clang-tidy/utils/LexerUtils.h
clang-tools-extra/docs/ReleaseNotes.rst
clang-tools-extra/test/clang-tidy/checkers/modernize-use-equals-default-copy.cpp
clang-tools-extra/test/clang-tidy/checkers/modernize-use-equals-default.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
index 991eada514d3..0309fa8d0a37 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseEqualsDefaultCheck.cpp
@@ -10,6 +10,7 @@
#include "clang/AST/ASTContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/Lex/Lexer.h"
+#include "../utils/LexerUtils.h"
using namespace clang::ast_matchers;
@@ -302,9 +303,16 @@ void UseEqualsDefaultCheck::check(const MatchFinder::MatchResult &Result) {
auto Diag = diag(Location, "use '= default' to define a trivial " +
SpecialFunctionName);
- if (ApplyFix)
- Diag << FixItHint::CreateReplacement(Body->getSourceRange(), "= default;")
+ if (ApplyFix) {
+ // Skipping comments, check for a semicolon after Body->getSourceRange()
+ Optional<Token> Token = utils::lexer::findNextTokenSkippingComments(
+ Body->getSourceRange().getEnd().getLocWithOffset(1),
+ Result.Context->getSourceManager(), Result.Context->getLangOpts());
+ StringRef Replacement =
+ Token && Token->is(tok::semi) ? "= default" : "= default;";
+ Diag << FixItHint::CreateReplacement(Body->getSourceRange(), Replacement)
<< RemoveInitializers;
+ }
}
} // namespace modernize
diff --git a/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp b/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
index a6e361d66aa7..e80fda6e318e 100644
--- a/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
+++ b/clang-tools-extra/clang-tidy/utils/LexerUtils.cpp
@@ -68,6 +68,16 @@ SourceLocation findNextTerminator(SourceLocation Start, const SourceManager &SM,
return findNextAnyTokenKind(Start, SM, LangOpts, tok::comma, tok::semi);
}
+Optional<Token> findNextTokenSkippingComments(SourceLocation Start,
+ const SourceManager &SM,
+ const LangOptions &LangOpts) {
+ Optional<Token> CurrentToken;
+ do {
+ CurrentToken = Lexer::findNextToken(Start, SM, LangOpts);
+ } while (CurrentToken && CurrentToken->is(tok::comment));
+ return CurrentToken;
+}
+
bool rangeContainsExpansionsOrDirectives(SourceRange Range,
const SourceManager &SM,
const LangOptions &LangOpts) {
diff --git a/clang-tools-extra/clang-tidy/utils/LexerUtils.h b/clang-tools-extra/clang-tidy/utils/LexerUtils.h
index 8330266e6341..2c4a2518259d 100644
--- a/clang-tools-extra/clang-tidy/utils/LexerUtils.h
+++ b/clang-tools-extra/clang-tidy/utils/LexerUtils.h
@@ -80,6 +80,11 @@ SourceLocation findNextAnyTokenKind(SourceLocation Start,
}
}
+// Finds next token that's not a comment.
+Optional<Token> findNextTokenSkippingComments(SourceLocation Start,
+ const SourceManager &SM,
+ const LangOptions &LangOpts);
+
/// Re-lex the provide \p Range and return \c false if either a macro spans
/// multiple tokens, a pre-processor directive or failure to retrieve the
/// next token is found, otherwise \c true.
diff --git a/clang-tools-extra/docs/ReleaseNotes.rst b/clang-tools-extra/docs/ReleaseNotes.rst
index fc61bda92541..09dc28ae1715 100644
--- a/clang-tools-extra/docs/ReleaseNotes.rst
+++ b/clang-tools-extra/docs/ReleaseNotes.rst
@@ -158,6 +158,10 @@ Improvements to clang-tidy
- The 'objc-avoid-spinlock' check was renamed to :doc:`darwin-avoid-spinlock
<clang-tidy/checks/darwin-avoid-spinlock>`
+- The :doc:`modernize-use-equals-default
+ <clang-tidy/checks/modernize-use-equals-default>` fix no longer adds
+ semicolons where they would be redundant.
+
- New :doc:`readability-redundant-access-specifiers
<clang-tidy/checks/readability-redundant-access-specifiers>` check.
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-use-equals-default-copy.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-use-equals-default-copy.cpp
index 8aa80d8a957f..2a8f5ab1f183 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize-use-equals-default-copy.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-use-equals-default-copy.cpp
@@ -119,7 +119,7 @@ Empty &Empty::operator=(const Empty &Other) { return *this; }
struct BF {
BF() = default;
BF(const BF &Other) : Field1(Other.Field1), Field2(Other.Field2), Field3(Other.Field3),
- Field4(Other.Field4) {}
+ Field4(Other.Field4) {};
// CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
// CHECK-FIXES: BF(const BF &Other) {{$}}
// CHECK-FIXES: = default;
diff --git a/clang-tools-extra/test/clang-tidy/checkers/modernize-use-equals-default.cpp b/clang-tools-extra/test/clang-tidy/checkers/modernize-use-equals-default.cpp
index c214f6a57394..40311a1435dd 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/modernize-use-equals-default.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/modernize-use-equals-default.cpp
@@ -7,7 +7,7 @@ class OL {
~OL();
};
-OL::OL() {}
+OL::OL() {};
// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: use '= default' to define a trivial default constructor [modernize-use-equals-default]
// CHECK-FIXES: OL::OL() = default;
OL::~OL() {}
@@ -17,9 +17,9 @@ OL::~OL() {}
// Inline definitions.
class IL {
public:
- IL() {}
+ IL() {} ; // Note embedded tab on this line
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
- // CHECK-FIXES: IL() = default;
+ // CHECK-FIXES: IL() = default ; // Note embedded tab on this line
~IL() {}
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
// CHECK-FIXES: ~IL() = default;
@@ -46,18 +46,20 @@ class IA {
// Default member initializer
class DMI {
public:
- DMI() {}
- // CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
- // CHECK-FIXES: DMI() = default;
+ DMI() {} // Comment before semi-colon on next line
+ ;
+ // CHECK-MESSAGES: :[[@LINE-2]]:3: warning: use '= default'
+ // CHECK-FIXES: DMI() = default // Comment before semi-colon on next line
+ // CHECK-FIXES-NEXT: ;
int Field = 5;
};
// Class member
class CM {
public:
- CM() {}
+ CM() {} /* Comments */ /* before */ /* semicolon */;
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
- // CHECK-FIXES: CM() = default;
+ // CHECK-FIXES: CM() = default /* Comments */ /* before */ /* semicolon */;
OL o;
};
@@ -66,7 +68,7 @@ class Priv {
Priv() {}
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
// CHECK-FIXES: Priv() = default;
- ~Priv() {}
+ ~Priv() {};
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: use '= default'
// CHECK-FIXES: ~Priv() = default;
};
More information about the cfe-commits
mailing list